Files
QuanTAlib/lib/cycles/eacp/eacp.md
T
86fe32a682 SIMD Refactor: Merge simd-dev into dev (#55)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: aider (openrouter/anthropic/claude-sonnet-4) <aider@aider.chat>
Co-authored-by: Warp <agent@warp.dev>
2026-01-18 19:02:03 -08:00

9.3 KiB
Raw Blame History

EACP: Ehlers Autocorrelation Periodogram

Overview and Purpose

Developed by John F. Ehlers (Technical Analysis of Stocks & Commodities, Sep 2016), the Ehlers Autocorrelation Periodogram (EACP) estimates the dominant market cycle by projecting normalized autocorrelation coefficients onto Fourier basis functions. The indicator blends a roofing filter (high-pass + Super Smoother) with a compact periodogram, yielding low-latency dominant cycle detection suitable for adaptive trading systems. Compared with Hilbert-based methods, the autocorrelation approach resists aliasing and maintains stability in noisy price data.

EACP answers a central question in cycle analysis: “What period currently dominates the market?” It prioritizes spectral power concentration, enabling downstream tools (adaptive moving averages, oscillators) to adjust responsively without the lag present in sliding-window techniques.

Core Concepts

  • Roofing Filter: High-pass plus Super Smoother combination removes low-frequency drift while limiting aliasing.
  • Pearson Autocorrelation: Computes normalized lag correlation to remove amplitude bias.
  • Fourier Projection: Sums cosine and sine terms of autocorrelation to approximate spectral energy.
  • Gain Normalization: Automatic gain control prevents stale peaks from dominating power estimates.
  • Warmup Compensation: Exponential correction guarantees valid output from the very first bar.

Implementation Notes

This is not a strict implementation of the TASC September 2016 specification. It is a more advanced evolution combining the core 2016 concept with techniques Ehlers introduced later. The fundamental Wiener-Khinchin theorem (power spectral density = Fourier transform of autocorrelation) is correctly implemented, but key implementation details differ:

Differences from Original 2016 TASC Article

  1. Dominant Cycle Calculation:

    • 2016 TASC: Uses peak-finding to identify the period with maximum power
    • This Implementation: Uses Center of Gravity (COG) weighted average over bins where power ≥ 0.5
    • Rationale: COG provides smoother transitions and reduces susceptibility to noise spikes
  2. Roofing Filter:

    • 2016 TASC: Simple first-order high-pass filter
    • This Implementation: Canonical 2-pole high-pass with √2 factor followed by Super Smoother bandpass
    • Formula: hp := (1-α/2)²·(p-2p[1]+p[2]) + 2(1-α)·hp[1] - (1-α)²·hp[2]
    • Rationale: Evolved filtering provides better attenuation and phase characteristics
  3. Normalized Power Reporting:

    • 2016 TASC: Reports peak power across all periods
    • This Implementation: Reports power specifically at the dominant period
    • Rationale: Provides more meaningful correlation between dominant cycle strength and normalized power
  4. Automatic Gain Control (AGC):

    • Uses decay factor K = 10^(-0.15/diff) where diff = maxPeriod - minPeriod
    • Ensures K < 1 for proper exponential decay of historical peaks
    • Prevents stale peaks from dominating current power estimates

Performance Characteristics

  • Complexity: O(N²) where N = (maxPeriod - minPeriod)
  • Implementation: Uses var arrays with native PineScript historical operator [offset]
  • Warmup: Exponential compensation (§2 pattern) ensures valid output from bar 1

This refined approach aligns with:

  • TradingView TASC 2025.02 implementation by blackcat1402
  • Modern Ehlers cycle analysis techniques post-2016
  • Evolved filtering methods from Cycle Analytics for Traders

The code is mathematically sound and production-ready, representing a refined version of the autocorrelation periodogram concept rather than a literal translation of the 2016 article.

Common Settings and Parameters

Parameter Default Function When to Adjust
Min Period 8 Lower bound of candidate cycles Increase to ignore microstructure noise; decrease for scalping.
Max Period 48 Upper bound of candidate cycles Increase for swing analysis; decrease for intraday focus.
Autocorrelation Length 3 Averaging window for Pearson correlation Set to 0 to match lag, or enlarge for smoother spectra.
Enhance Resolution true Cubic emphasis to highlight peaks Disable when a flatter spectrum is desired for diagnostics.

Pro Tip: Keep (maxPeriod - minPeriod) ≤ 64 to control O(n^2) inner loops and maintain responsiveness on lower timeframes.

Calculation and Mathematical Foundation

Explanation:

  1. Apply roofing filter to source using coefficients \alpha_1, a_1, b_1, c_1, c_2, c_3.
  2. For each lag L compute Pearson correlation r_L over window M (default L).
  3. For each period p, project onto Fourier basis: C_p=\sum_{n=2}^{N} r_n \cos\left(\frac{2\pi n}{p}\right) and S_p=\sum_{n=2}^{N} r_n \sin\left(\frac{2\pi n}{p}\right).
  4. Power P_p=C_p^2+S_p^2, smoothed then normalized via adaptive peak tracking.
  5. Dominant cycle D=\frac{\sum p\,\tilde P_p}{\sum \tilde P_p} over bins where \tilde P_p≥0.5, warmup-compensated.

Technical formula:

Step 1: hp_t = ((1-α₁)/2)(src_t - src_{t-1}) + α₁ hp_{t-1}
Step 2: filt_t = c₁(hp_t + hp_{t-1})/2 + c₂ filt_{t-1} + c₃ filt_{t-2}
Step 3: r_L = (M Σxy - Σx Σy) / √[(M Σx² - (Σx)²)(M Σy² - (Σy)²)]
Step 4: P_p = (Σ_{n=2}^{N} r_n cos(2πn/p))² + (Σ_{n=2}^{N} r_n sin(2πn/p))²
Step 5: D = Σ_{p∈Ω} p · ĤP_p / Σ_{p∈Ω} ĤP_p with warmup compensation

🔍 Technical Note: Warmup uses c = 1 / (1 - (1 - \alpha)^{k}) to scale early-cycle estimates, preventing low values during initial bars.

Interpretation Details

  • Primary Dominant Cycle:

    • High D (e.g., > 30) implies slow regime; adaptive MAs should lengthen.
    • Low D (e.g., < 15) signals rapid oscillations; shorten lookback windows.
  • Normalized Power:

    • Values > 0.8 indicate strong cycle confidence; consider cyclical strategies.
    • Values < 0.3 warn of flat spectra; favor trend or volatility approaches.
  • Regime Shifts:

    • Rapid drop in D alongside rising power often precedes volatility expansion.
    • Divergence between D and price swings may highlight upcoming breakouts.

Limitations and Considerations

  • Spectral Leakage: Limited lag range can smear peaks during abrupt volatility shifts.
  • O(n²) Segment: Although constrained (≤ 60 loops), wide period spans increase computation.
  • Stationarity Assumption: Autocorrelation presumes quasi-stationary cycles; regime changes reduce accuracy.
  • Latency in Noise: Even with roofing, extremely noisy assets may require higher avgLength.
  • Downtrend Bias: Negative trends may clip high-pass output; ensure preprocessing retains signal.

Performance Profile

Operation Count (Streaming Mode, per Bar)

Operation Count Cost (cycles) Subtotal
ADD/SUB ~N² 1 ~N²
MUL ~N² 3 ~3N²
DIV ~N 15 ~15N
SQRT ~N 15 ~15N
COS 40 40N²
SIN 40 40N²
Total ~4N² ~84N² cycles

Where N = maxPeriod - minPeriod (default 40)

Default (N=40): ~134,400 cycles per bar (dominated by trig functions)

Breakdown:

  • Roofing filter (HP + SSF): ~20 cycles
  • Autocorrelation (N lags): ~4N² for Pearson calculations
  • Fourier projection (N² iterations): 80N² cycles (COS + SIN)
  • Power + normalization: ~30N cycles

Complexity Analysis

Mode Complexity Notes
Streaming O(N²) Nested loops over lags × periods
Batch O(m×N²) m = bars, N = period range

Memory: ~3N×8 bytes (autocorrelation + power arrays)

SIMD Analysis

Optimization Applicable Notes
AVX2 vectorization Partial Fourier sums vectorizable across lags
FMA Accumulation: r × cos + sum pattern
Batch parallelism Limited Each bar depends on filtered history

Optimization Notes: Trig functions dominate cost. Consider:

  • Precomputed trig tables for fixed period range
  • SVML vectorized sin/cos for ~4× speedup
  • Reduce N by narrowing period search range

Quality Metrics

Metric Score Notes
Accuracy 9/10 Wiener-Khinchin theorem mathematically sound
Timeliness 6/10 Spectral analysis inherently lagging
Overshoot 8/10 COG averaging smooths cycle estimates
Smoothness 7/10 Enhanced resolution can create jumps

References

  • Ehlers, J. F. (2016). “Past Market Cycles.” Technical Analysis of Stocks & Commodities, 34(9), 52-55.
  • Thinkorswim Learning Center. “Ehlers Autocorrelation Periodogram.”
  • Fab MacCallini. “autocorrPeriodogram.R.” GitHub repository.
  • QuantStrat TradeR Blog. “Autocorrelation Periodogram for Adaptive Lookbacks.”
  • TradingView Script by blackcat1402. “Ehlers Autocorrelation Periodogram (Updated).”
Validation Sources:
Patterns: §2, §3, §7, §21
Wolfram: "Wiener-Khinchin theorem"
External: "Thinkorswim Ehlers Autocorrelation Periodogram","fabmaccallini autocorrPeriodogram","QuantStrat Autocorrelation Periodogram","TradingView blackcat Autocorrelation Periodogram"
API: ref-tools confirmed input.source/int/bool usage, plot defaults
Planning: phases=design,warmup,validation,docs