QuantConnect/Lean · error · AssertionError
FuturesChain() returned contract with no data.
Error message
FuturesChain() returned contract with no data.
What it means
Data-quality assertion in a FuturesChain regression: for every row in the futures_chain(future, flatten=True).data_frame, if bidprice, askprice AND volume are all 0 the test aborts, proving every returned contract has at least some market data.
Source
Thrown at Algorithm.Python/FuturesChainFullDataRegressionAlgorithm.py:35
### Regression algorithm illustrating the usage of the <see cref="QCAlgorithm.FuturesChain(Symbol, bool)"/>
### method to get a future chain.
### </summary>
class FuturesChainFullDataRegressionAlgorithm(QCAlgorithm):
def initialize(self):
self.set_start_date(2013, 10, 7)
self.set_end_date(2013, 10, 7)
future = self.add_future(Futures.Indices.SP_500_E_MINI, Resolution.MINUTE).symbol
chain = self.futures_chain(future, flatten=True)
# Demonstration using data frame:
df = chain.data_frame
for index, row in df.iterrows():
if row['bidprice'] == 0 and row['askprice'] == 0 and row['volume'] == 0:
raise AssertionError("FuturesChain() returned contract with no data.");
# Get contracts expiring within 6 months, with the latest expiration date, and lowest price
contracts = df.loc[(df.expiry <= self.time + timedelta(days=180))]
contracts = contracts.sort_values(['expiry', 'lastprice'], ascending=[False, True])
self._future_contract = contracts.index[0]
self.add_future_contract(self._future_contract)
def on_data(self, data):
# Do some trading with the selected contract for sample purposes
if not self.portfolio.invested:
self.set_holdings(self._future_contract, 0.5)
else:
self.liquidate()
View on GitHub (pinned to d2c3659f87)
Solutions
- Identify which contract (index) has all-zero bid/ask/volume and inspect its data file.
- Filter the chain to contracts that actually have data before trading.
- Confirm the resolution requested matches the data granularity available.
- Re-run the data generator / re-download the affected contract.
Example fix
// before
for index, row in df.iterrows():
if row['bidprice'] == 0 and row['askprice'] == 0 and row['volume'] == 0:
raise AssertionError("FuturesChain() returned contract with no data.")
// after - filter out empty contracts instead of failing
df = df[~((df['bidprice'] == 0) & (df['askprice'] == 0) & (df['volume'] == 0))] Defensive patterns
Strategy: validation
Validate before calling
# Filter empty-data contracts before trading
mask = ~((df['bidprice'] == 0) & (df['askprice'] == 0) & (df['volume'] == 0))
empty = df[~mask]
if not empty.empty:
self.debug(f"Contracts with no data: {list(empty.index)}")
df = df[mask] Type guard
def contract_has_data(row) -> bool:
return not (row['bidprice'] == 0 and row['askprice'] == 0 and row['volume'] == 0) Prevention
- Filter the chain to contracts with non-zero data before selecting.
- Match requested resolution to available data granularity.
- Inspect data files for contracts reported empty.
- Re-download or regenerate data for illiquid contracts.
When it happens
Trigger: The chain returning a contract whose data file has no quotes and no trades for the requested bar; a stale or placeholder contract entry with zero data; flatten=True surfacing contracts that have no row-level data.
Common situations: Data drop missing quote/trade files for one contract; chain provider returning expired/illiquid contracts with no activity; resolution mismatch so no bar aggregates; data refresh inserting empty rows.
Related errors
- [{UtcTime}] We hold a delisted securities: {string.Join(",",
- Expected at least two future contracts with option chains, b
- The Exchange hours was closed, verify 'extended_market_hours
- The Algorithms was not handled any StopMarketOrders
- Expected 3 futures chains from history request, but got {his
AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13).
Data as JSON: /api/errors/0d679fbe1ce7086f.
Report an issue: GitHub.