QuantConnect/Lean · error · RegressionTestException
Expected positive TotalMarginUsed, got {Portfolio.TotalMargi
Error message
Expected positive TotalMarginUsed, got {Portfolio.TotalMarginUsed} What it means
Thrown when Portfolio.TotalMarginUsed is zero or negative after the ADAUSDT buy order fills. TotalMarginUsed should reflect the maintenance margin consumed by the open ADAUSDT futures position. A zero value means the margin tracking system failed to register the position's margin requirement.
Source
Thrown at Algorithm.CSharp/BinanceCryptoFutureBnfcrCollateralRegressionAlgorithm.cs:79
// 1. BNFCR collateral must produce positive buying power (USDT is zero)
var buyingPower = _adaUsdt.BuyingPowerModel.GetBuyingPower(new BuyingPowerParameters(Portfolio, _adaUsdt, OrderDirection.Buy));
if (buyingPower.Value <= 0)
{
throw new RegressionTestException($"Expected positive buying power from BNFCR, got {buyingPower.Value}");
}
// 2. Order must not be rejected
var ticket = Buy(_adaUsdt.Symbol, 1000);
_orderPlaced = true;
if (ticket.Status == OrderStatus.Invalid)
{
throw new RegressionTestException("Order rejected — BNFCR collateral should cover margin");
}
// 3. Margin must be tracked
if (Portfolio.TotalMarginUsed <= 0)
{
throw new RegressionTestException($"Expected positive TotalMarginUsed, got {Portfolio.TotalMarginUsed}");
}
// 4. Shared collateral: ETHUSDC (different quote currency) must deduct ADAUSDT margin
_ethUsdc.SetMarketPrice(new TradeBar { Time = Time, Symbol = _ethUsdc.Symbol, Close = 1600 });
var ethBuyingPower = _ethUsdc.BuyingPowerModel.GetBuyingPower(new BuyingPowerParameters(Portfolio, _ethUsdc, OrderDirection.Buy));
var adaBuyingPower = _adaUsdt.BuyingPowerModel.GetBuyingPower(new BuyingPowerParameters(Portfolio, _adaUsdt, OrderDirection.Buy));
// ETHUSDC must see less buying power than ADAUSDT - ADAUSDT maintenance margin
// is deducted from ETHUSDC's shared pool, but ADAUSDT skips itself.
if (ethBuyingPower.Value >= adaBuyingPower.Value)
{
throw new RegressionTestException(
$"ETHUSDC buying power ({ethBuyingPower.Value}) must be less than ADAUSDT ({adaBuyingPower.Value}) " +
$"— shared BNFCR pool must deduct ADAUSDT maintenance margin");
}
}
View on GitHub (pinned to d2c3659f87)
Solutions
- Verify the ADAUSDT position is actually open: check Portfolio[_adaUsdt.Symbol].Quantity and .HoldingsValue.
- Inspect SecurityMarginModel.GetReservedMargin to confirm it returns a positive value for the open position.
- Check that Portfolio.ProcessFill or the fill event handler triggers margin recalculation for CryptoFuture.
- Log Securities[_adaUsdt.Symbol].BuyMarginModel and .MaintenanceMarginModel outputs.
- Ensure the crypto future price feed is active so the margin model has a current price to compute against.
Example fix
// before
if (Portfolio.TotalMarginUsed <= 0)
{
throw new RegressionTestException($"Expected positive TotalMarginUsed, got {Portfolio.TotalMarginUsed}");
}
// after — diagnose margin components
if (Portfolio.TotalMarginUsed <= 0)
{
var sec = Securities[_adaUsdt.Symbol];
Log($"Position: qty={Portfolio[_adaUsdt.Symbol].Quantity}, " +
$"margin model={sec.BuyingPowerModel.GetType().Name}");
throw new RegressionTestException(
$"Expected positive TotalMarginUsed, got {Portfolio.TotalMarginUsed}");
} Defensive patterns
Strategy: validation
Validate before calling
// Validate margin tracking before asserting
var qty = Portfolio[_adaUsdt.Symbol].Quantity;
Log($"ADAUSDT position: {qty}, TotalMarginUsed: {Portfolio.TotalMarginUsed}");
if (Portfolio.TotalMarginUsed <= 0 && qty != 0)
{
Log($"Position open but margin not tracked — check margin model");
} Prevention
- Verify the position is actually open (non-zero quantity) before checking margin.
- Inspect SecurityMarginModel.GetReservedMargin for the crypto future position.
- Ensure Portfolio.ProcessFill triggers margin recalculation for CryptoFuture.
- Log Holdings.Quantity and TotalMarginUsed together to correlate.
When it happens
Trigger: The CryptoFutureSecurityMarginModel did not update TotalMarginUsed after the fill, the position was not actually opened despite the order being accepted, or the margin model returns zero for this position configuration.
Common situations: Margin model bugs where crypto future positions are not counted, Holding objects not updated after fills, or Portfolio.ProcessFill not invoking the margin model correctly for CryptoFuture security type.
Related errors
- Expected positive buying power from BNFCR, got {buyingPower.
- Order rejected — BNFCR collateral should cover margin
- ETHUSDC buying power ({ethBuyingPower.Value}) must be less t
- Expected an open position at end of algorithm
- Index is not tradable.
AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13).
Data as JSON: /api/errors/39f43cee8e592013.
Report an issue: GitHub.