fix(docs): correct .md documentation across errors, dynamics, filters, forecasts, momentum, numerics, oscillators, reversals, statistics, trends, volatility, volume

Deep review of all indicator categories verified .md headers against .cs WarmupPeriod, parameters, inputs, and outputs. Fixes include warmup corrections, parameter documentation, output type accuracy, and Pine Script alignment.
This commit is contained in:
Miha Kralj
2026-03-10 18:38:23 -07:00
parent 8906c62dcf
commit 35a6702b06
178 changed files with 2579 additions and 998 deletions
+12 -13
View File
@@ -6,15 +6,15 @@
| **Inputs** | Source (close) |
| **Parameters** | `decay` (default 0.991) |
| **Outputs** | Single series (AGC) |
| **Output range** | Tracks input |
| **Output range** | [-1, +1] (normalized) |
| **Warmup** | `1` bars |
### TL;DR
- The Automatic Gain Control normalizes any oscillating signal to the \[-1, +1\] range through exponential peak tracking.
- Parameterized by `decay` (default 0.991).
- Output range: Tracks input.
- Requires `1` bars of warmup before first valid output (IsHot = true).
- Output range: [-1, +1] (normalized amplitude).
- Requires `1` bar of warmup before first valid output (IsHot = true).
- Validated against TA-Lib, Skender, and Tulip reference implementations where available.
> "The purpose of the AGC is to normalize the amplitude of any indicator to unity." — John F. Ehlers, TASC January 2015
@@ -86,26 +86,25 @@ Peak initializes to $10^{-10}$ (tiny positive) to avoid division by zero on the
### Operation Count (Streaming Mode)
AGC (Adaptive Gain Control) applies a slow EMA to estimate signal level, then scales the signal by the inverse of that level. O(1) per bar.
AGC uses exponential peak decay with a ratchet-up mechanism, then divides the signal by the tracked peak. O(1) per bar.
| Operation | Count | Cost (cycles) | Subtotal |
| :--- | :---: | :---: | :---: |
| Level EMA (FMA) | 1 | ~4 cy | ~4 cy |
| Gain = 1 / level (division) | 1 | ~10 cy | ~10 cy |
| Output multiply | 1 | ~3 cy | ~3 cy |
| **Total** | **3** | — | **~17 cycles** |
| Peak decay (multiply) | 1 | ~3 cy | ~3 cy |
| Abs + compare (ratchet) | 1 | ~2 cy | ~2 cy |
| Normalize (division) | 1 | ~10 cy | ~10 cy |
| **Total** | **3** | — | **~15 cycles** |
O(1) per bar. The division dominates; precomputing gain incrementally saves it but adds state. ~17 cycles/bar.
O(1) per bar. The division dominates. ~15 cycles/bar.
### Batch Mode (SIMD Analysis)
| Operation | Vectorizable? | Notes |
| :--- | :---: | :--- |
| Level EMA recursion | No | Sequential IIR dependency |
| Gain division | No | Depends on current EMA |
| Output multiply | N/A | Single scalar multiply |
| Peak decay + ratchet | No | Data-dependent branching (max of decay vs abs) |
| Normalize (division) | No | Depends on current peak |
Fully recursive. Batch throughput: ~17 cy/bar.
Fully sequential due to data-dependent peak tracking. Batch throughput: ~15 cy/bar.
| Metric | Value |
|---|---|
+13 -9
View File
@@ -7,7 +7,7 @@
| **Parameters** | `length` (default 20), `medianLength` (default 5) |
| **Outputs** | Single series (ALaguerre) |
| **Output range** | Tracks input |
| **Warmup** | 1 bar |
| **Warmup** | `max(4, length)` bars |
| **Signature** | [alaguerre_signature](alaguerre_signature.md) |
### TL;DR
@@ -15,7 +15,7 @@
- The Adaptive Laguerre Filter extends Ehlers' four-element all-pass cascade by replacing the fixed damping factor with a per-bar adaptive alpha deri...
- Parameterized by `length` (default 20), `medianlength` (default 5).
- Output range: Tracks input.
- Requires 1 bar of warmup before first valid output (IsHot = true).
- Requires `max(4, length)` bars of warmup before first valid output (IsHot = true).
- Validated against TA-Lib, Skender, and Tulip reference implementations where available.
> "The best filter is one that knows when to listen closely and when to smooth aggressively." -- John F. Ehlers (paraphrased)
@@ -111,24 +111,28 @@ The filter requires $\max(4, N)$ bars before producing reliable output. The firs
### Operation Count (Streaming Mode)
Laguerre filter uses 4 cascaded Laguerre stages L0..L3, each an O(1) gamma-parameterized FMA, plus a final weighted combination.
Adaptive Laguerre combines HH/LL tracking error normalization (O(N) scan), median smoothing (O(M log M) sort), and 4-stage Laguerre cascade (O(1)).
| Operation | Count | Cost (cycles) | Subtotal |
| :--- | :---: | :---: | :---: |
| Tracking error computation | 1 | ~3 cy | ~3 cy |
| HH/LL scan over N-element buffer | N | ~2 cy | ~40 cy (N=20) |
| Median via insertion sort (M elements) | M log M | ~3 cy | ~25 cy (M=5) |
| Laguerre state update x4 (each: 2 FMA) | 8 | ~4 cy | ~32 cy |
| Weighted output combination (3 adds) | 3 | ~2 cy | ~6 cy |
| **Total** | **11** | — | **~38 cycles** |
| Weighted output combination | 3 | ~2 cy | ~6 cy |
| **Total** | | — | **~106 cycles** (N=20, M=5) |
O(1) per bar. Four recursive stages with precomputed gamma constant. ~38 cycles/bar.
O(N + M log M) per bar due to HH/LL scan and median sort. Dominated by the lookback scan for large N.
### Batch Mode (SIMD Analysis)
| Operation | Vectorizable? | Notes |
| :--- | :---: | :--- |
| Laguerre stage recursion | No | Each stage `L[k][n]` depends on `L[k-1][n]` and `L[k][n-1]` |
| Weighted combination | No | Only 4 terms; SIMD overhead not worthwhile |
| HH/LL scan | Partial | Min/max over contiguous buffer amenable to `Vector<double>` |
| Median sort | No | Comparison-based sort, data-dependent |
| Laguerre cascade | No | Each stage depends on previous stage and previous bar |
Cascaded IIR stages cannot be vectorized. Batch throughput: ~38 cy/bar.
Adaptive overhead limits SIMD gains. Batch throughput: ~106 cy/bar (N=20, M=5).
| Metric | Value | Notes |
|--------|-------|-------|
+4 -4
View File
@@ -6,16 +6,16 @@
| **Inputs** | Source (close) |
| **Parameters** | `pLow` (default 6), `pHigh` (default 32), `k` (default 12) |
| **Outputs** | Single series (BaxterKing) |
| **Output range** | Tracks input |
| **Warmup** | 1 bar |
| **Output range** | Oscillates around zero |
| **Warmup** | `2K+1` bars (default 25) |
| **Signature** | [baxterking_signature](baxterking_signature.md) |
### TL;DR
- The **Baxter-King Band-Pass Filter** is a symmetric finite impulse response (FIR) filter that approximates the ideal spectral band-pass by truncati...
- Parameterized by `plow` (default 6), `phigh` (default 32), `k` (default 12).
- Output range: Tracks input.
- Requires 1 bar of warmup before first valid output (IsHot = true).
- Output range: Oscillates around zero (extracts cyclical component).
- Requires `2K+1` bars of warmup before first valid output (IsHot = true).
- Validated against TA-Lib, Skender, and Tulip reference implementations where available.
> "The business cycle is whatever remains after you strip away the trend and the noise. Baxter and King figured out the stripping."
+2 -2
View File
@@ -7,7 +7,7 @@
| **Parameters** | `length` |
| **Outputs** | Single series (Bessel) |
| **Output range** | Tracks input |
| **Warmup** | 1 bar |
| **Warmup** | `length` bars |
| **Signature** | [bessel_signature](bessel_signature.md) |
### TL;DR
@@ -15,7 +15,7 @@
- The Bessel Filter is a 2nd-order low-pass IIR filter designed to preserve the **shape** and **timing** of price moves.
- Parameterized by `length`.
- Output range: Tracks input.
- Requires 1 bar of warmup before first valid output (IsHot = true).
- Requires `length` bars of warmup before first valid output (IsHot = true).
- Validated against TA-Lib, Skender, and Tulip reference implementations where available.
> When you care more about *when* the market turns than how aggressively you can torture the noise, you reach for a Bessel.
+2 -2
View File
@@ -6,7 +6,7 @@
| **Inputs** | Source (close) |
| **Parameters** | `lowerPeriod`, `upperPeriod` |
| **Outputs** | Single series (BPF) |
| **Output range** | Tracks input |
| **Output range** | Oscillates around zero |
| **Warmup** | `Math.Max(lowerPeriod, upperPeriod)` bars |
| **Signature** | [bpf_signature](bpf_signature.md) |
@@ -14,7 +14,7 @@
- The **BPF** (BandPass Filter) is a second-order IIR architecture designed to surgically excise specific frequency components from a time series.
- Parameterized by `lowerperiod`, `upperperiod`.
- Output range: Tracks input.
- Output range: Oscillates around zero (bandpass extracts cyclic component).
- Requires `Math.Max(lowerPeriod, upperPeriod)` bars of warmup before first valid output (IsHot = true).
- Validated against TA-Lib, Skender, and Tulip reference implementations where available.
+2 -2
View File
@@ -6,7 +6,7 @@
| **Inputs** | Source (close) |
| **Parameters** | `pLow` (default 6), `pHigh` (default 32) |
| **Outputs** | Single series (Cfitz) |
| **Output range** | Tracks input |
| **Output range** | Oscillates around zero |
| **Warmup** | `2` bars |
| **Signature** | [cfitz_signature](cfitz_signature.md) |
@@ -14,7 +14,7 @@
- The **Christiano-Fitzgerald Band-Pass Filter** is an asymmetric full-sample filter that approximates the ideal spectral band-pass by using time-var...
- Parameterized by `plow` (default 6), `phigh` (default 32).
- Output range: Tracks input.
- Output range: Oscillates around zero (extracts cyclical component).
- Requires `2` bars of warmup before first valid output (IsHot = true).
- Validated against TA-Lib, Skender, and Tulip reference implementations where available.
+2 -2
View File
@@ -7,7 +7,7 @@
| **Parameters** | `length` (default 15) |
| **Outputs** | Single series (Edcf) |
| **Output range** | Tracks input |
| **Warmup** | 1 bar |
| **Warmup** | `length` bars |
| **Signature** | [edcf_signature](edcf_signature.md) |
### TL;DR
@@ -15,7 +15,7 @@
- The **Ehlers Distance Coefficient Filter (EDCF)** is a nonlinear adaptive FIR filter created by John F.
- Parameterized by `length` (default 15).
- Output range: Tracks input.
- Requires 1 bar of warmup before first valid output (IsHot = true).
- Requires `length` bars of warmup before first valid output (IsHot = true).
- Validated against TA-Lib, Skender, and Tulip reference implementations where available.
## Overview
+1 -1
View File
@@ -14,7 +14,7 @@
- Gauss (Gaussian Filter) is a smoothing filter that applies a Gaussian kernel to time series data.
- Parameterized by `sigma` (default 1.0).
- Output range: Tracks input.
- Requires 1 bar of warmup before first valid output (IsHot = true).
- Requires `2⌈3σ⌉+1` bars of warmup before first valid output (IsHot = true). Default: **7 bars** (σ=1.0).
- Validated against TA-Lib, Skender, and Tulip reference implementations where available.
> "SMA smears data like cheap paint. Gaussian filtering respects the signal's soul."
+1 -1
View File
@@ -15,7 +15,7 @@
- Hann (Hann Filter) is a Finite Impulse Response (FIR) smoothing filter that applies a Hann window to time series data.
- Parameterized by `length`.
- Output range: Tracks input.
- Requires 1 bar of warmup before first valid output (IsHot = true).
- Requires `length` bars of warmup before first valid output (IsHot = true).
- Validated against TA-Lib, Skender, and Tulip reference implementations where available.
> "The Hanning window whispers where the Boxcar screams. Smoothness is not just an aesthetic; it's a mathematical necessity."
+1 -1
View File
@@ -14,7 +14,7 @@
- The Hodrick-Prescott (HP) filter is a widely used tool in macroeconomics for separating the cyclical component of a time series from raw data.
- Parameterized by `lambda` (default 1600.0).
- Output range: Tracks input.
- Requires 1 bar of warmup before first valid output (IsHot = true).
- Requires `⌈2√λ⌉` bars of warmup before first valid output (IsHot = true). Default: **~80 bars** (λ=1600).
- Validated against TA-Lib, Skender, and Tulip reference implementations where available.
> "Trends are not lines; they are curves that we simplify for our sanity, often at the cost of reality."
+2 -2
View File
@@ -14,8 +14,8 @@
- The 2-Pole Highpass Filter (HPF) is designed to separate high-frequency components (like cycles and noise) from the underlying trend.
- Parameterized by `length` (default 40).
- Output range: Tracks input.
- Requires 1 bar of warmup before first valid output (IsHot = true).
- Output range: Oscillates around zero (detrended signal).
- Requires `length` bars of warmup before first valid output (IsHot = true). Default: **40 bars**.
- Validated against TA-Lib, Skender, and Tulip reference implementations where available.
> "Noise is just signal you haven't figured out how to filter yet. Or maybe, it's the only signal that matters."
+2 -2
View File
@@ -7,7 +7,7 @@
| **Parameters** | `period` (default 12) |
| **Outputs** | Single series (Rmed) |
| **Output range** | Tracks input |
| **Warmup** | 1 bar |
| **Warmup** | 5 bars (MedianWindow) |
| **Signature** | [rmed_signature](rmed_signature.md) |
### TL;DR
@@ -15,7 +15,7 @@
- RMED applies exponential smoothing to a 5-bar running median, creating a nonlinear IIR filter that rejects impulsive spike noise while providing sm...
- Parameterized by `period` (default 12).
- Output range: Tracks input.
- Requires 1 bar of warmup before first valid output (IsHot = true).
- Requires **5 bars** of warmup (MedianWindow) before first valid output (IsHot = true).
- Validated against TA-Lib, Skender, and Tulip reference implementations where available.
> "John Ehlers combined two tools that rarely meet: the median (nonlinear, spike-resistant) and the EMA (smooth, recursive). The median kills the spikes, the EMA smooths the survivors. Together they produce a filter that is both resistant and smooth."
+4 -4
View File
@@ -6,15 +6,15 @@
| **Inputs** | Source (close) |
| **Parameters** | `hpLength` (default 48), `ssLength` (default 10) |
| **Outputs** | Single series (ROOFING) |
| **Output range** | Tracks input |
| **Warmup** | 1 bar |
| **Output range** | Oscillates around zero |
| **Warmup** | `hpLength` bars (default 48) |
### TL;DR
- The **Roofing Filter** is John Ehlers' bandpass architecture designed specifically for oscillator construction.
- Parameterized by `hplength` (default 48), `sslength` (default 10).
- Output range: Tracks input.
- Requires 1 bar of warmup before first valid output (IsHot = true).
- Output range: Oscillates around zero (bandpass behavior).
- Requires `hpLength` bars of warmup before first valid output (IsHot = true). Default: **48 bars**.
- Validated against TA-Lib, Skender, and Tulip reference implementations where available.
> "The trend is your friend until it overwhelms the signal. The noise is your enemy until you mistake it for alpha."
+4 -4
View File
@@ -6,15 +6,15 @@
| **Inputs** | Source (close) |
| **Parameters** | `shortPeriod` (default 40), `longPeriod` (default 60), `rmsPeriod` (default 50) |
| **Outputs** | Single series (SPBF) |
| **Output range** | Tracks input |
| **Warmup** | 1 bar |
| **Output range** | Oscillates around zero |
| **Warmup** | `max(longPeriod, rmsPeriod)` bars (default 60) |
### TL;DR
- The **Super Passband Filter** is John Ehlers' wide-band bandpass constructed by differencing two z-transformed EMAs with Ehlers-style smoothing ($\...
- Parameterized by `shortperiod` (default 40), `longperiod` (default 60), `rmsperiod` (default 50).
- Output range: Tracks input.
- Requires 1 bar of warmup before first valid output (IsHot = true).
- Output range: Oscillates around zero.
- Requires `max(longPeriod, rmsPeriod)` bars of warmup before first valid output (IsHot = true).
- Validated against TA-Lib, Skender, and Tulip reference implementations where available.
> "Two EMAs walk into a frequency domain. The difference between them is the only thing worth trading."
+1 -1
View File
@@ -26,7 +26,7 @@ ssf2(series float src, simple int length) =>
float ssrc = nz(src, src[1])
float src1 = nz(src[1], ssrc)
float src2 = nz(src[2], src1)
ssf_internal := c1 * ssrc + c2 * nz(ssf_internal[1], src1) + c3 * nz(ssf_internal[2], src2)
ssf_internal := c1 * (ssrc + src1) * 0.5 + c2 * nz(ssf_internal[1], src1) + c3 * nz(ssf_internal[2], src2)
ssf_internal
// ---------- Main loop ----------
+8 -9
View File
@@ -62,25 +62,24 @@ Where:
### Operation Count (Streaming Mode)
Universal Smooth Filter: adaptive-weight FIR that adjusts taps based on signal characteristics. O(N) per bar.
Ehlers Ultimate Smoother Filter (USF): 2-pole IIR low-pass filter with high-pass subtraction for zero-lag smoothing. Five FMA operations per bar.
| Operation | Count | Cost (cycles) | Subtotal |
| :--- | :---: | :---: | :---: |
| Adaptive weight derivation | N | ~8 cy | ~240 cy (N=30) |
| Weighted sum FMA | N | ~5 cy | ~150 cy |
| Normalization | 1 | ~3 cy | ~3 cy |
| **Total (N=30)** | **2N+1** | — | **~393 cycles** |
| Input combination (3 taps) | 3 | ~4 cy | ~12 cy |
| Feedback (2 taps) | 2 | ~4 cy | ~8 cy |
| State update | 4 | ~1 cy | ~4 cy |
| **Total** | **9** | — | **~24 cycles** |
O(N) per bar. Adaptive weights computed per bar (no precomputation) because they depend on current signal level. ~393 cycles for N=30.
O(1) per bar. Coefficients derived from period parameter; precomputed. ~24 cycles/bar.
### Batch Mode (SIMD Analysis)
| Operation | Vectorizable? | Notes |
| :--- | :---: | :--- |
| Adaptive weight computation | Partial | Independent per element; vectorizable if no data dependency |
| Weighted sum FMA | Yes | Standard dot product |
| USF recursion | No | y[n] depends on y[n-1] and y[n-2] |
SIMD potential: ~100 cy for N=30 if adaptive weights vectorized.
Batch throughput: ~24 cy/bar.
| Metric | Score | Notes |
| :--- | :--- | :--- |
+11 -10
View File
@@ -6,7 +6,7 @@
| **Inputs** | Source (close) |
| **Parameters** | `period` (default 20), `predict` (default 3), `bandwidth` (default 0.25) |
| **Outputs** | Single series (VOSS) |
| **Output range** | Tracks input |
| **Output range** | Oscillates around zero |
| **Warmup** | `period` bars |
| **Signature** | [voss_signature](voss_signature.md) |
@@ -86,25 +86,26 @@ The Voss predictor stage is an IIR filter with `Order` feedback taps, each weigh
### Operation Count (Streaming Mode)
Voss-McCartney 1/f noise filter: octave-cascade of N random sources, each updated probabilistically. O(N) per bar worst-case, O(1) amortized.
Ehlers Voss Predictive Filter: two-stage pipeline — 2-pole bandpass filter (Stage 1) + weighted feedback predictor (Stage 2). O(Order) per bar where Order = 3 × Predict.
| Operation | Count | Cost (cycles) | Subtotal |
| :--- | :---: | :---: | :---: |
| Bit-scan (which octave to update) | 1 | ~3 cy | ~3 cy |
| RNG sample + accumulate | 1 | ~8 cy | ~8 cy |
| Running sum update | 1 | ~2 cy | ~2 cy |
| **Total (amortized)** | **3** | — | **~13 cycles** |
| BPF: diff + 3-term FMA | 3 | ~4 cy | ~12 cy |
| Voss: weighted sum loop | Order | ~5 cy | ~45 cy (Order=9) |
| Voss: gain × filt sumC | 2 | ~4 cy | ~8 cy |
| State update (shifts) | 4 | ~1 cy | ~4 cy |
| **Total (Order=9)** | **Order+9** | — | **~69 cycles** |
O(1) amortized per bar. Each bar updates exactly 1 octave source on average. ~13 cycles/bar amortized.
O(Order) per bar. Order = 3 × Predict; at defaults (Predict=3), Order=9. ~69 cycles/bar.
### Batch Mode (SIMD Analysis)
| Operation | Vectorizable? | Notes |
| :--- | :---: | :--- |
| Octave update scheduling | No | Bit-count branching; data-dependent |
| RNG generation | Partial | SIMD RNG (e.g., xoshiro SIMD) available but niche |
| BPF recursion | No | y[n] depends on y[n-1] and y[n-2] |
| Voss weighted sum | Partial | Inner loop vectorizable but short (Order=9) |
Amortized O(1) makes SIMD gains minimal. Batch throughput: ~13 cy/bar.
Batch throughput: ~69 cy/bar at defaults.
| Metric | Value |
|--------|-------|
+2 -2
View File
@@ -7,14 +7,14 @@
| **Parameters** | `levels` (default 4), `threshMult` (default 1.0) |
| **Outputs** | Single series (Wavelet) |
| **Output range** | Tracks input |
| **Warmup** | 1 bar |
| **Warmup** | `2^levels` bars (default 16) |
### TL;DR
- The Wavelet Denoising Filter applies an *à trous* (with holes) Haar wavelet decomposition with soft thresholding to remove high-frequency noise fro...
- Parameterized by `levels` (default 4), `threshmult` (default 1.0).
- Output range: Tracks input.
- Requires 1 bar of warmup before first valid output (IsHot = true).
- Requires `2^levels` bars of warmup before first valid output (IsHot = true).
- Validated against TA-Lib, Skender, and Tulip reference implementations where available.
> "The wavelet transform is to the Fourier transform what a microscope is to a telescope: same math, different scale."