microsoft/qlib · error · NotImplementedError

This type of signal is not supported

Error message

This type of signal is not supported

What it means

create_signal_from in qlib/backtest/signal.py dispatches on the runtime type of its obj argument: Signal is returned as-is, tuple/list becomes ModelSignal(*obj), dict/str is treated as a config for init_instance_by_config, and pandas DataFrame/Series becomes SignalWCache. Any other type (int, None, numpy array, ndarray, torch tensor, etc.) falls into the else branch and raises NotImplementedError.

Source

Thrown at qlib/backtest/signal.py:105

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)
    else:
        raise NotImplementedError(f"This type of signal is not supported")

View on GitHub (pinned to 79633dd950)

Solutions

  1. Pass a pandas Series (typically named 'score') or DataFrame so SignalWCache is used.
  2. If you have a config describing the signal class, pass the dict or its YAML string path.
  3. If you have model+dataset, pass them as a tuple/list so ModelSignal is built.
  4. Convert numpy arrays back: create_signal_from(pd.Series(arr, index=dates)).

Example fix

# before
signal = create_signal_from(pred.values)  # ndarray -> NotImplementedError
# after
signal = create_signal_from(pd.Series(pred.values, index=pred.index, name='score'))
Defensive patterns

Strategy: type-guard

Validate before calling

import pandas as pd
from qlib.backtest.signal import Signal
SUPPORTED = (Signal, tuple, list, dict, str, pd.DataFrame, pd.Series)
assert isinstance(obj, SUPPORTED), f'create_signal_from cannot handle {type(obj).__name__}'

Type guard

import pandas as pd

def is_signal_source(obj) -> bool:
    return isinstance(obj, (tuple, list, dict, str, pd.DataFrame, pd.Series))

Try / catch

try:
    sig = create_signal_from(obj)
except NotImplementedError:
    if isinstance(obj, pd.DataFrame):
        obj = obj['score']
    sig = create_signal_from(pd.Series(getattr(obj, 'values', obj)))

Prevention

When it happens

Trigger: Calling create_signal_from with a numpy.ndarray, torch.Tensor, None, or a bare object that is not one of the six supported container types; commonly happens when model.predict output is converted to .values or .to_numpy() before being passed in.

Common situations: Users convert predictions to numpy for serialization and forget to convert back to pandas; pass a path object (Path) instead of str; or pass a lambda/function as a signal source.

Related errors


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