Digital Signal Processing
This part of the toolbox borrows a set of tools from engineering — digital signal processing, or DSP — and points them at price. The idea is to treat a chart as a signal rather than a list of numbers: a wiggly line made of an underlying movement plus a lot of noise. Once you look at it that way you can ask useful questions. How long is the market's current swing? Is there a real rhythm here, or is it mostly random? Where is the trend underneath the chop? The functions on these pages are built to answer exactly those questions.
You do not need the maths to use any of it. The sections below explain the ideas in plain English, and the map at the end points you to the right function for each job.
Built on proven work — and extended
These tools come from more than one place, and the toolbox is not a museum piece — it improves on the originals. Knowing the lineage helps you read the rest of this section:
- The cycle and Hilbert-transform tools — DominantCycle, HilbertPeriod, CyberCycle, MAMA, SineWave, HilbertOscillator, InstantTrendline and the signal-to-noise gauges — grow out of the work of John Ehlers, an engineer who adapted radio and radar techniques to markets (his books Rocket Science for Traders and Cybernetic Analysis for Stocks and Futures are the original sources).
- The frequency transforms — EndPointFFT and Goertzel — come instead from the published work of Dennis Meyers, who showed how to turn the Fourier and Goertzel transforms into curves you can actually trade in real time rather than hindsight curve-fits.
- The toolbox's own additions. The cycle indicators are no longer tied to one fixed method: a selectable spectral engine lets you measure the cycle with Homodyne, autocorrelation/Mesa, Burg, Kalman or a concentrated-taper periodogram, and the spectral engines feed a genuine signal-versus-noise reading. The frequency transforms are generalised — you choose the cycle range, how many cycles to keep, and how far to project — and are implemented to update efficiently as each bar arrives instead of re-fitting the whole history.
So when this page says "treat price as a signal," that idea is shared across all of them — but the specific tool you reach for may be Ehlers', Meyers', or a toolbox extension of either.
Price as a signal
An engineer looking at a noisy signal assumes it is two things added together: a signal they care about, and noise they want to remove. A price chart is the same. Underneath the tick-by-tick randomness there is usually some slower movement — a trend, or a swing that repeats every so many bars. DSP gives you filters that try to keep that slower movement and throw away the jitter, without the heavy lag you get from simply using a long moving average.
One practical consequence shows up again and again on these pages: what you feed
in matters. Most of these tools work best on a smooth, symmetric price like the
bar's midpoint, (High + Low) / 2, rather than the close, which sits at
whatever the last print happened to be. Several functions even read the High and Low
directly for that reason. And because a strong trend can swamp the small cyclic swings
you are trying to measure, some tools detrend the data first (the frequency transforms
take the log of price and remove a straight line before they start). When you want to
compare two series on a like-for-like basis, PercentDifference
is a simple way to put price changes on a common, percentage footing.
Cycles and the dominant cycle
A cycle is just a swing that repeats: price runs up for a while, rolls over, runs down, and turns back up, taking roughly the same number of bars to do it each time. That number of bars is the cycle's period (sometimes called its length). A 20-bar cycle peaks about every 20 bars.
Real markets rarely have one clean cycle. They have several layered on top of each other, plus the trend, plus noise — and they drift, speeding up and slowing down over time. The dominant cycle is the single period that is currently the strongest. It is the most useful one to know, because it lets you set indicator lengths automatically instead of guessing a fixed number. Feed the measured period (or half of it) into an adaptive RSI, stochastic or moving average and the indicator stretches out in slow markets and tightens up in fast ones. That is the single biggest pay-off of the whole section, and it is why the adaptive VariablePeriod indicators exist alongside these measurements.
A dominant-cycle reading is itself an estimate, and a noisy one. It wanders, it lags a little, and in a strong trend there may be no real cycle at all. Treat it as useful context — a sensible length to adapt to — not as a precise clock for timing turns to the bar.
The spectrum, and choosing an engine
If a cycle is a swing of one length, a spectrum is the full picture: a read-out of how much energy sits at every cycle length at once. Think of it like an audio equaliser display, but the bars are cycle lengths instead of bass and treble. A tall bar at "20 bars" means there is a strong 20-bar swing in the data right now. The dominant cycle is simply the tallest bar.
There is more than one way to estimate that spectrum, and they have different
personalities — some react faster, some are smoother, some are better at telling two
nearby cycles apart. Rather than ship a separate indicator for each method, the toolbox
lets the cycle indicators take an optional Engine argument that picks the
estimator: Homodyne (the low-lag default), the Ehlers alpha cycle, autocorrelation
("Mesa"), Burg maximum-entropy, a Kalman tracker, or a concentrated-taper periodogram.
You write the formula once and audition the engines by changing a single number. The
Cycle Engines page explains each one and when to reach
for it.
Signal-to-noise: is there even a cycle?
A cycle measurement is only worth acting on when there is a real cycle to measure. The signal-to-noise ratio (SNR) puts a number on that. It compares the strength of the detected cycle against the background noise and reports the result in decibels — the same unit audio engineers use. A high SNR means a clean, tradeable rhythm; a low SNR means the market is mostly noise and you should treat cycle signals with caution (or stand aside). Used as a simple gate — "only take cycle signals when SNR is healthy" — it is one of the more honest filters in the toolbox.
Be honest about what this can and can't do
These tools are powerful, but they are not magic, and using them well means being clear about their limits:
- The latest values can change. The cycle estimators and the frequency transforms (EndPointFFT, Goertzel) recompute as each new bar arrives, so the most recent readings can shift slightly after the fact — they "repaint". A turning point that looks perfect in the middle of the chart was not necessarily that clean when it was the last bar. Always judge a method on how it behaved at the hard right edge, not in hindsight.
- There is always some lag. Every filter that removes noise also delays the result a little. DSP buys you less lag for a given amount of smoothing than a plain moving average, but it never gets to zero. Be suspicious of any tool that claims otherwise.
- Don't curve-fit the cycle. It is tempting to hunt for the exact period or threshold that makes last year's backtest look perfect. That is overfitting, and it rarely survives contact with new data. Prefer settings that work reasonably across many markets and periods over ones that are razor-tuned to one.
- Cycles come and go. A rhythm that has been reliable for weeks can simply stop. The signal-to-noise tools and the Sine Wave's "lines run parallel" behaviour are there precisely to tell you when the cycle has faded and a different approach (a trend tool) is the better bet.
The tools, grouped by job
Here is the whole section laid out by what each tool is for. Start with whichever row matches the question you are trying to answer.
Measuring and tracking the cycle
- DominantCycle — the main cycle-length measurement, with the selectable engine. Your first stop for driving adaptive indicators.
- HilbertPeriod — an alternative dominant-cycle reading; a touch smoother and slower than the Homodyne default.
- CyberCycle — extracts the cyclic component of price as an oscillator that swings around zero.
- MAMA — an adaptive moving average (MAMA and its companion FAMA) whose speed is driven by the measured cycle.
Choosing the spectral engine
- Cycle Engines — the one place that explains the engine selector shared by DominantCycle, SineWave, InstantTrendline, HilbertOscillator and EnhancedSignalNoiseRatio: Homodyne, Ehlers alpha, Mesa, Burg, Kalman and Multitaper, and when to use each.
Cycle oscillators and lines
- SineWave — plots where price sits within its cycle; the lead/main crossing flags turns, and parallel lines flag a trend.
- SineWaveDC — the dominant-cycle variant of the Sine Wave, reached through SineWave's engine argument.
- HilbertOscillator — a low-lag, cycle-matched oscillator (lead and lag lines) for timing turns.
- InstantTrendline — a responsive trend line that averages over exactly one dominant cycle to cancel the swing.
Frequency transforms
- EndPointFFT — a non-repainting FFT that keeps every surviving frequency and locks in the endpoint each bar.
- Goertzel — scans a range of cycle lengths, keeps the strongest few, and rebuilds a smooth, optionally projected signal.
Projection and smoothing
- PolynomialInterpolation — fits a smooth low-lag curve through recent data; useful for de-noising or estimating slope and curvature.
Signal quality
- SignalNoiseRatio — the classic, lightweight cycle-versus-noise gauge in decibels.
- EnhancedSignalNoiseRatio — a sharper, spectrum-based SNR that reads a real signal and noise floor from the Mesa, Burg, Kalman or Multitaper engines.
Putting it together
A common pattern uses three of these tools at once: measure the cycle, only act when the cycle is strong, and adapt an ordinary indicator to its length.
price = ( High + Low ) / 2; // a smooth, symmetric input
periods = DominantCycle( price ); // how long is the current swing?
snr = SignalNoiseRatio(); // is there really a cycle to trade?
adaptiveRSI = VariablePeriodRSI( Close, periods ); // RSI that adapts to it
Plot( adaptiveRSI, "Adaptive RSI", colorRed );
// Only trust the oscillator's extremes when the cycle is clean enough.
cycleIsClean = snr > 6;
Buy = cycleIsClean AND Cross( adaptiveRSI, 30 );
Sell = cycleIsClean AND Cross( 70, adaptiveRSI );
If you are new to this, start with DominantCycle and one adaptive indicator, leave the engine on its default, and add SignalNoiseRatio as a filter before you reach for anything fancier. The spectral engines and frequency transforms are worth exploring, but they are not where you need to begin.