Quant Memo
Core

Feature Half-Life and Smoothing Choices

How much to smooth a noisy raw signal into a feature, and why the smoothing window's half-life should be chosen to match how fast the underlying information actually decays, not picked for convenience.

Prerequisites: Lag and Rolling-Window Features

A raw daily signal — say, order-book imbalance or a single day's price move — is usually too jumpy to feed straight into a model; a lot of what moves it day to day is noise that won't repeat tomorrow. Smoothing averages recent observations together to keep the real, persistent part of the signal while damping the noise. But smooth too aggressively and you also erase the genuine, fast-moving information the model needed — the feature becomes a lagging indicator of something that's already over by the time it fires.

An analogy: a car's speedometer versus its trip-average

A speedometer updates instantly and shows every bump and lift of the accelerator — responsive, but jittery if you're trying to gauge overall pace. A trip-average speed smooths all of that into one stable number, but if you slam the brakes right now, the trip average won't reflect it for a long time. Feature smoothing is choosing where on that spectrum a given signal belongs: fast enough to catch real, tradeable changes; slow enough to not be dominated by noise that means nothing tomorrow.

The standard way to control this is an exponentially weighted moving average, where each new observation xtx_t updates the smoothed feature sts_t as

st=λxt+(1λ)st1,s_t = \lambda x_t + (1-\lambda) s_{t-1},

with decay parameter λ\lambda between 0 and 1. In plain English: the new feature value is a blend of today's fresh reading and yesterday's smoothed value, and λ\lambda controls how much weight goes to "today" versus "history." This is usually described instead by its half-life hh — the number of periods after which a past observation's weight has decayed to half its original influence — related to λ\lambda by

h=ln(0.5)ln(1λ).h = \frac{\ln(0.5)}{\ln(1-\lambda)}.

In plain English: half-life is a more intuitive way of expressing the same smoothing strength — "this feature forgets an old data point's influence within about hh days" — rather than working directly with the more abstract decay parameter.

Worked example: matching half-life to a signal's own persistence

Suppose research shows an order-flow imbalance signal is genuinely informative about returns over roughly the next 3 days, then loses predictive power. A half-life of h=3h=3 days gives λ=10.51/30.206\lambda = 1 - 0.5^{1/3} \approx 0.206: about 20.6% weight on today's reading, decaying to half its influence after 3 days — matched to the signal's own useful life. Using instead a h=20h=20-day half-life (λ0.034\lambda \approx 0.034) would smooth the imbalance so heavily that the feature mostly reflects flow from two or three weeks ago, well past the point the signal actually predicted anything — the model would be trading on an echo of information that already played out. Conversely, using h=1h=1 day (λ=0.5\lambda = 0.5) barely smooths at all, and the feature would be dominated by single-day noise the 3-day signal was never meant to capture on its own.

raw short h long h
A short half-life tracks the raw signal's real moves closely; a long half-life flattens it almost to a constant, erasing information the underlying signal only holds briefly.

What this means in practice

Half-life is a hyperparameter that should be set from evidence about how long the underlying information actually stays predictive — an autocorrelation or decay study on the raw signal against forward returns — not chosen by default (many pipelines use a 20-day EWMA reflexively because it's a common convention elsewhere) or tuned purely by grid search on in-sample fit, which invites overfitting the smoothing constant to noise. Different features in the same model often need very different half-lives: a slow-moving valuation ratio and a fast order-flow signal should not share a smoothing window.

Choose a feature's smoothing half-life to match how long the underlying signal is genuinely informative, using h=ln(0.5)/ln(1λ)h = \ln(0.5)/\ln(1-\lambda) to translate between the intuitive half-life and the EWMA decay parameter λ\lambda. Too short leaves noise in; too long smooths away the real signal along with it.

Related concepts

Practice in interviews

Further reading

  • Chan, Algorithmic Trading, ch. 3
ShareTwitterLinkedIn