QuantConnect/Lean · error · AssertionError

Expected 3 option chains from history request, but got {hist

Error message

Expected 3 option chains from history request, but got {historical_options_data_df.index.levshape[1]}

What it means

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.

Source

Thrown at Algorithm.Python/OptionUniverseHistoryRegressionAlgorithm.py:32

from AlgorithmImports import *

### <summary>
### Regression algorithm testing history requests for <see cref="OptionUniverse"/> type work as expected
### and return the same data as the option chain provider.
### </summary>
class OptionUniverseHistoryRegressionAlgorithm(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2015, 12, 25)
        self.set_end_date(2015, 12, 25)

        option = self.add_option("GOOG").symbol

        historical_options_data_df = self.history(option, 3, flatten=True)

        # 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

  1. Confirm OptionUniverse history data exists for 3 trading days ending at the start date for GOOG.
  2. Verify flatten=True still produces a 2-level multi-index with dates at level 0 after any Lean refactor.
  3. Fix the message typo to read levshape[0] for clarity, and prefer checking the number of unique dates explicitly.
  4. If fewer bars are available, request a shorter period or extend the data package.

Example fix

# before (also fixes the levshape[1] message typo)
if historical_options_data_df.index.levshape[0] != 3:
    raise AssertionError(f'...got {historical_options_data_df.index.levshape[1]}')
# after
n_dates = historical_options_data_df.index.get_level_values(0).nunique()
if n_dates != 3:
    raise AssertionError(f'Expected 3 option chains, got {n_dates}')
Defensive patterns

Strategy: validation

Validate before calling

# Count distinct dates explicitly instead of relying on levshape
df = self.history(option, 3, flatten=True)
n_dates = df.index.get_level_values(0).nunique()
if n_dates != 3:
    raise AssertionError(f'Expected 3 option chains, got {n_dates}')

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13). Data as JSON: /api/errors/356151639e22e7b9. Report an issue: GitHub.