microsoft/qlib · error · ValueError

The benchmark {_codes} does not exist. Please provide the ri

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.

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)

Solutions

  1. Check the code exists in your data: D.features(['SH000300'], ['$close'], start, end, freq=freq)
  2. Extend benchmark_config start_time/end_time to match data coverage or drop them
  3. 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

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


AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15). Data as JSON: /api/errors/6d9bfba154fddc07. Report an issue: GitHub.