{"record":{"id":"01595e0f1f5c1609","repo":"microsoft/qlib","slug":"benchmark-freq-can-t-be-none","errorCode":null,"errorMessage":"benchmark freq can't be None!","messagePattern":"benchmark freq can't be None!","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"qlib/backtest/report.py","lineNumber":111,"sourceCode":"        self.benchmark_config = benchmark_config\n        self.bench = self._cal_benchmark(self.benchmark_config, self.freq)\n\n    @staticmethod\n    def _cal_benchmark(benchmark_config: Optional[dict], freq: str) -> Optional[pd.Series]:\n        if benchmark_config is None:\n            return None\n        benchmark = benchmark_config.get(\"benchmark\", CSI300_BENCH)\n        if benchmark is None:\n            return None\n\n        if isinstance(benchmark, pd.Series):\n            return benchmark\n        else:\n            start_time = benchmark_config.get(\"start_time\", None)\n            end_time = benchmark_config.get(\"end_time\", None)\n\n            if freq is None:\n                raise ValueError(\"benchmark freq can't be None!\")\n            _codes = benchmark if isinstance(benchmark, (list, dict)) else [benchmark]\n            fields = [\"$close/Ref($close,1)-1\"]\n            _temp_result, _ = get_higher_eq_freq_feature(_codes, fields, start_time, end_time, freq=freq)\n            if len(_temp_result) == 0:\n                raise ValueError(f\"The benchmark {_codes} does not exist. Please provide the right benchmark\")\n            return (\n                _temp_result.groupby(level=\"datetime\", group_keys=False)[_temp_result.columns.tolist()[0]]\n                .mean()\n                .fillna(0)\n            )\n\n    def _sample_benchmark(\n        self,\n        bench: pd.Series,\n        trade_start_time: Union[str, pd.Timestamp],\n        trade_end_time: Union[str, pd.Timestamp],\n    ) -> Optional[float]:\n        if self.bench is None:","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/backtest/report.py#L93-L129","documentation":"PortfolioMetric.init_bench -> _cal_benchmark builds the benchmark return series from data. If the benchmark is given as code(s) (not an inline pd.Series) the series must be fetched at frequency `freq`; when freq is None the query cannot be formed and ValueError('benchmark freq can't be None!') is raised. freq is stored on init_bench(freq=...) — it is None when the metric was initialized without freq and never set.","triggerScenarios":"Creating PortfolioMetric (or calling init_bench) with a benchmark_config containing a string/list benchmark but no freq argument; e.g. PortfolioMetric(benchmark_config={'benchmark': 'SH000300'}) with freq left None, then any code path that materializes the bench.","commonSituations":"Migrating report code that previously supplied freq via a global/config; calling init_bench(benchmark_config=...) and forgetting the freq keyword; high-frequency backtests where freq is carried in executor config but not passed to the metric.","solutions":["Pass a freq when initializing: PortfolioMetric(..., freq='day') or init_bench(freq='day', benchmark_config=cfg)","Call init_bench with an explicit freq each time you change benchmark_config","Alternatively supply the benchmark as a precomputed pd.Series, which bypasses the freq requirement"],"exampleFix":"# before\npm.init_bench(benchmark_config={\"benchmark\": \"SH000300\"})\n\n# after\npm.init_bench(freq=\"day\", benchmark_config={\"benchmark\": \"SH000300\"})","handlingStrategy":"validation","validationCode":"bench = (benchmark_config or {}).get(\"benchmark\")\nif bench is not None and not isinstance(bench, pd.Series):\n    assert freq is not None, \"benchmark freq can't be None — pass freq='day' (or your freq)\"","typeGuard":"def needs_freq(benchmark_config) -> bool:\n    b = (benchmark_config or {}).get(\"benchmark\")\n    return b is not None and not isinstance(b, pd.Series)","tryCatchPattern":"try:\n    pm.init_bench(freq=freq, benchmark_config=cfg)\nexcept ValueError as e:\n    pm.init_bench(freq=\"day\", benchmark_config=cfg)  # retry with explicit freq","preventionTips":["Always pass freq when a benchmark is configured","Or provide the benchmark as a pd.Series to bypass data fetching"],"tags":["qlib","backtest","benchmark","report","missing-argument"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}