QuantConnect/Lean · error · AssertionError

Option chain was not received.

Error message

Option chain was not received.

What it means

OptionUniverseFilterGreeksRegressionAlgorithm sets a flag option_chain_received when on_data sees a non-empty chain for self.option_symbol; on_end_of_algorithm asserts it was set. A failure means no option chain ever arrived in on_data during the whole backtest, so the filter and Greek logic was never exercised. It guards against the filter being so restrictive (or data being absent) that the algorithm silently did nothing.

Source

Thrown at Algorithm.Python/OptionUniverseFilterGreeksRegressionAlgorithm.py:91

        '''
        return universe \
            .d(self._min_delta, self._max_delta) \
            .g(self._min_gamma, self._max_gamma) \
            .v(self._min_vega, self._max_vega) \
            .t(self._min_theta, self._max_theta) \
            .r(self._min_rho, self._max_rho) \
            .iv(self._min_iv, self._max_iv) \
            .oi(self._min_open_interest, self._max_open_interest)
        '''

    def on_data(self, slice: Slice) -> None:
        chain = slice.option_chains.get(self.option_symbol)
        if chain and len(chain.contracts) > 0:
            self.option_chain_received = True

    def on_end_of_algorithm(self) -> None:
        if not self.option_chain_received:
            raise AssertionError("Option chain was not received.")

View on GitHub (pinned to d2c3659f87)

Solutions

  1. Loosen the filter ranges (especially the tight Greek/IV/OI bounds) so at least some contracts pass and a chain arrives.
  2. Verify GOOG option data exists for the backtest date in Lean/Data.
  3. Confirm option_symbol matches the add_option result and that set_filter was registered.
  4. Add a debug log in on_data printing slice.option_chains keys to confirm the subscription resolves.

Example fix

# before: filter removes everything -> no chain ever received
.delta(0.99, 1.01).gamma(0.00059, 0.00061)...
# after: realistic ranges
.delta(self._min_delta, self._max_delta).gamma(self._min_gamma, self._max_gamma)...
Defensive patterns

Strategy: validation

Validate before calling

# In on_end_of_algorithm, give a clear reason when no chain arrived
if not self.option_chain_received:
    # was the filter too tight, or data missing?
    self.log('No option chain received; check filter ranges and data availability')
    raise AssertionError('Option chain was not received.')

Prevention

When it happens

Trigger: on_end_of_algorithm runs with self.option_chain_received still False because every on_data call had slice.option_chains.get(self.option_symbol) return None or an empty chain. Caused by an over-restrictive filter excluding all contracts, missing option data for the date, or a wrong option_symbol.

Common situations: Setting filter ranges that exclude every contract; pointing at a data package lacking GOOG options for 2015-12-24; a typo in the underlying ticker or option_symbol mismatch; the option subscription not being enabled.

Related errors


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