QuantConnect/Lean · error · RegressionTestException
{Time} - Unexpected symbol changed event old symbol: {change
Error message
{Time} - Unexpected symbol changed event old symbol: {changedEvent} What it means
This EUREX futures regression algorithm tracks continuous-contract rollover. When Lean remaps a continuous future, it emits a SymbolChangedEvent whose OldSymbol should equal the contract that was mapped BEFORE the roll. The assertion compares changedEvent.OldSymbol against _mappedSymbol.ID.ToString() (the contract captured at last mapping/subscription start). A mismatch means Lean rolled away from a different contract than the algorithm believed was active, indicating the mapping chain diverged from expectations.
Source
Thrown at Algorithm.CSharp/BasicTemplateEurexFuturesAlgorithm.cs:80
var seeder = new FuncSecuritySeeder(GetLastKnownPrices);
SetSecurityInitializer(security => seeder.SeedSecurity(security));
}
public override void OnData(Slice slice)
{
foreach (var changedEvent in slice.SymbolChangedEvents.Values)
{
if (++_mappingsCount > 1)
{
throw new RegressionTestException($"{Time} - Unexpected number of symbol changed events (mappings): {_mappingsCount}. " +
$"Expected only 1.");
}
Debug($"{Time} - SymbolChanged event: {changedEvent}");
if (changedEvent.OldSymbol != _mappedSymbol.ID.ToString())
{
throw new RegressionTestException($"{Time} - Unexpected symbol changed event old symbol: {changedEvent}");
}
if (changedEvent.NewSymbol != _continuousContract.Mapped.ID.ToString())
{
throw new RegressionTestException($"{Time} - Unexpected symbol changed event new symbol: {changedEvent}");
}
// Let's trade the previous mapped contract, so we can hold it until expiration for testing
// (will be sooner than the new mapped contract)
_contractToTrade = _mappedSymbol;
_mappedSymbol = _continuousContract.Mapped;
}
// Let's trade after the mapping is done
if (_contractToTrade != null && _boughtQuantity == 0 && Securities[_contractToTrade].Exchange.ExchangeOpen)
{
Buy(_contractToTrade, 1);
}View on GitHub (pinned to d2c3659f87)
Solutions
- Confirm Initialize() continuous contract settings (dataMappingMode: FirstDayMonth, contractDepthOffset: 0, dataNormalizationMode: BackwardsRatio) match the data set the regression expects.
- Verify the EuroStoxx50 contract chain for the 2024-05-30..2024-06-23 window to see which contract should be the rollover source.
- Ensure the EUREX futures data is present locally (CanRunLocally / required data points); missing contracts corrupt the mapping.
- If adapting the pattern, capture _mappedSymbol fresh from _continuousContract.Mapped on each OnSecuritiesChanged canonical add rather than assuming a fixed symbol.
Defensive patterns
Strategy: validation
Validate before calling
// Before processing the change event, confirm old symbol matches expectation
foreach (var changedEvent in slice.SymbolChangedEvents.Values)
{
if (changedEvent.OldSymbol != _mappedSymbol.ID.ToString())
{
Log($"{Time} - Mapping source mismatch: event={changedEvent.OldSymbol} expected={_mappedSymbol.ID}");
continue; // or handle gracefully
}
} Try / catch
try
{
if (changedEvent.OldSymbol != _mappedSymbol.ID.ToString())
throw new RegressionTestException($"{Time} - Unexpected old symbol: {changedEvent}");
}
catch (RegressionTestException ex)
{
Log(ex.Message); // in non-regression use, log and re-map _mappedSymbol
} Prevention
- Keep _mappedSymbol in sync with _continuousContract.Mapped on each OnSecuritiesChanged canonical add.
- Pin the Lean version and EUREX dataset so the mapping chain is deterministic.
- Log every SymbolChangedEvent to audit the rollover source.
When it happens
Trigger: A SymbolChangedEvent fires during the backtest window (2024-05-30 to 2024-06-23 EuroStoxx50) and changedEvent.OldSymbol != _mappedSymbol.ID.ToString(). Occurs when the continuous contract's previously mapped symbol and the event's reported old symbol disagree — e.g. mapping mode/contractDepthOffset/data changes shifted which contract is the rollover source.
Common situations: Lean engine version upgrade changes default continuous-contract mapping rules; EUREX EuroStoxx50 dataset updated so a different contract becomes front-month; DataMappingMode.FirstDayMonth or contractDepthOffset: 0 altered in Initialize; incomplete local futures data alters the mapping chain.
Related errors
- {Time} - Unexpected symbol changed event new symbol: {change
- Unexpected number of symbol changed events (mappings): {_map
- {Time} unexpected symbol changed event {changedEvent}!
- {Time} unexpected symbol changed event {changedEvent}!
- {Time} unexpected symbol changed event {changedEvent}!
AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13).
Data as JSON: /api/errors/138176317c99aee0.
Report an issue: GitHub.