microsoft/qlib · error · NotImplementedError
Please implement the `prepare_tasks` method.
Error message
Please implement the `prepare_tasks` method.
What it means
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.
Source
Thrown at qlib/workflow/online/strategy.py:44
Init OnlineStrategy.
This module **MUST** use `Trainer <../reference/api.html#qlib.model.trainer.Trainer>`_ to finishing model training.
Args:
name_id (str): a unique name or id.
trainer (qlib.model.trainer.Trainer, optional): a instance of Trainer. Defaults to None.
"""
self.name_id = name_id
self.logger = get_module_logger(self.__class__.__name__)
self.tool = OnlineTool()
def prepare_tasks(self, cur_time, **kwargs) -> List[dict]:
"""
After the end of a routine, check whether we need to prepare and train some new tasks based on cur_time (None for latest)..
Return the new tasks waiting for training.
You can find the last online models by OnlineTool.online_models.
"""
raise NotImplementedError(f"Please implement the `prepare_tasks` method.")
def prepare_online_models(self, trained_models, cur_time=None) -> List[object]:
"""
Select some models from trained models and set them to online models.
This is a typical implementation to online all trained models, you can override it to implement the complex method.
You can find the last online models by OnlineTool.online_models if you still need them.
NOTE: Reset all online models to trained models. If there are no trained models, then do nothing.
**NOTE**:
Current implementation is very naive. Here is a more complex situation which is more closer to the
practical scenarios.
1. Train new models at the day before `test_start` (at time stamp `T`)
2. Switch models at the `test_start` (at time timestamp `T + 1` typically)
Args:
models (list): a list of models.
cur_time (pd.Dataframe): current time from OnlineManger. None for the latest.View on GitHub (pinned to 79633dd950)
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
Example fix
# before
class MyStrategy(OnlineStrategy):
def __init__(self):
super().__init__('my_strat')
# prepare_tasks missing -> NotImplementedError
# after
class MyStrategy(OnlineStrategy):
def __init__(self):
super().__init__('my_strat')
def prepare_tasks(self, cur_time, **kwargs) -> List[dict]:
last_models = self.tool.online_models()
# decide + return new task dicts
return [self.task_template] if len(last_models) == 0 else [] Defensive patterns
Strategy: type-guard
Validate before calling
from qlib.workflow.online.strategy import OnlineStrategy
def assert_strategy_complete(strategy):
if strategy.prepare_tasks.__func__ is OnlineStrategy.prepare_tasks:
raise TypeError(f'{type(strategy).__name__} must implement prepare_tasks') Type guard
from qlib.workflow.online.strategy import OnlineStrategy
def has_prepare_tasks(strategy) -> bool:
return strategy.prepare_tasks.__func__ is not OnlineStrategy.prepare_tasks Try / catch
try:
strategy.prepare_tasks(cur_time)
except NotImplementedError as e:
raise TypeError(f'{type(strategy).__name__} is abstract: {e}') from e Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Please implement the `first_tasks` method.
- Please implement the `get_all_stock` method
- Please implement the `get_data` method
- Please implement the `__init__` method
- Subclass of SeriesDFilter must reimplement `getFilterSeries`
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/f1188c9011996380.
Report an issue: GitHub.