QuantConnect/Lean · error · RegressionTestException
Fee rate should be 0.0025, but was {feeRate}
Error message
Fee rate should be 0.0025, but was {feeRate} What it means
Asserts _spy.ShortableProvider.FeeRate returns exactly 0.0025m at end-of-algorithm Time. The custom CustomSPYShortableProvider returns a constant 0.0025m; a different value means the custom provider is not the one installed (the default provider answered instead).
Source
Thrown at Algorithm.CSharp/CustomShortableProviderRegressionAlgorithm.cs:68
}
}
public override void OnEndOfAlgorithm()
{
var transactions = Transactions.OrdersCount;
if (transactions != 1)
{
throw new RegressionTestException($"Algorithm should have just 1 order, but was {transactions}");
}
var orderQuantity = Transactions.GetOrderById(_orderId).Quantity;
if (orderQuantity != -1001)
{
throw new RegressionTestException($"Quantity of order {_orderId} should be -1001, but was {orderQuantity}");
}
var feeRate = _spy.ShortableProvider.FeeRate(_spy.Symbol, Time);
if (feeRate != 0.0025m)
{
throw new RegressionTestException($"Fee rate should be 0.0025, but was {feeRate}");
}
var rebateRate = _spy.ShortableProvider.RebateRate(_spy.Symbol, Time);
if (rebateRate != 0.0507m)
{
throw new RegressionTestException($"Fee rate should be 0.0507, but was {rebateRate}");
}
}
private class CustomSPYShortableProvider : IShortableProvider
{
public decimal FeeRate(Symbol symbol, DateTime localTime) => 0.0025m;
public decimal RebateRate(Symbol symbol, DateTime localTime) => 0.0507m;
public long? ShortableQuantity(Symbol symbol, DateTime localTime)
{
if (localTime < new DateTime(2013, 10, 4, 16, 0, 0))
{View on GitHub (pinned to d2c3659f87)
Solutions
- Call _spy.SetShortableProvider(new CustomSPYShortableProvider()) AFTER SetBrokerageModel.
- Ensure _spy is the stored Security from AddEquity, not a recomputed reference.
- Verify CustomSPYShortableProvider.FeeRate returns 0.0025m (constant) and is not shadowed by an interface default.
- Re-assert the provider type at OnEndOfAlgorithm to detect silent overwrites.
Example fix
// before: brokerage overwrites the shortable provider _spy.SetShortableProvider(new CustomSPYShortableProvider()); SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage); // after: install custom provider after brokerage defaults SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage); _spy.SetShortableProvider(new CustomSPYShortableProvider());
Defensive patterns
Strategy: validation
Validate before calling
// Assert the custom provider is installed before reading rates
if (!(_spy.ShortableProvider is CustomSPYShortableProvider))
throw new InvalidOperationException("Custom shortable provider not installed");
var fee = _spy.ShortableProvider.FeeRate(_spy.Symbol, Time); Type guard
bool HasCustomShortableProvider(Security s) => s.ShortableProvider is CustomSPYShortableProvider;
Prevention
- Call SetShortableProvider after SetBrokerageModel.
- Configure the stored Security reference, not a throwaway.
- Re-assert the provider type before reading its rates.
When it happens
Trigger: Calling FeeRate on _spy.ShortableProvider and getting a non-0.0025 value, indicating SetShortableProvider did not persist or was overwritten.
Common situations: SetShortableProvider called before SetBrokerageModel so the brokerage overwrote it; provider set on a different Security reference; or the brokerage model's default shortable provider took precedence.
Related errors
- Fee rate should be 0.0507, but was {rebateRate}
- CustomMarginInterestRateModel was not set
- Algorithm should have just 1 order, but was {transactions}
- Quantity of order {_orderId} should be -1001, but was {order
- {Time} - Unexpected symbol changed event old symbol: {change
AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13).
Data as JSON: /api/errors/810363425b5c1852.
Report an issue: GitHub.