microsoft/qlib · error · NotImplementedError

Please implement the `get_data` method

Error message

Please implement the `get_data` method

What it means

BaseQuote is an abstract base class for quote-data containers in qlib's high-performance backtest layer. Its get_data(stock_id, start_time, end_time, field, method) method only raises NotImplementedError; every concrete subclass must override it. Hitting this error means you instantiated BaseQuote directly (or a subclass that failed to override get_data) and then queried data.

Source

Thrown at qlib/backtest/high_performance_ds.py:100

        start_time : Union[pd.Timestamp, str]
            closed start time for backtest
        end_time : Union[pd.Timestamp, str]
            closed end time for backtest
        field : str
            the columns of data to fetch
        method : Union[str, None]
            the method apply to data.
            e.g [None, "last", "all", "sum", "mean", "ts_data_last"]

        Return
        ----------
        Union[None, int, float, bool, IndexData]
            it will return None in following cases
            - There is no stock data which meet the query criterion from data source.
            - The `method` returns None
        """

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


class PandasQuote(BaseQuote):
    def __init__(self, quote_df: pd.DataFrame, freq: str) -> None:
        super().__init__(quote_df=quote_df, freq=freq)
        quote_dict = {}
        for stock_id, stock_val in quote_df.groupby(level="instrument", group_keys=False):
            quote_dict[stock_id] = stock_val.droplevel(level="instrument")
        self.data = quote_dict

    def get_all_stock(self):
        return self.data.keys()

    def get_data(self, stock_id, start_time, end_time, field, method=None):
        if method == "ts_data_last":
            method = ts_data_last
        stock_data = resam_ts_data(self.data[stock_id][field], start_time, end_time, method=method)
        if stock_data is None:

View on GitHub (pinned to 79633dd950)

Solutions

  1. Use a concrete implementation: PandasQuote (qlib/backtest/high_performance_ds.py:103) or NumpyQuote (line 128)
  2. If you subclass BaseQuote, implement get_all_stock and get_data with the documented signature (returns None | int | float | bool | IndexData)
  3. Audit custom Quote subclasses with inspect.getmembers to confirm every abstract-style method is overridden before use

Example fix

// before
quote = BaseQuote(quote_df, freq="day")
close = quote.get_data("SH600000", "2010-01-04", "2010-01-06", "$close")
// after
from qlib.backtest.high_performance_ds import NumpyQuote
quote = NumpyQuote(quote_df, freq="day")
close = quote.get_data("SH600000", "2010-01-04", "2010-01-06", "$close")
Defensive patterns

Strategy: type-guard

Validate before calling

from qlib.backtest.high_performance_ds import BaseQuote, PandasQuote, NumpyQuote
assert type(quote) is not BaseQuote, "use PandasQuote or NumpyQuote, not BaseQuote"
assert isinstance(quote, (PandasQuote, NumpyQuote))

Type guard

def is_concrete_quote(q) -> bool:
    from qlib.backtest.high_performance_ds import BaseQuote, PandasQuote, NumpyQuote
    return isinstance(q, (PandasQuote, NumpyQuote)) and not type(q) is BaseQuote

Prevention

When it happens

Trigger: Calling BaseQuote(quote_df, freq).get_data(...), or passing a BaseQuote-typed object that is not a PandasQuote/NumpyQuote into code that fetches bars (e.g. qlib.backtest exchange/account machinery that calls quote.get_data).

Common situations: Custom quote backends that subclass BaseQuote but forget to implement get_data; test code or REPL experiments constructing the base class directly; type-annotated factory code that defaults to BaseQuote instead of a concrete class.

Related errors


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