QuantConnect/Lean · error · RegressionTestException
Contract was not delisted
Error message
Contract was not delisted
What it means
OnEndOfAlgorithm asserts the traded contract was actually delisted (_delisted == true). _delisted is only set when slice.Delistings for _contractToTrade reports DelistingType.Delisted (line 102-104). If it never fired, the contract did not expire in-window, so the delisting/liquidation test path was never exercised.
Source
Thrown at Algorithm.CSharp/BasicTemplateEurexFuturesAlgorithm.cs:170
foreach (var addedSecurity in changes.AddedSecurities)
{
if (addedSecurity.Symbol.SecurityType == SecurityType.Future && addedSecurity.Symbol.IsCanonical())
{
_mappedSymbol = _continuousContract.Mapped;
}
}
}
public override void OnEndOfAlgorithm()
{
if (_mappingsCount == 0)
{
throw new RegressionTestException($"Unexpected number of symbol changed events (mappings): {_mappingsCount}. Expected 1.");
}
if (!_delisted)
{
throw new RegressionTestException("Contract was not delisted");
}
// Make sure we traded and that the position was liquidated on delisting
if (_boughtQuantity <= 0 || _liquidatedQuantity >= 0)
{
throw new RegressionTestException($"Unexpected sold quantity: {_boughtQuantity} and liquidated quantity: {_liquidatedQuantity}");
}
}
/// <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, Language.Python };View on GitHub (pinned to d2c3659f87)
Solutions
- Confirm _contractToTrade was set (a mapping occurred) and that contract's expiry falls within the end date.
- Verify the contract's delisting data (warning + delisted events) is present.
- Extend SetEndDate past the held contract's expiration if the window was shortened.
- Ensure the held contract is the sooner-expiring previous-mapped one (line 90), not the new mapped one.
Defensive patterns
Strategy: validation
Validate before calling
public override void OnEndOfAlgorithm()
{
if (!_delisted)
{
Log("Contract was not delisted in-window; verify _contractToTrade expiry vs EndDate.");
}
} Prevention
- Hold the sooner-expiring previous-mapped contract so delisting falls in-window.
- Set EndDate past the held contract's expiry.
- Confirm delisting data events are present.
When it happens
Trigger: OnEndOfAlgorithm runs with _delisted == false — no DelistingType.Delisted event arrived for _contractToTrade during the backtest. The chosen contract (the previously-mapped, sooner-expiring one) did not reach its delisting date within the window.
Common situations: Date window ended before the held contract's expiry; the delisting data event is missing; _contractToTrade was never assigned because no mapping occurred; the wrong (later-expiring) contract was held.
Related errors
- {Time} - Portfolio should not be invested after the traded c
- Unexpected number of symbol changed events (mappings): {_map
- Unexpected sold quantity: {_boughtQuantity} and liquidated q
- {Time} - Unexpected symbol changed event old symbol: {change
- {Time} - Unexpected symbol changed event new symbol: {change
AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13).
Data as JSON: /api/errors/730e6cce03c893de.
Report an issue: GitHub.