- The Trendflex indicator combines a 2-pole Butterworth low-pass pre-filter (Super Smoother) with an O(1) cumulative slope measurement and exponentia...
The Trendflex indicator combines a 2-pole Butterworth low-pass pre-filter (Super Smoother) with an O(1) cumulative slope measurement and exponential RMS normalization to produce a zero-centered oscillator that quantifies trend strength. Unlike conventional slope or momentum indicators that suffer from noise amplification or lag, Trendflex pre-smooths via the Super Smoother, computes the least-squares slope of the filtered signal over a lookback window in constant time, then normalizes by a running RMS estimate. The result: a bounded oscillator where values above zero indicate uptrend, below zero indicate downtrend, and magnitude reflects trend conviction.
## Historical Context
John F. Ehlers introduced the Trendflex indicator in his 2013 work on cycle and trend measurement for traders. The indicator addresses a fundamental problem: how do you separate trend from cycle without introducing excessive lag or noise? Ehlers' insight was to cascade two well-understood DSP components: a Super Smoother (2-pole Butterworth) that removes high-frequency noise without the phase distortion of moving averages, followed by a slope estimator that measures the linear regression slope of the filtered signal.
The original Pine Script implementation uses an O(N) summation loop per bar. QuanTAlib's implementation replaces this with a RingBuffer-based running sum, reducing the per-bar cost to O(1) while producing bit-identical results. This is a pure algorithmic optimization with no mathematical approximation.
No other major library (TA-Lib, Skender, Tulip, Ooples) implements Trendflex. QuanTAlib's implementation serves as a reference.
## Architecture and Physics
### 1. Super Smoother Pre-Filter (2-Pole Butterworth)
The Super Smoother acts as a low-pass filter with cutoff at the half-period:
The summation $\sum \text{Filt}_{n-i}$ is maintained as a running sum in a circular buffer (RingBuffer). Each bar adds the new filtered value and removes the oldest, keeping the operation O(1) regardless of period length.
### 3. Exponential RMS Normalization
To produce a unit-scale oscillator, the slope is divided by its own running RMS:
The 0.04/0.96 exponential weighting corresponds to approximately a 25-bar half-life for the mean-square estimate, providing smooth normalization without requiring a lookback buffer.
The RMS normalization is a nonlinear operation with no closed-form transfer function, but its exponential smoothing has characteristic time constant $\tau = 1/0.04 = 25$ bars.
### FMA Usage
Both the Super Smoother and RMS normalization use `Math.FusedMultiplyAdd` for the `a*b + c` patterns:
| **Total hot path** | **~9 ops** | O(1) per bar |
### Batch Mode
The batch path uses `CalculateCore` which inlines the same logic without RingBuffer snapshot/restore overhead. Since the SSF is inherently serial (IIR dependency), SIMD parallelization is not applicable. The FMA chain provides excellent instruction-level pipelining.
Self-consistency validation: Streaming, Batch (TSeries), and Span Batch modes produce identical results to machine precision ($< 10^{-10}$).
## Common Pitfalls
1.**Not an overlay.** Trendflex is an oscillator centered around zero. Plot in a separate window, not overlaid on price.
2.**Period interpretation.** The `period` parameter controls both the SSF cutoff (via half-period) and the slope lookback window. Larger periods produce smoother output but increase lag. Typical range: 10-40.
3.**RMS normalization startup.** The exponential mean-square estimate needs approximately 25 bars (1/0.04) to stabilize. During warmup, the normalization may produce values with higher variance. `IsHot` fires at `count >= period`.
4.**Constant input produces zero.** By design, constant input produces zero slope and zero output. This is correct behavior, not a bug.
5.**Sensitivity to period < 3.** Very small periods cause the SSF coefficients to become extreme, potentially producing oscillatory artifacts. Use period >= 3 for stable results.
6.**Bar correction cost.** The RingBuffer snapshot/restore mechanism for `isNew=false` is O(period) due to the buffer copy. For very large periods (>1000), this may be noticeable in tight correction loops.
7.**Not bounded to [-1, 1].** Despite RMS normalization, Trendflex output is not strictly bounded. Strong trend initiations can produce values > 1 or < -1 before the RMS estimate catches up. Treat as a relative measure, not a percentage.
## References
- Ehlers, J. F. (2013). "Trendflex and Reflex." *Cycle Analytics for Traders*. Wiley.
- Ehlers, J. F. (2004). *Cybernetic Analysis for Stocks and Futures*. Wiley.