QuantConnect/Lean · error · RegressionTestException
{Time} - Unexpected symbol changed event new symbol: {change
Error message
{Time} - Unexpected symbol changed event new symbol: {changedEvent} What it means
The companion assertion to the old-symbol check: after a continuous-future rollover, the SymbolChangedEvent.NewSymbol must equal the contract that Lean now reports as _continuousContract.Mapped. A mismatch means the event's reported destination contract differs from the engine's current mapped contract, signalling a divergence between the event stream and the continuous-contract security state.
Source
Thrown at Algorithm.CSharp/BasicTemplateEurexFuturesAlgorithm.cs:85
{
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);
}
if (_contractToTrade != null && slice.Delistings.TryGetValue(_contractToTrade, out var delisting))
{
if (delisting.Type == DelistingType.Delisted)
{View on GitHub (pinned to d2c3659f87)
Solutions
- Validate the continuous-contract configuration (mapping mode, depth offset, normalization) against the expected data set.
- Check that only one mapping event occurs in the backtest (the _mappingsCount > 1 guard at line 70 has not tripped).
- Confirm EUREX futures data completeness; a missing destination contract makes NewSymbol fall back unexpectedly.
- Re-read _continuousContract.Mapped at event time rather than caching, to compare against current engine state.
Defensive patterns
Strategy: validation
Validate before calling
foreach (var changedEvent in slice.SymbolChangedEvents.Values)
{
var currentMapped = _continuousContract.Mapped.ID.ToString();
if (changedEvent.NewSymbol != currentMapped)
{
Log($"{Time} - Mapping dest mismatch: event={changedEvent.NewSymbol} mapped={currentMapped}");
}
} Prevention
- Re-read _continuousContract.Mapped at event-processing time rather than caching.
- Ensure only one mapping event occurs (guard _mappingsCount).
- Pin Lean version and EUREX data for deterministic destination contracts.
When it happens
Trigger: A SymbolChangedEvent fires and changedEvent.NewSymbol != _continuousContract.Mapped.ID.ToString(). The destination contract in the event does not match the live continuous-contract Mapped symbol at the moment the event is processed.
Common situations: Engine version change alters how/when Mapped is updated relative to event emission; multiple mapping events queued in one slice; data change shifts the destination contract; contractDepthOffset adjusted so a different expiry becomes the new mapped contract.
Related errors
- {Time} - Unexpected symbol changed event old 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/9780493e24b1fa8e.
Report an issue: GitHub.