microsoft/qlib · error · ValueError
{lack_stock} doesn't have close price in qlib in the latest
Error message
{lack_stock} doesn't have close price in qlib in the latest {last_days} days What it means
Position.fill_stock_value tries to backfill missing prices for the initial holdings by querying D.features for '$close' over the last `last_days` (default 30) days before backtest start. If any instrument has no non-NaN close price in that window, it raises ValueError listing the offending stocks. It almost always means the qlib data provider has no (or only NaN) bars for those instruments before the backtest start date.
Source
Thrown at qlib/backtest/position.py:318
return
start_time = pd.Timestamp(start_time)
# note that start time is 2020-01-01 00:00:00 if raw start time is "2020-01-01"
price_end_time = start_time
price_start_time = start_time - timedelta(days=last_days)
price_df = D.features(
stock_list,
["$close"],
price_start_time,
price_end_time,
freq=freq,
disk_cache=True,
).dropna()
price_dict = price_df.groupby(["instrument"], group_keys=False).tail(1)["$close"].to_dict()
if len(price_dict) < len(stock_list):
lack_stock = set(stock_list) - set(price_dict)
raise ValueError(f"{lack_stock} doesn't have close price in qlib in the latest {last_days} days")
for stock in stock_list:
self.position[stock]["price"] = price_dict[stock]
self.position["now_account_value"] = self.calculate_value()
def _init_stock(self, stock_id: str, amount: float, price: float | None = None) -> None:
"""
initialization the stock in current position
Parameters
----------
stock_id :
the id of the stock
amount : float
the amount of the stock
price :
the price when buying the init stock
"""View on GitHub (pinned to 79633dd950)
Solutions
- Provide the 'price' field explicitly for each stock in the initial position config so fill_stock_value skips them
- Push the backtest start_time later, past the listing date of every held instrument
- Increase last_days (e.g. fill_stock_value(start, freq, last_days=120)) if the stock was suspended longer
- Verify the instruments exist in your data: D.features([stock], ['$close'], start, end, freq=freq) and drop delisted names from the initial position
Example fix
# before
position_dict = {"SH600000": {"amount": 1000, "price": None}}
# after
position_dict = {"SH600000": {"amount": 1000, "price": 11.5}} Defensive patterns
Strategy: validation
Validate before calling
from qlib.data import D
lack = [s for s, v in position.position.items() if isinstance(v, dict) and v.get("price") is None]
if lack:
df = D.features(lack, ["$close"], start_time - pd.Timedelta(days=30), start_time, freq=freq)
missing = set(lack) - set(df.dropna().index.get_level_values("instrument").unique())
assert not missing, f"no close price for {missing}" Try / catch
try:
position.fill_stock_value(start_time, freq)
except ValueError as e:
# drop unpriceable holdings or extend window and retry once
position.fill_stock_value(start_time, freq, last_days=120) Prevention
- Always set 'price' in initial position configs
- Pre-check data coverage with D.features before backtest start
- Keep last_days larger than the longest suspension you expect
When it happens
Trigger: Building a Position from a config/dict whose stock entries lack a 'price' key, then running fill_stock_value(start_time, freq). Occurs when: the instrument is not in the local bin data; the backtest start_time is before the instrument's listing date (new IPO); wrong freq passed; delisted/suspended stock with no recent close.
Common situations: Warm-starting a backtest with an inherited real portfolio that includes recently listed stocks; using cn_data demo dump that lacks some instruments; passing freq='1min' while only daily data exists; start_time set earlier than data coverage.
Related errors
- Please implement the `settle_conf` method
- Please implement the `settle_commit` method
- {} not in current position
- only have {} {}, require {}
- This type of input is not supported
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/de01234c06d10378.
Report an issue: GitHub.