{"record":{"id":"356151639e22e7b9","repo":"QuantConnect/Lean","slug":"expected-3-option-chains-from-history-request-but","errorCode":null,"errorMessage":"Expected 3 option chains from history request, but got {historical_options_data_df.index.levshape[1]}","messagePattern":"Expected 3 option chains from history request, but got (.+?)","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"Algorithm.Python/OptionUniverseHistoryRegressionAlgorithm.py","lineNumber":32,"sourceCode":"from AlgorithmImports import *\n\n### <summary>\n### Regression algorithm testing history requests for <see cref=\"OptionUniverse\"/> type work as expected\n### and return the same data as the option chain provider.\n### </summary>\nclass OptionUniverseHistoryRegressionAlgorithm(QCAlgorithm):\n\n    def initialize(self):\n        self.set_start_date(2015, 12, 25)\n        self.set_end_date(2015, 12, 25)\n\n        option = self.add_option(\"GOOG\").symbol\n\n        historical_options_data_df = self.history(option, 3, flatten=True)\n\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":14,"sourceCodeEnd":48,"githubUrl":"https://github.com/QuantConnect/Lean/blob/d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892/Algorithm.Python/OptionUniverseHistoryRegressionAlgorithm.py#L14-L48","documentation":"OptionUniverseHistoryRegressionAlgorithm calls self.history(option, 3, flatten=True) expecting a multi-indexed DataFrame whose level-0 (date) has 3 entries (3 option chains, one per requested bar). The assertion checks historical_options_data_df.index.levshape[0] == 3. Note the message reads levshape[1] (a known copy-paste bug) while the condition checks levshape[0]; a failure means the history request returned a different number of chains than 3, indicating a history-resolution or data-availability problem for the OptionUniverse type.","triggerScenarios":"Calling history(option, 3, flatten=True) when the engine returns a DataFrame whose top multi-index level does not have exactly 3 distinct dates. Occurs when fewer than 3 bars of option-universe history exist for the date range, when flatten=True changes the index shape, or when the OptionUniverse history provider changed.","commonSituations":"Data package missing OptionUniverse history for the requested dates; a Lean change to how flatten=True shapes the index; requesting a period that extends before available data; running near the start of available option data.","solutions":["Confirm OptionUniverse history data exists for 3 trading days ending at the start date for GOOG.","Verify flatten=True still produces a 2-level multi-index with dates at level 0 after any Lean refactor.","Fix the message typo to read levshape[0] for clarity, and prefer checking the number of unique dates explicitly.","If fewer bars are available, request a shorter period or extend the data package."],"exampleFix":"# before (also fixes the levshape[1] message typo)\nif historical_options_data_df.index.levshape[0] != 3:\n    raise AssertionError(f'...got {historical_options_data_df.index.levshape[1]}')\n# after\nn_dates = historical_options_data_df.index.get_level_values(0).nunique()\nif n_dates != 3:\n    raise AssertionError(f'Expected 3 option chains, got {n_dates}')","handlingStrategy":"validation","validationCode":"# Count distinct dates explicitly instead of relying on levshape\ndf = self.history(option, 3, flatten=True)\nn_dates = df.index.get_level_values(0).nunique()\nif n_dates != 3:\n    raise AssertionError(f'Expected 3 option chains, got {n_dates}')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer counting unique level-0 dates over levshape indexing.","Ensure OptionUniverse history data spans the requested period.","Verify flatten=True index shape after Lean refactors.","Fix the message-vs-condition levshape[0]/[1] typo."],"tags":["options","history","dataframe","regression-test","quantconnect","option-universe"],"backgroundTag":null,"analyzedSha":"d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892","analyzedAt":"2026-08-13T13:52:21.013Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}