{"record":{"id":"ab3696a0a64b954f","repo":"microsoft/qlib","slug":"generate-portfolio-metrics-should-be-true-if-you-w","errorCode":null,"errorMessage":"generate_portfolio_metrics should be True if you want to generate portfolio_metrics","messagePattern":"generate_portfolio_metrics should be True if you want to generate portfolio_metrics","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"qlib/backtest/account.py","lineNumber":413,"sourceCode":"            trade_start_time=trade_start_time,\n            trade_exchange=trade_exchange,\n            atomic=atomic,\n            outer_trade_decision=outer_trade_decision,\n            trade_info=trade_info,\n            inner_order_indicators=inner_order_indicators,\n            decision_list=decision_list,\n            indicator_config=indicator_config,\n        )\n\n    def get_portfolio_metrics(self) -> Tuple[pd.DataFrame, dict]:\n        \"\"\"get the history portfolio_metrics and positions instance\"\"\"\n        if self.is_port_metr_enabled():\n            assert self.portfolio_metrics is not None\n            _portfolio_metrics = self.portfolio_metrics.generate_portfolio_metrics_dataframe()\n            _positions = self.get_hist_positions()\n            return _portfolio_metrics, _positions\n        else:\n            raise ValueError(\"generate_portfolio_metrics should be True if you want to generate portfolio_metrics\")\n\n    def get_trade_indicator(self) -> Indicator:\n        \"\"\"get the trade indicator instance, which has pa/pos/ffr info.\"\"\"\n        return self.indicator\n","sourceCodeStart":395,"sourceCodeEnd":418,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/backtest/account.py#L395-L418","documentation":"DiskDatasetCache._dataset_uri (qlib/data/cache.py:762) raises the same inst_processor guard as _dataset: with disk_cache != 0 and non-empty inst_processors, qlib cannot serve a shared dataset-cache URI whose contents would depend on the per-instrument processors. The fix set is identical — disk_cache=0 (client-side load path, which only walks expression caches) or no dataset cache.","triggerScenarios":"Requesting a dataset cache URI (D.features with disk_cache=1 in client/server mode, or DatasetCache.dataset with return_uri semantics) while passing inst_processors; the disk_cache=0 branch above it returns \"\" after multi_cache_walker, but any other value plus processors triggers the ValueError.","commonSituations":"Client/server qlib deployments combining instrument processors with dataset-cache serving; switching a pipeline to inst_processors without changing the disk_cache flag.","solutions":["Pass disk_cache=0 in D.features so the server only checks expression caches and the client applies inst_processors itself","Run qlib.init(dataset_cache=None) to remove the dataset cache from the provider chain","Move instrument-level processing out of the data layer into dataset processors (DataHandlerLP)"],"exampleFix":"# before\nuri = D.features(insts, fields, start, end, disk_cache=1, inst_processors=[p])  # ValueError\n\n# after\nuri = D.features(insts, fields, start, end, disk_cache=0, inst_processors=[p])","handlingStrategy":"validation","validationCode":"assert not (inst_processors and disk_cache), \\\n    \"inst_processors require disk_cache=0 with a configured dataset cache\"","typeGuard":"def safe_disk_cache(disk_cache: int, inst_processors) -> int:\n    return 0 if inst_processors else disk_cache","tryCatchPattern":"try:\n    uri = cache.dataset(insts, fields, start, end, disk_cache=1, inst_processors=procs, return_uri=True)\nexcept ValueError as e:\n    if \"does not support inst_processor\" in str(e):\n        uri = cache.dataset(insts, fields, start, end, disk_cache=0, inst_processors=procs, return_uri=True)\n    else:\n        raise","preventionTips":["In client/server deployments, encode the disk_cache=0 rule whenever processors are configured","Centralize D.features calls behind one wrapper that enforces the compatibility rule","Document which pipelines use inst_processors so cache config stays consistent"],"tags":["qlib","dataset-cache","inst-processors","client-server"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}