SD Signal Decay & Alpha Erosion
Every edge has an expiration date — the question is how long yours lasts
Learning Objectives
- •Understand why trading signals lose predictive power over time
- •Measure the half-life of alpha for different signal types
- •Build monitoring systems for signal degradation
- •Develop strategies for maintaining a signal pipeline
Explain Like I'm 5
Signals decay because markets learn. Once enough people discover the same pattern, the edge disappears — sometimes slowly, sometimes overnight.
Think of It This Way
It's like a fishing spot. The first person who finds it catches plenty. Word gets out, more people show up, and eventually the fish are gone. But new spots always form — you just need to keep exploring.
1Why Signals Decay
2Half-Life of Alpha
3Measuring Decay
4When a Signal Dies
5Building a Signal Pipeline
Key Formulas
Signal Half-Life
Time for a signal's IC to decay to half its initial value, where lambda is the exponential decay rate
Decayed IC Estimate
Expected IC at time t given initial IC and decay rate
Hands-On Code
Signal Decay Monitor
import numpy as np
from scipy.optimize import curve_fit
def measure_signal_decay(rolling_ic_series, time_periods):
"""
Fit exponential decay model to rolling IC and estimate half-life.
Parameters:
rolling_ic_series: array of rolling IC values
time_periods: array of corresponding time indices
Returns:
decay_params: dict with lambda, half_life, initial_ic, r_squared
"""
def decay_model(t, ic0, lam):
return ic0 * np.exp(-lam * t)
mask = rolling_ic_series > 0
if mask.sum() < 10:
return {'status': 'insufficient_positive_ic_data'}
try:
popt, pcov = curve_fit(
decay_model,
time_periods[mask],
rolling_ic_series[mask],
p0=[rolling_ic_series[mask].max(), 0.01],
bounds=([0, 0], [1, 2])
)
ic0, lam = popt
half_life = np.log(2) / lam if lam > 0 else np.inf
predicted = decay_model(time_periods[mask], ic0, lam)
ss_res = np.sum((rolling_ic_series[mask] - predicted) ** 2)
ss_tot = np.sum((rolling_ic_series[mask] - np.mean(rolling_ic_series[mask])) ** 2)
r_squared = 1 - ss_res / ss_tot
return {
'initial_ic': round(ic0, 4),
'decay_rate': round(lam, 4),
'half_life_months': round(half_life, 1),
'r_squared': round(r_squared, 3),
'status': 'decaying' if lam > 0.01 else 'stable'
}
except RuntimeError:
return {'status': 'fit_failed'}Fits an exponential decay model to rolling IC data and estimates signal half-life, initial IC, decay rate, and goodness of fit.
Knowledge Check
Q1.McLean & Pontiff (2016) found that factor returns decline by approximately what percentage after academic publication?
Q2.Which type of signal typically has the shortest half-life?
Q3.What is the most robust early warning sign of signal decay?
Assignment
Take any momentum or mean-reversion signal and compute its rolling 60-day IC across 3+ years of data. Fit an exponential decay model and estimate the half-life. Compare the half-life across different volatility regimes (VIX > 20 vs VIX < 20).