microsoft/qlib · error · ValueError
The benchmark does not exist. Please provide the right…
Error message
The benchmark {_codes} does not exist. Please provide the right benchmark What it means
After resolving benchmark codes and querying $close/Ref($close,1)-1 via get_higher_eq_freq_feature, _cal_benchmark receives an empty result and raises ValueError('The benchmark {codes} does not exist...'). The local qlib data contains no bars for the requested benchmark instrument(s) in the given time range, so no return series can be built.
Solutions
- Check the code exists in your data: D.features(['SH000300'], ['$close'], start, end, freq=freq)
- Extend benchmark_config start_time/end_time to match data coverage or drop them
- Download/provide index data with dump_bin.py, or pass benchmark as an inline pd.Series you computed yourself
Example fix
# before
benchmark_config = {"benchmark": "SH000300"} # not in local data
# after
import pandas as pd
bench_ret = pd.Series(..., index=pd.DatetimeIndex(...)) # precomputed
benchmark_config = {"benchmark": bench_ret} Defensive patterns
Strategy: validation
Validate before calling
from qlib.data import D
codes = benchmark if isinstance(benchmark, (list, dict)) else [benchmark]
df = D.features(codes, ["$close"], cfg.get("start_time"), cfg.get("end_time"), freq=freq)
assert len(df.dropna()) > 0, f"benchmark data missing for {codes}" Try / catch
try:
pm.init_bench(freq=freq, benchmark_config=cfg)
except ValueError as e:
if "does not exist" in str(e):
pm.init_bench(freq=freq, benchmark_config={"benchmark": precomputed_series}) Prevention
- Verify benchmark instruments exist in the local dump before backtests
- Use the same instrument naming convention as your data
- Fall back to an inline pd.Series benchmark when index data is unavailable
When it happens
Trigger: benchmark like 'SH000300' (or a custom list) missing from the installed data dump; start_time/end_time in benchmark_config entirely outside data coverage; wrong instrument naming convention for the dump; freq mismatch with available data.
Common situations: Using the small qlib demo data (which may lack index data) with the default CSI300 benchmark; custom datasets without benchmark indices; date ranges before the index existed; instrument name typos ('000300' vs 'SH000300').
Related errors
- benchmark freq can't be None!
- Both trade_end_time and bench_value is None, benchmark is…
- doesn't have close price in qlib in the latest days
- None in [trade_start_time, account_value, cash…
- df is empty.
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/6d9bfba154fddc07.
Report an issue: GitHub.
Appendix: source
Thrown at qlib/backtest/report.py:116
if benchmark_config is None:
return None
benchmark = benchmark_config.get("benchmark", CSI300_BENCH)
if benchmark is None:
return None
if isinstance(benchmark, pd.Series):
return benchmark
else:
start_time = benchmark_config.get("start_time", None)
end_time = benchmark_config.get("end_time", None)
if freq is None:
raise ValueError("benchmark freq can't be None!")
_codes = benchmark if isinstance(benchmark, (list, dict)) else [benchmark]
fields = ["$close/Ref($close,1)-1"]
_temp_result, _ = get_higher_eq_freq_feature(_codes, fields, start_time, end_time, freq=freq)
if len(_temp_result) == 0:
raise ValueError(f"The benchmark {_codes} does not exist. Please provide the right benchmark")
return (
_temp_result.groupby(level="datetime", group_keys=False)[_temp_result.columns.tolist()[0]]
.mean()
.fillna(0)
)
def _sample_benchmark(
self,
bench: pd.Series,
trade_start_time: Union[str, pd.Timestamp],
trade_end_time: Union[str, pd.Timestamp],
) -> Optional[float]:
if self.bench is None:
return None
def cal_change(x):
return (x + 1).prod()
View on GitHub (pinned to 79633dd950)