microsoft/qlib · error · NotImplementedError
_update_model is not implemented!
Error message
_update_model is not implemented!
What it means
ModelSignal (qlib/backtest/signal.py) is created from a (model, dataset) tuple and is supposed to lazily produce prediction scores. Updating the model with freshly arriving online data each bar (online/mobile backtest mode) is planned but not implemented — the docstring explicitly says the online update path is a TODO. Calling _update_model raises NotImplementedError by design.
Source
Thrown at qlib/backtest/signal.py:85
class ModelSignal(SignalWCache):
def __init__(self, model: BaseModel, dataset: Dataset) -> None:
self.model = model
self.dataset = dataset
pred_scores = self.model.predict(dataset)
if isinstance(pred_scores, pd.DataFrame):
pred_scores = pred_scores.iloc[:, 0]
super().__init__(pred_scores)
def _update_model(self) -> None:
"""
When using online data, update model in each bar as the following steps:
- update dataset with online data, the dataset should support online update
- make the latest prediction scores of the new bar
- update the pred score into the latest prediction
"""
# TODO: this method is not included in the framework and could be refactor later
raise NotImplementedError("_update_model is not implemented!")
def create_signal_from(
obj: Union[Signal, Tuple[BaseModel, Dataset], List, Dict, Text, pd.Series, pd.DataFrame],
) -> Signal:
"""
create signal from diverse information
This method will choose the right method to create a signal based on `obj`
Please refer to the code below.
"""
if isinstance(obj, Signal):
return obj
elif isinstance(obj, (tuple, list)):
return ModelSignal(*obj)
elif isinstance(obj, (dict, str)):
return init_instance_by_config(obj)
elif isinstance(obj, (pd.DataFrame, pd.Series)):
return SignalWCache(signal=obj)View on GitHub (pinned to 79633dd950)
Solutions
- Use precomputed prediction scores: call model.predict(dataset) first and pass the resulting Series/DataFrame to create_signal_from, which yields SignalWCache instead of ModelSignal.
- Save predictions to a file and create the signal from a dict config pointing at that file (SignalWCache from a pickle path).
- If per-bar model updates are genuinely needed, subclass ModelSignal and implement _update_model yourself (update dataset with online data, re-predict, refresh scores).
- Check whether your executor/strategy config sets an online-update flag you can disable.
Example fix
# before signal = create_signal_from((model, dataset)) # ModelSignal -> NotImplementedError on update # after pred = model.predict(dataset) signal = create_signal_from(pred) # SignalWCache, safe in online loops
Defensive patterns
Strategy: validation
Validate before calling
from qlib.backtest.signal import SignalWCache, ModelSignal # before starting an online/looped simulation, reject ModelSignal assert not isinstance(signal, ModelSignal) or not online_mode, 'ModelSignal cannot update online; precompute scores'
Type guard
from qlib.backtest.signal import SignalWCache
def is_precomputed_signal(s) -> bool:
return isinstance(s, SignalWCache) Try / catch
try:
signal.update(...) # online loop
except NotImplementedError as e:
if '_update_model' in str(e):
raise RuntimeError('Precompute model.predict() and use SignalWCache for online simulation') from e
raise Prevention
- For online simulations, always create signals from precomputed pandas scores.
- Run model.predict(dataset) once and cache results to disk before entering the execution loop.
When it happens
Trigger: Running an online/incremental simulation where the executor loop calls signal update hooks each bar (e.g. nested execution with online data via signal.update_score/update paths), while the signal was built from a (model, dataset) tuple via create_signal_from.
Common situations: Users run qlib's online serving / mobile backtest examples that expect SignalWCache (precomputed scores) but pass a model+dataset tuple instead; or they upgrade to a qlib version where the online loop now invokes _update_model unconditionally.
Related errors
- nfs-common is not found, please install it by execute: sudo
- Mount failed: requires sudo or permission denied
- mount {provider_uri} on {mount_path} error! Command error
- Mount failed: {e.stderr}
- We can't find the project path
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/b4accdba31c2a388.
Report an issue: GitHub.