{"record":{"id":"4cdbb92268c6e924","repo":"microsoft/qlib","slug":"both-trade-end-time-and-bench-value-is-none-bench","errorCode":null,"errorMessage":"Both trade_end_time and bench_value is None, benchmark is not usable.","messagePattern":"Both trade_end_time and bench_value is None, benchmark is not usable\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"qlib/backtest/report.py","lineNumber":185,"sourceCode":"        # check data\n        if None in [\n            trade_start_time,\n            account_value,\n            cash,\n            return_rate,\n            total_turnover,\n            turnover_rate,\n            total_cost,\n            cost_rate,\n            stock_value,\n        ]:\n            raise ValueError(\n                \"None in [trade_start_time, account_value, cash, return_rate, total_turnover, turnover_rate, \"\n                \"total_cost, cost_rate, stock_value]\",\n            )\n\n        if trade_end_time is None and bench_value is None:\n            raise ValueError(\"Both trade_end_time and bench_value is None, benchmark is not usable.\")\n        elif bench_value is None:\n            bench_value = self._sample_benchmark(self.bench, trade_start_time, trade_end_time)\n\n        # update pm data\n        self.accounts[trade_start_time] = account_value\n        self.returns[trade_start_time] = return_rate\n        self.total_turnovers[trade_start_time] = total_turnover\n        self.turnovers[trade_start_time] = turnover_rate\n        self.total_costs[trade_start_time] = total_cost\n        self.costs[trade_start_time] = cost_rate\n        self.values[trade_start_time] = stock_value\n        self.cashes[trade_start_time] = cash\n        self.benches[trade_start_time] = bench_value\n        # update pm\n        self.latest_pm_time = trade_start_time\n        # finish pm update in each step\n\n    def generate_portfolio_metrics_dataframe(self) -> pd.DataFrame:","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/backtest/report.py#L167-L203","documentation":"In PortfolioMetric.fill, the benchmark value for the step is either passed in (bench_value) or sampled from self.bench between trade_start_time and trade_end_time. If both are None there is no way to compute the benchmark leg, so ValueError('Both trade_end_time and bench_value is None, benchmark is not usable.') is raised before any data is recorded.","triggerScenarios":"Calling fill without trade_end_time and without bench_value while a benchmark series is configured; or with trade_end_time=None and bench=None (no benchmark was given at init, so _sample_benchmark returns None and the passed bench_value is None).","commonSituations":"Single-timestamp fills (intraday steps with no end time) that still carry a benchmark config; benchmark_config set to None so init produced self.bench = None, while fill still expects a bench value.","solutions":["Pass trade_end_time (even equal to trade_start_time) whenever a benchmark is configured","Or pass bench_value explicitly (e.g. 0.0) for steps where no benchmark sampling applies","If you do not want benchmark comparison, construct the metric without benchmark_config so the bench path is skipped"],"exampleFix":"# before\npm.fill(trade_start_time=t, account_value=v, cash=c, ..., bench_value=None)\n\n# after\npm.fill(trade_start_time=t, trade_end_time=t, account_value=v, cash=c, ..., bench_value=0.0)","handlingStrategy":"validation","validationCode":"if trade_end_time is None and bench_value is None:\n    bench_value = 0.0  # or pass trade_end_time=trade_start_time\n    # choose based on whether benchmark comparison matters for this step","typeGuard":null,"tryCatchPattern":"try:\n    pm.fill(..., trade_end_time=trade_end_time, bench_value=bench_value)\nexcept ValueError as e:\n    if \"benchmark is not usable\" in str(e):\n        pm.fill(..., bench_value=0.0)  # retry without benchmark sampling","preventionTips":["Always pass trade_end_time to fill","Pass an explicit bench_value for single-timestamp steps","Drop benchmark_config entirely if you do not report benchmark-relative metrics"],"tags":["qlib","backtest","benchmark","report","missing-argument"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}