Skip to content

03 Modules Signals Signals Module

Łukasz Rafał Czarnacki edited this page Mar 9, 2026 · 2 revisions

Signals Module

Source package: src/trade_lab/signals

Source files:

  • base.py
  • signals.py
  • temporal.py
  • external.py

This page covers both true signals and the ExternalSignal helper that is re-exported from trade_lab.signals.

What Signals Do

Signals take a DataFrame with OHLCV data and append new columns. You can chain signals together by passing one signal as source to another.

BaseSignal (base.py)

BaseSignal is the parent class for all signals.

__init__(source=None, lag=0)

  • Stores optional upstream signal in source.
  • Stores lag (how many bars to shift output columns backward).
  • Raises ValueError if lag < 0.

get_data(df)

  • If source exists, computes the source first and returns its output DataFrame.
  • If no source, returns the input df unchanged.
  • Purpose: make signal chaining consistent.

compute(df)

  • Public method used to run a signal.
  • Calls subclass _compute(df) to create raw signal columns.
  • If lag > 0, shifts each raw output column by lag bars.
  • Renames lagged outputs with suffix _lag{lag}.
  • Returns the updated DataFrame.

output_columns (property)

  • Returns final output column names.
  • If lag == 0, names are raw names.
  • If lag > 0, adds _lag{lag} suffix.

_compute(df) (abstract)

  • Must be implemented in each concrete signal.
  • Should write data into _raw_output_columns.

plot(df) (abstract)

  • Must be implemented in each concrete signal.
  • Should visualize signal outputs.

_raw_output_columns (abstract property)

  • Must return raw column names created by _compute.
  • Used by compute for lag renaming/shifting.

OHLC (signals.py)

OHLC creates log-normalized features from standard OHLC columns.

_compute(df)

  • Calls get_data(df) to resolve optional source chain.
  • Uses previous close: Close(t-1).
  • Creates four columns:
    • signal__log_return_open
    • signal__log_return_high
    • signal__log_return_low
    • signal__log_return_close
  • Formula for each price P: log(P(t) / Close(t-1)).

HeikinAshi (signals.py)

HeikinAshi computes Heikin-Ashi bars and then log-normalizes them.

_compute(df)

  • Calls get_data(df).
  • Computes HA Open/High/Low/Close from input OHLC.
  • Saves raw HA bars internally for plotting.
  • Creates normalized output columns:
    • signal__ha_open
    • signal__ha_high
    • signal__ha_low
    • signal__ha_close

CyclicalTemporalSignal (temporal.py)

CyclicalTemporalSignal encodes calendar time as sine/cosine features.

Important behavior

  • Works from df.index (must be datetime-like).
  • Does not accept a source signal.
  • Creates signal__<component>_p<period>_sin and signal__<component>_p<period>_cos.

ExternalSignal (external.py)

ExternalSignal is a convenience wrapper for ML workflows. Despite the import path, it subclasses BaseIndicator, not BaseSignal.

What it does

  • Reads an existing column already present in the DataFrame.
  • Optionally applies a normalization callback.
  • Writes the result as indicator__<name>__lag_0 (plus _lagN suffix when lagged).
  • Integrates cleanly with MLStrategy, FeatureMatrix, and feature auto-discovery.

Important limitations

  • It does not accept upstream source signals.
  • It does not implement to_signal_strength() for StandardStrategy.
  • Use it for ML features such as VIX, rates, macro series, or sentiment data that you merged yourself before calling TradeLab.

Constructor

__init__(column, name=None, normalization=None, lag=0)

  • column: required source column in the DataFrame
  • name: optional friendly output name
  • normalization: optional Callable[[pd.Series], pd.Series]
  • lag: handled by the base indicator implementation

Practical Notes

  • Always call compute(df) (not _compute) in normal usage.
  • lag helps prevent look-ahead leakage in feature engineering.
  • Chaining works for signals that use source; temporal signal is intentionally independent.
  • ExternalSignal is ML-only and expects its input column to already exist in df.

Clone this wiki locally