QuantConnect/Lean · error · AssertionError
Expected symbol {expected_symbol} at index {i} on {date}, bu
Error message
Expected symbol {expected_symbol} at index {i} on {date}, but got {symbol} What it means
Within a date's history chain, the regression iterates contracts in order and checks each symbol equals expected_chain[i] from the option chain provider for that date. A mismatch means the two providers return the same count but in a different order, or return different Symbols (e.g. different SecurityIdentifier/expiry/strike encoding). It guards determinism of contract ordering and symbol construction between the history and chain-provider paths.
Source
Thrown at Algorithm.Python/OptionUniverseHistoryRegressionAlgorithm.py:47
# Level 0 of the multi-index is the date, we expect 3 dates, 3 option chains
if historical_options_data_df.index.levshape[0] != 3:
raise AssertionError(f"Expected 3 option chains from history request, but got {historical_options_data_df.index.levshape[1]}")
for date in historical_options_data_df.index.levels[0]:
expected_chain = list(self.option_chain_provider.get_option_contract_list(option, date))
expected_chain_count = len(expected_chain)
actual_chain = historical_options_data_df.loc[date]
actual_chain_count = len(actual_chain)
if expected_chain_count != actual_chain_count:
raise AssertionError(f"Expected {expected_chain_count} options in chain on {date}, but got {actual_chain_count}")
for i, symbol in enumerate(actual_chain.index):
expected_symbol = expected_chain[i]
if symbol != expected_symbol:
raise AssertionError(f"Expected symbol {expected_symbol} at index {i} on {date}, but got {symbol}")
View on GitHub (pinned to d2c3659f87)
Solutions
- Ensure both the history provider and the option chain provider sort contracts by the same key (e.g. expiry, then strike, then right).
- Verify Symbol/SecurityIdentifier construction is identical in both paths.
- If order is intentionally unspecified, compare as sets instead of positional index.
- Log the differing pair (expected vs actual) to see whether it is ordering or symbol content.
Example fix
# before: positional comparison assumes identical ordering
for i, symbol in enumerate(actual_chain.index):
if symbol != expected_chain[i]: raise AssertionError(...)
# after: order-independent set comparison
def to_key(s): return (s.id.date, s.id.strike_price, s.id.option_right)
if sorted(map(to_key, actual_chain.index)) != sorted(map(to_key, expected_chain)):
raise AssertionError('chain symbols differ from provider') Defensive patterns
Strategy: validation
Validate before calling
# Order-independent comparison using stable keys
def key(s): return (s.id.date, s.id.strike_price, s.id.option_right)
expected = sorted(map(key, expected_chain))
actual = sorted(map(key, actual_chain.index))
if expected != actual:
raise AssertionError('chain symbols differ from provider') Prevention
- Sort contracts by the same key in both the history and chain-provider paths.
- If order is unspecified, compare as sets with stable keys.
- Keep Symbol/SecurityIdentifier construction identical across paths.
- Log differing pairs to distinguish ordering from symbol-content issues.
When it happens
Trigger: actual_chain.index[i] != expected_chain[i] for some i, where counts match. Caused by a sort-order difference between the history DataFrame index and get_option_contract_list, or by Symbol construction diverging (e.g. SID, strike, expiry, right) between the two paths.
Common situations: Changing the sort key (by expiry vs strike vs SID) in one path but not the other; a Symbol/SID encoding change; daylight-savings or expiry-date normalization differences producing different expiry Symbols.
Related errors
- Unexpected delisting warning event: {delisting}
- Unexpected delisting event: {delisting}
- Expected 3 option chains from history request, but got {hist
- Expected {expected_chain_count} options in chain on {date},
- Unexpected history count: {history.Count}
AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13).
Data as JSON: /api/errors/d1d1d525682635ad.
Report an issue: GitHub.