QuantConnect/Lean · error · RegressionTestException
Expected an open position at end of algorithm
Error message
Expected an open position at end of algorithm
What it means
Thrown in OnEndOfAlgorithm when Portfolio.Invested is false, meaning all positions were closed or never opened. The algorithm expects the ADAUSDT futures position (bought in OnData) to remain open at algorithm termination. If the position was liquidated, rejected, or never filled, this assertion catches it.
Source
Thrown at Algorithm.CSharp/BinanceCryptoFutureBnfcrCollateralRegressionAlgorithm.cs:102
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");
}
}
public override void OnEndOfAlgorithm()
{
if (!Portfolio.Invested)
{
throw new RegressionTestException("Expected an open position at end of algorithm");
}
}
public override void OnOrderEvent(OrderEvent orderEvent)
{
Debug($"{Time} {orderEvent}");
}
/// <summary>
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
/// </summary>
public bool CanRunLocally { get; } = true;
/// <summary>
/// This is used by the regression test system to indicate which languages this algorithm is written in.
/// </summary>
public List<Language> Languages { get; } = new() { Language.CSharp };
View on GitHub (pinned to d2c3659f87)
Solutions
- Check Portfolio[_adaUsdt.Symbol].Quantity to confirm whether the position was ever opened.
- Review OnOrderEvent logs for margin-call or liquidation events.
- Verify the backtest date range is long enough for the order to fill (single-day algo: SetStartDate/SetEndDate same day).
- Inspect the order ticket status history to see if the fill occurred.
- Ensure no Liquidate() call paths execute between the Buy and algorithm end.
Example fix
// before
public override void OnEndOfAlgorithm()
{
if (!Portfolio.Invested)
{
throw new RegressionTestException("Expected an open position at end of algorithm");
}
}
// after — diagnose position state
public override void OnEndOfAlgorithm()
{
if (!Portfolio.Invested)
{
foreach (var kvp in Securities)
{
Log($"{kvp.Key}: qty={kvp.Value.Holdings.Quantity}, invested={kvp.Value.Invested}");
}
throw new RegressionTestException("Expected an open position at end of algorithm");
}
} Defensive patterns
Strategy: validation
Validate before calling
// Validate position state before asserting
public override void OnEndOfAlgorithm()
{
if (!Portfolio.Invested)
{
foreach (var kvp in Securities)
{
Log($"{kvp.Key}: qty={kvp.Value.Holdings.Quantity}, invested={kvp.Value.Invested}");
}
}
} Type guard
bool HasOpenPosition() => Portfolio.Invested &&
Securities.Values.Any(s => s.Holdings.Quantity != 0); Prevention
- Log order ticket status after Buy to confirm the fill occurred.
- Check OnOrderEvent for margin-call or liquidation events.
- Ensure no Liquidate() call paths execute after the Buy.
- Verify the backtest window is long enough for the order to process.
When it happens
Trigger: The Buy order was rejected (links to error 36), the position was automatically liquidated by a margin call, the backtest ended before the order filled, or a settlement/expiry closed the position.
Common situations: Margin call liquidation when BNFCR collateral is insufficient, order not filled due to data feed issues, algorithm end date set before the order processes, or an expiry/settlement event closing the crypto future position.
Related errors
- Expected positive TotalMarginUsed, got {Portfolio.TotalMargi
- Expected positive buying power from BNFCR, got {buyingPower.
- Order rejected — BNFCR collateral should cover margin
- ETHUSDC buying power ({ethBuyingPower.Value}) must be less t
- Index is not tradable.
AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13).
Data as JSON: /api/errors/dafd8799d9808a8e.
Report an issue: GitHub.