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
- Ensure the selector returns only future symbols, e.g. Symbol.Create(Futures.Indices.SP500EMini, SecurityType.Future, Market.CME) or the QuantConnect future canonical.
- Validate each returned symbol's security_type == SecurityType.FUTURE before returning it from the selector.
- 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
- Always pass SecurityType.Future as the second arg to Symbol.Create for future canonicals.
- Return canonical future symbols, not underlying equities or indices.
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
- optionChainSymbolSelector must return option, index options,
- Future contracts did not work up as expected: {addedSecurity
- Future contracts did not work up as expected: {addedSecurity
- ShareClassMeanReversionAlphaModel: symbols parameter must co
- {Time} - Unexpected symbol changed event old symbol: {change
AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13).
Data as JSON: /api/errors/a4162ad8e5039b68.
Report an issue: GitHub.