{"record":{"id":"d1d1d525682635ad","repo":"QuantConnect/Lean","slug":"expected-symbol-expected-symbol-at-index-i-on-d1d1d5","errorCode":null,"errorMessage":"Expected symbol {expected_symbol} at index {i} on {date}, but got {symbol}","messagePattern":"Expected symbol (.+?) at index (.+?) on (.+?), but got (.+?)","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"Algorithm.Python/OptionUniverseHistoryRegressionAlgorithm.py","lineNumber":47,"sourceCode":"\n        # Level 0 of the multi-index is the date, we expect 3 dates, 3 option chains\n        if historical_options_data_df.index.levshape[0] != 3:\n            raise AssertionError(f\"Expected 3 option chains from history request, but got {historical_options_data_df.index.levshape[1]}\")\n\n        for date in historical_options_data_df.index.levels[0]:\n            expected_chain = list(self.option_chain_provider.get_option_contract_list(option, date))\n            expected_chain_count = len(expected_chain)\n\n            actual_chain = historical_options_data_df.loc[date]\n            actual_chain_count = len(actual_chain)\n\n            if expected_chain_count != actual_chain_count:\n                raise AssertionError(f\"Expected {expected_chain_count} options in chain on {date}, but got {actual_chain_count}\")\n\n            for i, symbol in enumerate(actual_chain.index):\n                expected_symbol = expected_chain[i]\n                if symbol != expected_symbol:\n                    raise AssertionError(f\"Expected symbol {expected_symbol} at index {i} on {date}, but got {symbol}\")\n","sourceCodeStart":29,"sourceCodeEnd":48,"githubUrl":"https://github.com/QuantConnect/Lean/blob/d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892/Algorithm.Python/OptionUniverseHistoryRegressionAlgorithm.py#L29-L48","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before: positional comparison assumes identical ordering\nfor i, symbol in enumerate(actual_chain.index):\n    if symbol != expected_chain[i]: raise AssertionError(...)\n# after: order-independent set comparison\ndef to_key(s): return (s.id.date, s.id.strike_price, s.id.option_right)\nif sorted(map(to_key, actual_chain.index)) != sorted(map(to_key, expected_chain)):\n    raise AssertionError('chain symbols differ from provider')","handlingStrategy":"validation","validationCode":"# Order-independent comparison using stable keys\ndef key(s): return (s.id.date, s.id.strike_price, s.id.option_right)\nexpected = sorted(map(key, expected_chain))\nactual = sorted(map(key, actual_chain.index))\nif expected != actual:\n    raise AssertionError('chain symbols differ from provider')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["options","history","symbol","ordering","regression-test","quantconnect"],"backgroundTag":null,"analyzedSha":"d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892","analyzedAt":"2026-08-13T13:52:21.013Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}