{"record":{"id":"bde168984db0a5ba","repo":"microsoft/qlib","slug":"subclass-of-seriesdfilter-must-reimplement-getfil","errorCode":null,"errorMessage":"Subclass of SeriesDFilter must reimplement `getFilterSeries` method","messagePattern":"Subclass of SeriesDFilter must reimplement `getFilterSeries` method","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"qlib/data/filter.py","lineNumber":214,"sourceCode":"        \"\"\"Get filter series based on the rules assigned during the initialization and the input time range.\n\n        Parameters\n        ----------\n        instruments : dict\n            the dict of instruments to be filtered.\n        fstart : pd.Timestamp\n            start time of filter.\n        fend : pd.Timestamp\n            end time of filter.\n\n        .. note:: fstart/fend indicates the intersection of instruments start/end time and filter start/end time.\n\n        Returns\n        ----------\n        pd.Dataframe\n            a series of {pd.Timestamp => bool}.\n        \"\"\"\n        raise NotImplementedError(\"Subclass of SeriesDFilter must reimplement `getFilterSeries` method\")\n\n    def filter_main(self, instruments, start_time=None, end_time=None):\n        \"\"\"Implement this method to filter the instruments.\n\n        Parameters\n        ----------\n        instruments: dict\n            input instruments to be filtered.\n        start_time: str\n            start of the time range.\n        end_time: str\n            end of the time range.\n\n        Returns\n        ----------\n        dict\n            filtered instruments, same structure as input instruments.\n        \"\"\"","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/data/filter.py#L196-L232","documentation":"Raised by SeriesDFilter.getFilterSeries (qlib/data/filter.py), the abstract template method of the series-based instrument filter family. The base class intentionally raises NotImplementedError; every concrete subclass (e.g. SeriesTrendFilter) must override getFilterSeries to return the {pd.Timestamp => bool} series used to drop instruments. Hitting it means a subclass was used without implementing the required method.","triggerScenarios":"Instantiating SeriesDFilter directly, or subclassing it (class MyFilter(SeriesDFilter)) without overriding getFilterSeries, then calling filter_main — which internally calls getFilterSeries.","commonSituations":"Writing custom instrument filters for qlib and forgetting the override; renaming the method (e.g. get_filter_series) so the override no longer matches; copy-pasting a filter class and deleting the 'boilerplate' method.","solutions":["Implement getFilterSeries(self, instruments, fstart, fend) in your subclass, returning a pd.Series of booleans indexed by pd.Timestamp.","Alternatively derive from a concrete filter such as SeriesTrendFilter and override only what changes.","Do not instantiate the abstract SeriesDFilter itself; pick or implement a concrete subclass."],"exampleFix":"# before\nclass MyFilter(SeriesDFilter):\n    def __init__(self, ...):\n        ...\n    # getFilterSeries missing\n\n# after\nclass MyFilter(SeriesDFilter):\n    def __init__(self, ...):\n        ...\n    def getFilterSeries(self, instruments, fstart, fend):\n        # build and return pd.Series({timestamp: bool, ...})\n        return self._compute_series(instruments, fstart, fend)","handlingStrategy":"validation","validationCode":"import inspect\nif not (\n    hasattr(cls, \"getFilterSeries\") and cls.getFilterSeries is not SeriesDFilter.getFilterSeries\n):\n    raise TypeError(f\"{cls.__name__} must override getFilterSeries\")","typeGuard":"def implements_get_filter_series(cls) -> bool:\n    return getattr(cls, \"getFilterSeries\", None) is not SeriesDFilter.getFilterSeries","tryCatchPattern":null,"preventionTips":["Run a smoke instantiation of each custom filter in unit tests.","Name the override exactly getFilterSeries (camelCase) to match the base class."],"tags":["qlib","filter","abstract-method","not-implemented"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}