microsoft/qlib · error · NotImplementedError

InfPosition doesn't support calculating value

Error message

InfPosition doesn't support calculating value

What it means

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.

Source

Thrown at qlib/backtest/position.py:534

        return True

    def update_order(self, order: Order, trade_val: float, cost: float, trade_price: float) -> None:
        pass

    def update_stock_price(self, stock_id: str, price: float) -> None:
        pass

    def calculate_stock_value(self) -> float:
        """
        Returns
        -------
        float:
            infinity stock value
        """
        return np.inf

    def calculate_value(self) -> float:
        raise NotImplementedError(f"InfPosition doesn't support calculating value")

    def get_stock_list(self) -> List[str]:
        raise NotImplementedError(f"InfPosition doesn't support stock list position")

    def get_stock_price(self, code: str) -> float:
        """the price of the inf position is meaningless"""
        return np.nan

    def get_stock_amount(self, code: str) -> float:
        return np.inf

    def get_cash(self, include_settle: bool = False) -> float:
        return np.inf

    def get_stock_amount_dict(self) -> dict:
        raise NotImplementedError(f"InfPosition doesn't support get_stock_amount_dict")

    def get_stock_weight_dict(self, only_stock: bool = False) -> dict:

View on GitHub (pinned to 79633dd950)

Solutions

  1. Use the concrete Position class when your flow needs account-value reporting
  2. Skip/gate metric calculation: check isinstance(position, InfPosition) before calling calculate_value
  3. In custom reporters, rely on calculate_stock_value() (returns np.inf) instead of the unsupported aggregate

Example fix

# before
value = position.calculate_value()

# after
from qlib.backtest.position import InfPosition
value = None if isinstance(position, InfPosition) else position.calculate_value()
Defensive patterns

Strategy: type-guard

Validate before calling

from qlib.backtest.position import InfPosition
if isinstance(position, InfPosition):
    return  # account value undefined; skip reporting

Type guard

def can_calculate_value(pos) -> bool:
    from qlib.backtest.position import InfPosition
    return not isinstance(pos, InfPosition)

Try / catch

try:
    value = position.calculate_value()
except NotImplementedError:
    value = None  # InfPosition: value reporting disabled

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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