2.53 The Roofing Filter: Band-Limit Before You Build Any Indicator
Oscillators drift and whipsaw because raw price feeds them trend and noise at once. The roofing filter, a high-pass plus a SuperSmoother, strips both and passes only the tradeable cycle band first.
The old article "Feature Engineering Before Machine Learning" made the case that what you feed an indicator decides its ceiling, and that most of the achievable edge is won or lost before any model sees the data. The old article "High-Pass Filters for Traders" and the old article "The Trader's Guide to Low-Pass Filters" gave you the two tools to control that input. The roofing filter is what you get when you put them in series, and it answers a question almost no retail trader asks before slapping an RSI on a chart: what cycles am I even letting into this thing?
Every indicator runs on whatever spectrum you hand it
Linear systems theory frames any indicator as three boxes: input, transfer, output. Traders obsess over the transfer box, the indicator formula itself, and ignore the input box entirely, which is where the damage happens. Closing prices contain everything at once: a slow multi-month trend, a tradeable cycle in the middle, and fast bar-to-bar noise. Feed that raw stew into an oscillator and the oscillator dutifully responds to all three. An RSI computed on raw price drifts because the slow trend is dragging its baseline, and it whipsaws because the fast noise is jiggling its numerator. The oscillator was never broken; you handed it garbage at both ends of the spectrum.
The roofing filter fixes the input box before the transfer box ever runs. It strips the two ends you do not want and passes only the band in the middle where tradeable cycles live.
$$ \text{prices} \;\longrightarrow\; \underbrace{\text{High-Pass}}_{\text{kill slow trend}} \;\longrightarrow\; \underbrace{\text{SuperSmoother}}_{\text{kill fast noise}} \;\longrightarrow\; \text{indicator (RSI, etc.)} $$
Two filters, two cutoffs, one clean band
The first stage is the high-pass filter from the old high-pass article. A high-pass passes fast cycles and removes slow ones, so set its cutoff at a long period, around 40 to 48 bars, and it strips out everything slower than that: the multi-month drift, the wandering baseline, the brownian trend component. What survives is detrended, centered, free of the slow drag that was tilting your oscillator.
The second stage is the SuperSmoother, the two-pole low-pass from the old low-pass article. A low-pass passes slow cycles and removes fast ones, so set its cutoff at a short period, around 10 bars, and it removes everything faster than that: the single-bar jitter, the microstructure noise, the high-frequency garbage that produces false oscillator crossings. The SuperSmoother matters specifically because it is the critically-damped two-pole design that gives a clean 12 dB-per-octave rolloff without the overshoot and ringing a naive smoother adds, so it kills noise without inventing wiggles of its own.
Cascade the two and the high-pass sets the roof while the SuperSmoother sets the floor. What passes is a band, roughly 10 to 48 bars in this example, which is why a roofing filter is a wide-band band-pass built from a high-pass and a low-pass stacked together.
$$ \text{High-Pass cutoff (e.g. 48 bars)} \;=\; \text{upper period limit (roof)} \qquad \text{SuperSmoother cutoff (e.g. 10 bars)} \;=\; \text{lower period limit (floor)} $$
The two cutoffs are choices, not constants. Set the roof to the longest cycle you consider tradeable and the floor just above the noise you cannot trade, and recognize that picking them is itself a modeling decision you should make deliberately rather than inheriting from a default.
Why this beats reaching for a different oscillator
The output of the roofing filter is useful two ways. You can read it directly as a detrended, denoised oscillator that crosses zero at cycle turns, or you can use it as the input to a conventional indicator. Feed roofed prices into an RSI and the RSI behaves: its baseline stops drifting because the trend is gone, and its crossings stop chattering because the noise is gone, so the same formula that looked useless on raw price becomes a clean cycle reader. You did not change the indicator. You fixed what you fed it.
This is the old feature-engineering article's thesis made concrete. When an oscillator misbehaves, the reflex is to try a different oscillator, or to tune its length, or to add a confirming indicator on top. The roofing filter says the problem is upstream: you never controlled the input spectrum, so you were asking the indicator to separate trend, cycle, and noise all at once, a job it was never built to do. Band-limit first, and every downstream indicator gets easier.
Keep the honest caveats from the filter articles in view. Band-limiting reshapes history, it does not predict; the roofing filter makes a cleaner feature, not a forecast. Both stages cost lag, and a sharper roof or floor costs more of it, so you are trading responsiveness for cleanliness exactly as the low-pass article warned. And a beautifully band-limited input still has to earn its keep: a clean cycle feature that carries no predictive value on your instrument is a clean feature that loses money, which is the empirical test the feature-engineering article insisted you run before trusting any of this.

KEY POINTS
- Every indicator is input-transfer-output; traders tune the transfer (the formula) and ignore the input. Raw price carries slow trend, a middle cycle, and fast noise all at once, so an oscillator fed raw price drifts on the trend and whipsaws on the noise.
- The roofing filter fixes the input first: a high-pass stage removes the slow trend (the roof) and a SuperSmoother low-pass stage removes the fast noise (the floor), passing only the tradeable cycle band in between.
- Set the high-pass cutoff at a long period (around 40-48 bars) and the SuperSmoother at a short one (around 10 bars); the result is a wide-band band-pass. The cutoffs are deliberate modeling choices, not defaults.
- The SuperSmoother is the critically-damped two-pole low-pass from the old low-pass article, chosen because it rolls off noise cleanly without the overshoot and ringing a naive smoother adds.
- Use the output directly as a detrended denoised oscillator, or feed roofed prices into a conventional indicator like RSI; the same formula that looked useless on raw price becomes a clean cycle reader because its baseline stops drifting and its crossings stop chattering.
- It reshapes history, it does not predict; both stages cost lag, and a band-limited input still has to pass the empirical test from the old feature-engineering article that the band you kept actually carries predictive value.
References
- Cycle Analytics for Traders - John Ehlers (Amazon)
- Predictive and Successful Indicators (Ehlers, roofing filter and SuperSmoother)
- The Scientist and Engineer's Guide to Digital Signal Processing: Filter Combinations
- Bandpass filters and cascaded high-pass/low-pass design (Stanford CCRMA)
- Butterworth and critically-damped low-pass filters (overview)