Signal Combiner
Horizon includes a signal combination system for building composite alpha signals from multiple data sources. Core math is implemented in Rust for performance, with Python pipeline factories for ergonomic use inhz.run().
Signals are functions that extract a single float value (typically 0 to 1) from the current market context. The signal combiner merges multiple signals into a single composite score that can drive downstream quoting or sizing decisions.
Overview
Weighted Average
hz.combine_signals() with "weighted_avg" method for importance-weighted combination.Built-in Extractors
5 ready-to-use signal extractors: price, spread, momentum, flow, and imbalance.
EMA Smoothing
hz.ema() for exponential smoothing of noisy signal values.Time Decay
hz.decay_weight() for exponential half-life weighting of stale data.Core Functions
hz.combine_signals
Combine multiple weighted signal values into a single score.
Methods:
"weighted_avg"- Weighted mean:sum(v*w) / sum(w). Zero-weight signals are filtered out."rank"- Rank-based: converts values to percentile ranks, then weighted average."zscore"- Z-score normalization: standardizes values, then maps back to 0-1 via sigmoid.
hz.ema
Compute the exponential moving average of a series.
Returns 0.0 for empty input or zero span.
hz.zscore
Compute the z-score of a value given mean and standard deviation.hz.decay_weight
Compute an exponential decay weight based on age and half-life.
Returns 0.0 for negative age or zero half-life.
Pipeline Factory: hz.signal_combiner
Thesignal_combiner() factory returns a pipeline function that evaluates and combines signals on each cycle.
Parameters
If a signal raises an exception during evaluation, it is skipped (not propagated). This ensures robustness when feeds are temporarily unavailable.
Built-in Signal Extractors
Each extractor returns aSignal object with a name, fn, and weight.
hz.price_signal
Extracts the mid price from a feed. Returns the raw price (typically 0 to 1 for prediction markets).hz.spread_signal
Measures bid-ask tightness. Tighter spreads produce higher values (closer to 1.0).1.0 - min(spread / 0.20, 1.0) where spread = ask - bid.
hz.momentum_signal
Tracks rolling price momentum. Values above 0.5 indicate an uptrend, below 0.5 indicate a downtrend.hz.flow_signal
Estimates buy/sell flow direction from price tick movements. Values above 0.5 indicate net buying pressure.hz.imbalance_signal
Estimates orderbook imbalance from bid/ask prices. Values above 0.5 indicate buy-side pressure.Examples
Basic Signal Combination
Custom Signal with Built-in Combiner
Signal + Kelly Sizing
Signal + Market Maker
Signal Dataclass
TheSignal dataclass is used to define custom signals: