microsoft/qlib · error · NotImplementedError

Please implement the `add` method

Error message

Please implement the `add` method

What it means

BaseSingleMetric.add(other, fill_value=None) is abstract. Per its docstring it adds two metrics after replacing NaN with fill_value in both — the NaN-handling counterpart to __add__. The base class raises NotImplementedError; SingleMetric implements it. Calling .add(...) on a bare BaseSingleMetric raises this error.

Source

Thrown at qlib/backtest/high_performance_ds.py:283

    def count(self) -> int:
        """Return the count of the single metric, NaN is not included."""

        raise NotImplementedError(f"Please implement the `count` method")

    def abs(self) -> BaseSingleMetric:
        raise NotImplementedError(f"Please implement the `abs` method")

    @property
    def empty(self) -> bool:
        """If metric is empty, return True."""

        raise NotImplementedError(f"Please implement the `empty` method")

    def add(self, other: BaseSingleMetric, fill_value: float = None) -> BaseSingleMetric:
        """Replace np.nan with fill_value in two metrics and add them."""

        raise NotImplementedError(f"Please implement the `add` method")

    def replace(self, replace_dict: dict) -> BaseSingleMetric:
        """Replace the value of metric according to replace_dict."""

        raise NotImplementedError(f"Please implement the `replace` method")

    def apply(self, func: Callable) -> BaseSingleMetric:
        """Replace the value of metric with func (metric).
        Currently, the func is only qlib/backtest/order/Order.parse_dir.
        """

        raise NotImplementedError(f"Please implement the 'apply' method")


class BaseOrderIndicator:
    """
    The data structure of order indicator.
    !!!NOTE: There are two ways to organize the data structure. Please choose a better way.

View on GitHub (pinned to 79633dd950)

Solutions

  1. Use SingleMetric.add(other, fill_value=...), which mirrors pandas' fill_value semantics
  2. Implement add(self, other, fill_value) in your subclass: fill NaN on both sides, then add element-wise
  3. Alternatively pre-fill both underlying Series with .fillna(fill_value) and use +

Example fix

# before
total = BaseSingleMetric(today).add(BaseSingleMetric(yesterday), fill_value=0.0)
# after
from qlib.backtest.high_performance_ds import SingleMetric
total = SingleMetric(today).add(SingleMetric(yesterday), fill_value=0.0)
Defensive patterns

Strategy: type-guard

Validate before calling

from qlib.backtest.high_performance_ds import BaseSingleMetric
assert type(m).add is not BaseSingleMetric.add, "object does not implement add(fill_value=...)"

Type guard

def supports_add_method(m) -> bool:
    from qlib.backtest.high_performance_ds import BaseSingleMetric
    return isinstance(m, BaseSingleMetric) and type(m).add is not BaseSingleMetric.add

Prevention

When it happens

Trigger: m1.add(m2, fill_value=0.0) where m1 is a raw BaseSingleMetric; combining two per-stock metrics whose stock universes differ (e.g. today's positions + yesterday's cash-flow series with missing instruments); subclasses implementing __add__ but not add().

Common situations: Time-series accumulation of daily metrics where coverage changes day to day; aligning metrics with disjoint stock ids; porting pandas Series.add(fill_value=...) idioms onto metric objects.

Related errors


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