{"record":{"id":"ddacd3faef0070b2","repo":"microsoft/qlib","slug":"infposition-doesn-t-support-calculating-value","errorCode":null,"errorMessage":"InfPosition doesn't support calculating value","messagePattern":"InfPosition doesn't support calculating value","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"qlib/backtest/position.py","lineNumber":534,"sourceCode":"        return True\n\n    def update_order(self, order: Order, trade_val: float, cost: float, trade_price: float) -> None:\n        pass\n\n    def update_stock_price(self, stock_id: str, price: float) -> None:\n        pass\n\n    def calculate_stock_value(self) -> float:\n        \"\"\"\n        Returns\n        -------\n        float:\n            infinity stock value\n        \"\"\"\n        return np.inf\n\n    def calculate_value(self) -> float:\n        raise NotImplementedError(f\"InfPosition doesn't support calculating value\")\n\n    def get_stock_list(self) -> List[str]:\n        raise NotImplementedError(f\"InfPosition doesn't support stock list position\")\n\n    def get_stock_price(self, code: str) -> float:\n        \"\"\"the price of the inf position is meaningless\"\"\"\n        return np.nan\n\n    def get_stock_amount(self, code: str) -> float:\n        return np.inf\n\n    def get_cash(self, include_settle: bool = False) -> float:\n        return np.inf\n\n    def get_stock_amount_dict(self) -> dict:\n        raise NotImplementedError(f\"InfPosition doesn't support get_stock_amount_dict\")\n\n    def get_stock_weight_dict(self, only_stock: bool = False) -> dict:","sourceCodeStart":516,"sourceCodeEnd":552,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/backtest/position.py#L516-L552","documentation":"InfPosition is a position with infinite cash and amount used to generate/accept arbitrary orders; total account value is mathematically infinite and undefined to compute, so calculate_value() deliberately raises NotImplementedError. Its components (calculate_stock_value -> np.inf, get_cash -> np.inf) are fine; only the aggregate 'value' API is blocked.","triggerScenarios":"Calling calculate_value() on an InfPosition: report/account code (e.g. PortfolioMetric.fill or risk metric generators) that computes now_account_value per step, plugged into a flow that was given an InfPosition.","commonSituations":"Using InfPosition (often via exchange config for order generation) but also attaching a PortfolioMetric/reporter that evaluates account value each bar; reusing code written for Position on an InfPosition instance.","solutions":["Use the concrete Position class when your flow needs account-value reporting","Skip/gate metric calculation: check isinstance(position, InfPosition) before calling calculate_value","In custom reporters, rely on calculate_stock_value() (returns np.inf) instead of the unsupported aggregate"],"exampleFix":"# before\nvalue = position.calculate_value()\n\n# after\nfrom qlib.backtest.position import InfPosition\nvalue = None if isinstance(position, InfPosition) else position.calculate_value()","handlingStrategy":"type-guard","validationCode":"from qlib.backtest.position import InfPosition\nif isinstance(position, InfPosition):\n    return  # account value undefined; skip reporting","typeGuard":"def can_calculate_value(pos) -> bool:\n    from qlib.backtest.position import InfPosition\n    return not isinstance(pos, InfPosition)","tryCatchPattern":"try:\n    value = position.calculate_value()\nexcept NotImplementedError:\n    value = None  # InfPosition: value reporting disabled","preventionTips":["Do not attach value-based reporters to InfPosition flows","Check isinstance(position, InfPosition) before metric collection"],"tags":["qlib","backtest","position","inf-position","not-implemented"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}