Files
QuanTAlib/lib/cycles/eacp/eacp.md
T
Miha Kralj 90d5638008 Add new moving average implementations: LTMA, MCNMA, NLMA, NMA, NYQMA, RAIN, and TRAMA
- LTMA (Linear Trend Moving Average): Introduces a predictive moving average using dual cascaded EMAs for trend estimation.
- MCNMA (McNicholl EMA): Implements a zero-lag TEMA using a cascaded EMA structure for enhanced responsiveness.
- NLMA (Non-Lag Moving Average): Utilizes a damped cosine kernel to achieve reduced lag in moving averages.
- NMA (Natural Moving Average): Adapts smoothing based on volatility profiles using a square-root kernel.
- NYQMA (Nyquist Moving Average): Applies the Nyquist-Shannon theorem to prevent aliasing in cascaded moving averages.
- RAIN (Rainbow Moving Average): Combines multiple SMA layers with weighted averages for multi-scale smoothing.
- TRAMA (Trend Regularity Adaptive Moving Average): Adapts smoothing based on the frequency of new highs and lows in price data.
2026-02-20 21:40:32 -08:00

5.2 KiB

EACP: Ehlers Autocorrelation Periodogram

EACP estimates the dominant cycle period of a financial time series by computing autocorrelation across multiple lags and transforming the result into a power spectrum via the Wiener-Khinchin theorem. The output is a continuously updating cycle period measurement (in bars) that can adaptively tune other indicators to the market's current rhythm, making fixed-period assumptions unnecessary.

Historical Context

John Ehlers introduced the Autocorrelation Periodogram to solve the fundamental problem of cycle measurement in noisy financial data. Traditional spectral methods (FFT) assume stationarity and require long data windows, making them impractical for real-time trading. Ehlers leveraged the Wiener-Khinchin theorem, which establishes that a signal's autocorrelation function and its power spectral density form a Fourier transform pair. By computing autocorrelation in the time domain and transforming to frequency via a discrete cosine transform, the algorithm identifies spectral peaks corresponding to dominant periodicities. The center-of-gravity weighting of spectral peaks provides a robust, noise-tolerant period estimate. This enables truly adaptive trading systems where RSI, Stochastic, or moving average periods track the market's actual cycle length rather than relying on fixed parameters.

Architecture & Physics

1. Signal Pre-processing

A high-pass filter removes the DC (trend) component, and a Super-Smoother filter attenuates aliasing noise above the Nyquist frequency:

HP_t = (1 - \alpha_{HP}/2)^2 (P_t - 2P_{t-1} + P_{t-2}) + 2(1 - \alpha_{HP}) HP_{t-1} - (1 - \alpha_{HP})^2 HP_{t-2}

The Super-Smoother then applies a 2-pole Butterworth low-pass to HP_t.

2. Autocorrelation

For each lag k from 0 to MaxPeriod, the normalized Pearson autocorrelation is computed over an averaging window of M samples:

R_k = \frac{\sum_{i=0}^{M-1} (x_i - \bar{x})(x_{i-k} - \bar{x})}{\sqrt{\sum (x_i - \bar{x})^2 \sum (x_{i-k} - \bar{x})^2}}

A high R_k at lag 20 implies a 20-bar cycle is present.

3. Power Spectrum (DFT of Autocorrelation)

For each candidate period p in [MinPeriod, MaxPeriod]:

P_p = \left(\sum_{k=0}^{M-1} R_k \cos\!\left(\frac{2\pi k}{p}\right)\right)^2

Smoothed with exponential decay: S_p = 0.2 \cdot P_p + 0.8 \cdot S_{p,prev}

4. Dominant Cycle Extraction

Center-of-gravity weighting across spectral peaks:

DC = \frac{\sum S_p \cdot p}{\sum S_p}

5. Optional Enhancement

When enhance=true, spectral values are cubed before CG weighting, sharpening peaks but increasing sensitivity to noise.

6. Complexity

O(N \times M) per bar where N is the period range and M is the averaging length. This is one of the most computationally expensive indicators due to nested correlation and DFT loops. Memory is O(N) for correlation and power arrays.

Mathematical Foundation

Parameters

Parameter Description Default Constraint
minPeriod Minimum period to evaluate 8 \geq 3
maxPeriod Maximum period to evaluate 48 > minPeriod
enhance Apply cubic emphasis to spectral peaks true

Pseudo-code

function EACP(source, minPeriod, maxPeriod, enhance):
    N ← maxPeriod - minPeriod + 1
    M ← maxPeriod        // averaging window
    hpBuf ← HighPassFilter(source)
    ssfBuf ← SuperSmoother(hpBuf)

    power[N] ← {0}
    smoothPower[N] ← {0}

    for each bar:
        // Autocorrelation for each lag
        corr[0..maxPeriod] ← PearsonAutocorrelation(ssfBuf, M)

        // DFT: convert autocorrelation to power spectrum
        for p = minPeriod to maxPeriod:
            cosPower ← 0
            for k = 0 to M-1:
                cosPower += corr[k] * cos(2π * k / p)
            power[p] ← cosPower²

        // Exponential smoothing of spectrum
        for p = minPeriod to maxPeriod:
            smoothPower[p] ← 0.2 * power[p] + 0.8 * smoothPower[p]

        // Optional cubic enhancement
        if enhance:
            for p: smoothPower[p] ← smoothPower[p]³

        // AGC normalization
        maxPow ← max(smoothPower)
        for p: smoothPower[p] /= maxPow   // normalize to [0, 1]

        // Center-of-gravity dominant cycle
        num ← 0; den ← 0
        for p = minPeriod to maxPeriod:
            num += smoothPower[p] * p
            den += smoothPower[p]
        dominantCycle ← (den > 0) ? num / den : (minPeriod + maxPeriod) / 2

        emit dominantCycle

Output Interpretation

Output Meaning
dominantCycle Estimated dominant period in bars (use to tune other indicators)
Stable value Market exhibiting regular cyclical behavior
Rapidly changing value Market transitioning between regimes
Pegged at maxPeriod No clear cycle detected; likely trending

Resources

  • Ehlers, J.F. Cycle Analytics for Traders. Wiley, 2013.
  • Ehlers, J.F. Cybernetic Analysis for Stocks and Futures. Wiley, 2004.
  • Wiener, N. "Generalized Harmonic Analysis." Acta Mathematica, 55(1), 1930.
  • Khinchin, A. "Korrelationstheorie der stationären stochastischen Prozesse." Mathematische Annalen, 109(1), 1934.