{"record":{"id":"f1188c9011996380","repo":"microsoft/qlib","slug":"please-implement-the-prepare-tasks-method","errorCode":null,"errorMessage":"Please implement the `prepare_tasks` method.","messagePattern":"Please implement the `prepare_tasks` method\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"qlib/workflow/online/strategy.py","lineNumber":44,"sourceCode":"        Init OnlineStrategy.\n        This module **MUST** use `Trainer <../reference/api.html#qlib.model.trainer.Trainer>`_ to finishing model training.\n\n        Args:\n            name_id (str): a unique name or id.\n            trainer (qlib.model.trainer.Trainer, optional): a instance of Trainer. Defaults to None.\n        \"\"\"\n        self.name_id = name_id\n        self.logger = get_module_logger(self.__class__.__name__)\n        self.tool = OnlineTool()\n\n    def prepare_tasks(self, cur_time, **kwargs) -> List[dict]:\n        \"\"\"\n        After the end of a routine, check whether we need to prepare and train some new tasks based on cur_time (None for latest)..\n        Return the new tasks waiting for training.\n\n        You can find the last online models by OnlineTool.online_models.\n        \"\"\"\n        raise NotImplementedError(f\"Please implement the `prepare_tasks` method.\")\n\n    def prepare_online_models(self, trained_models, cur_time=None) -> List[object]:\n        \"\"\"\n        Select some models from trained models and set them to online models.\n        This is a typical implementation to online all trained models, you can override it to implement the complex method.\n        You can find the last online models by OnlineTool.online_models if you still need them.\n\n        NOTE: Reset all online models to trained models. If there are no trained models, then do nothing.\n\n        **NOTE**:\n            Current implementation is very naive. Here is a more complex situation which is more closer to the\n            practical scenarios.\n            1. Train new models at the day before `test_start` (at time stamp `T`)\n            2. Switch models at the `test_start` (at time timestamp `T + 1` typically)\n\n        Args:\n            models (list): a list of models.\n            cur_time (pd.Dataframe): current time from OnlineManger. None for the latest.","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/workflow/online/strategy.py#L26-L62","documentation":"OnlineStrategy.prepare_tasks is an abstract hook: the base class intentionally raises NotImplementedError telling you to override it. It fires whenever the online workflow calls strategy.prepare_tasks(cur_time) on a subclass that did not provide the method — i.e. you instantiated a custom OnlineStrategy (or a subclass) that is still incomplete.","triggerScenarios":"Defining a class inheriting OnlineStrategy without overriding prepare_tasks, then running OnlineManager.routine or calling prepare_tasks directly; instantiating OnlineStrategy itself (it is effectively abstract); a typo in the override name (e.g. prepare_task) so the base method runs.","commonSituations":"Writing a custom online strategy for the first time and forgetting one of the required hooks; copying an example strategy but renaming the method incorrectly; upgrading qlib and missing that a new hook method is required.","solutions":["Implement prepare_tasks(cur_time, **kwargs) -> List[dict] in your subclass that decides whether new tasks should be trained based on cur_time (None = latest) and returns them","If you do not need custom logic, use the provided RollingStrategy which implements prepare_tasks via its rolling_gen","Verify the override signature and spelling match exactly (prepare_tasks, plural) so Python actually overrides the base method"],"exampleFix":"# before\nclass MyStrategy(OnlineStrategy):\n    def __init__(self):\n        super().__init__('my_strat')\n    # prepare_tasks missing -> NotImplementedError\n\n# after\nclass MyStrategy(OnlineStrategy):\n    def __init__(self):\n        super().__init__('my_strat')\n    def prepare_tasks(self, cur_time, **kwargs) -> List[dict]:\n        last_models = self.tool.online_models()\n        # decide + return new task dicts\n        return [self.task_template] if len(last_models) == 0 else []","handlingStrategy":"type-guard","validationCode":"from qlib.workflow.online.strategy import OnlineStrategy\n\ndef assert_strategy_complete(strategy):\n    if strategy.prepare_tasks.__func__ is OnlineStrategy.prepare_tasks:\n        raise TypeError(f'{type(strategy).__name__} must implement prepare_tasks')","typeGuard":"from qlib.workflow.online.strategy import OnlineStrategy\n\ndef has_prepare_tasks(strategy) -> bool:\n    return strategy.prepare_tasks.__func__ is not OnlineStrategy.prepare_tasks","tryCatchPattern":"try:\n    strategy.prepare_tasks(cur_time)\nexcept NotImplementedError as e:\n    raise TypeError(f'{type(strategy).__name__} is abstract: {e}') from e","preventionTips":["Prefer composing RollingStrategy over subclassing OnlineStrategy from scratch","At startup, assert each hook resolves to your subclass (strategy.prepare_tasks.__func__ is not the base function)","Run a one-line smoke test instantiating and calling each hook after writing a new strategy"],"tags":["qlib","online-strategy","abstract-method","not-implemented"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}