QuantConnect/Lean · error · ValueError

futureChainSymbolSelector must return future symbols.

Error message

futureChainSymbolSelector must return future symbols.

What it means

FutureUniverseSelectionModel.create_universes() iterates the user-supplied future_chain_symbol_selector and builds a FutureChain per returned symbol. Each returned symbol MUST be of SecurityType.Future; any other security type raises ValueError because the model can only construct future chains for future underlyings.

Source

Thrown at Algorithm.Framework/Selection/FutureUniverseSelectionModel.py:50

        self.future_chain_symbol_selector = futureChainSymbolSelector
        self.universe_settings = universeSettings

    def get_next_refresh_time_utc(self):
        '''Gets the next time the framework should invoke the `CreateUniverses` method to refresh the set of universes.'''
        return self.next_refresh_time_utc

    def create_universes(self, algorithm: QCAlgorithm) -> list[Universe]:
        '''Creates a new fundamental universe using this class's selection functions
        Args:
            algorithm: The algorithm instance to create universes for
        Returns:
            The universe defined by this model'''
        self.next_refresh_time_utc = algorithm.utc_time + self.refresh_interval

        unique_symbols = set()
        for future_symbol in self.future_chain_symbol_selector(algorithm.utc_time):
            if future_symbol.SecurityType != SecurityType.FUTURE:
                raise ValueError("futureChainSymbolSelector must return future symbols.")

            # prevent creating duplicate future chains -- one per symbol
            if future_symbol not in unique_symbols:
                unique_symbols.add(future_symbol)
                selection = self.filter
                if hasattr(self, "Filter") and callable(self.Filter):
                    selection = self.Filter
                for universe in Extensions.create_future_chain(algorithm, future_symbol, selection, self.universe_settings):
                    yield universe

    def filter(self, filter):
        '''Defines the future chain universe filter'''
        # NOP
        return filter

View on GitHub (pinned to d2c3659f87)

Solutions

  1. Ensure the selector returns only future symbols, e.g. Symbol.Create(Futures.Indices.SP500EMini, SecurityType.Future, Market.CME) or the QuantConnect future canonical.
  2. Validate each returned symbol's security_type == SecurityType.FUTURE before returning it from the selector.
  3. Double-check the Symbol.Create call's security-type argument — it's the second positional parameter.

Example fix

# before
def selector(utc):
    return [Symbol.Create('SPY', SecurityType.Equity, Market.USA)]  # wrong type -> raises

# after
def selector(utc):
    return [Symbol.Create(Futures.Indices.SP500EMini, SecurityType.Future, Market.CME)]
Defensive patterns

Strategy: validation

Validate before calling

def future_selector(utc):
    syms = my_selector(utc)
    bad = [s for s in syms if s.security_type != SecurityType.FUTURE]
    if bad:
        raise ValueError(f'Non-future symbols returned: {bad}')
    return syms

Type guard

def all_are_futures(symbols) -> bool:
    return all(s.security_type == SecurityType.FUTURE for s in symbols)

Prevention

When it happens

Trigger: The future_chain_symbol_selector callback returns a Symbol whose SecurityType is not SecurityType.FUTURE (e.g., an equity, option, index, or forex symbol slipped in).

Common situations: Using Symbol.Create or Symbol.CreateFuture incorrectly (wrong security type), returning underlying equity symbols instead of future canonicals, or a typo in the canonical symbol string.

Related errors


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