mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-24 05:28:05 +00:00
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.
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
# ADXVMA: ADX Variable Moving Average
|
||||
|
||||
> "Use ADX to measure trend strength, then feed that measurement back as the smoothing constant. When the trend is strong, track fast. When it is not, stand still. The market tells you how much to listen."
|
||||
|
||||
ADXVMA is an adaptive IIR filter that uses the Average Directional Index (ADX) as its smoothing constant. When ADX is high (strong trend), the smoothing factor approaches 1.0 and the filter tracks price aggressively. When ADX is low (range-bound), the smoothing factor approaches 0.0 and the filter barely moves. This creates a moving average that automatically switches between responsive trend-following and noise-immune range-holding without external regime detection.
|
||||
|
||||
## Historical Context
|
||||
|
||||
ADXVMA combines two well-established concepts: Welles Wilder's ADX (1978) as a trend-strength measure, and the adaptive moving average framework pioneered by Perry Kaufman's AMA (1995). While Kaufman used an efficiency ratio (net displacement / total path) to adapt smoothing, ADXVMA substitutes ADX, which measures trend directionality through the divergence of positive and negative directional movement indicators.
|
||||
|
||||
The ADX-based adaptation has a practical advantage over efficiency-ratio methods: ADX responds to the consistency of directional movement, not just net displacement. A market that trends steadily but slowly produces high ADX but low efficiency ratio. Conversely, a market with a sharp one-bar spike produces high efficiency ratio but low ADX (because the spike is not sustained). For trend-following applications, the ADX criterion better matches the trading requirement of sustained directional moves.
|
||||
|
||||
The implementation uses Wilder's RMA (Recursive Moving Average, equivalent to EMA with $\alpha = 1/N$) for all internal smoothing components (TR, +DM, -DM, DX), with warmup compensation to produce valid output from the first bar. The warmup compensator $c = 1/(1-\beta^n)$ corrects the exponential bias during the initial transient, eliminating the need for a multi-bar initialization period.
|
||||
|
||||
## Architecture & Physics
|
||||
|
||||
### 1. True Range and Directional Movement
|
||||
|
||||
Per-bar computation of True Range (TR), Plus Directional Movement (+DM), and Minus Directional Movement (-DM) using Wilder's definitions.
|
||||
|
||||
### 2. Wilder's RMA with Warmup Compensation
|
||||
|
||||
Each of TR, +DM, -DM, and DX is smoothed using RMA ($\alpha = 1/N$). The warmup compensator tracks the decay factor $e = \beta^n$ and divides the raw exponential accumulation by $(1-e)$, providing unbiased estimates from bar 1.
|
||||
|
||||
### 3. ADX Computation
|
||||
|
||||
$$
|
||||
\text{ADX} = \text{RMA}\left(\frac{|+DI - -DI|}{+DI + -DI} \times 100\right)
|
||||
$$
|
||||
|
||||
### 4. Adaptive Smoothing
|
||||
|
||||
The ADX value is clamped to $[0, 100]$ and divided by 100 to produce a smoothing constant $sc \in [0, 1]$:
|
||||
|
||||
$$
|
||||
\text{ADXVMA}_t = \text{ADXVMA}_{t-1} + sc \times (\text{source}_t - \text{ADXVMA}_{t-1})
|
||||
$$
|
||||
|
||||
## Mathematical Foundation
|
||||
|
||||
**Directional indicators:**
|
||||
|
||||
$$
|
||||
+DI = \frac{100 \cdot \text{RMA}(+DM, N)}{\text{RMA}(TR, N)}, \quad -DI = \frac{100 \cdot \text{RMA}(-DM, N)}{\text{RMA}(TR, N)}
|
||||
$$
|
||||
|
||||
**Directional Index:**
|
||||
|
||||
$$
|
||||
DX = \frac{100 \cdot |+DI - -DI|}{+DI + -DI}
|
||||
$$
|
||||
|
||||
**ADX:**
|
||||
|
||||
$$
|
||||
\text{ADX} = \text{RMA}(DX, N)
|
||||
$$
|
||||
|
||||
**Adaptive output:**
|
||||
|
||||
$$
|
||||
sc = \text{clamp}\left(\frac{\text{ADX}}{100}, 0, 1\right)
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{ADXVMA}_t = \text{ADXVMA}_{t-1} + sc \cdot (x_t - \text{ADXVMA}_{t-1})
|
||||
$$
|
||||
|
||||
**Effective time constant:** When ADX = 50, $sc = 0.5$, equivalent to an EMA with period 3. When ADX = 20, $sc = 0.2$, equivalent to period 9. When ADX = 80, $sc = 0.8$, equivalent to period 1.5.
|
||||
|
||||
**Default parameters:** `period = 14`, `minPeriod = 1`. Requires OHLC data for TR/DM computation.
|
||||
|
||||
**Pseudo-code (streaming):**
|
||||
|
||||
```
|
||||
alpha = 1/period; beta = 1 - alpha
|
||||
|
||||
// RMA with warmup compensation for TR, +DM, -DM, DX
|
||||
raw_tr = raw_tr * beta + tr * alpha
|
||||
e_tr *= beta
|
||||
comp_tr = raw_tr / (1 - e_tr) // warmup-compensated
|
||||
|
||||
// ... same for +DM, -DM ...
|
||||
|
||||
+DI = 100 * comp_pdm / comp_tr
|
||||
-DI = 100 * comp_ndm / comp_tr
|
||||
DX = 100 * |+DI - -DI| / (+DI + -DI)
|
||||
|
||||
raw_dx = raw_dx * beta + DX * alpha
|
||||
ADX = raw_dx / (1 - e_dx)
|
||||
|
||||
sc = clamp(ADX / 100, 0, 1)
|
||||
result = result + sc * (source - result)
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
- Wilder, J.W. (1978). *New Concepts in Technical Trading Systems*. Trend Research. Chapter 6: Directional Movement.
|
||||
- Kaufman, P.J. (1995). *Smarter Trading*. McGraw-Hill. Chapter 7: Adaptive Techniques.
|
||||
- Chande, T.S. (2001). *Beyond Technical Analysis*, 2nd ed. John Wiley & Sons.
|
||||
@@ -0,0 +1,80 @@
|
||||
# AHRENS: Ahrens Moving Average
|
||||
|
||||
> "Richard Ahrens looked at the EMA and thought: what if the correction term accounted for where the average was, not just where it is? The result is a self-referencing IIR filter that uses its own history as a stabilizer."
|
||||
|
||||
AHRENS is a recursive IIR filter that adjusts toward the source price minus the midpoint of its current and lagged (by one period) states. The formula $\text{AHRENS}_t = \text{AHRENS}_{t-1} + (\text{source} - \frac{\text{AHRENS}_{t-1} + \text{AHRENS}_{t-N}}{2}) / N$ creates a self-dampening feedback loop: the correction term shrinks as the current and lagged states converge, producing a smoother approach to equilibrium than a standard EMA with less tendency to overshoot on reversals.
|
||||
|
||||
## Historical Context
|
||||
|
||||
Richard D. Ahrens published "Build A Better Moving Average" in *Stocks & Commodities* magazine (Volume 31, Issue 11, October 2013). The article proposed a modification to the standard recursive moving average that incorporates a lagged copy of the average itself, creating a second-order feedback structure.
|
||||
|
||||
The key insight is the midpoint correction: instead of pulling toward the source price directly (as EMA does), Ahrens pulls toward the source minus the midpoint of the current and lagged average. This means the correction is large when the average is changing rapidly (current and lagged states diverge) and small when it is stable (current and lagged states converge). The effect is automatic damping of oscillatory behavior without sacrificing trend-tracking ability.
|
||||
|
||||
The lagged state introduces a memory requirement: a circular buffer of $N$ past AHRENS values is needed to retrieve the value from $N$ bars ago. This makes AHRENS O(1) per bar in computation but O(N) in memory, comparable to an SMA but with IIR-like smoothing characteristics.
|
||||
|
||||
## Architecture & Physics
|
||||
|
||||
### 1. Circular Buffer for Lagged State
|
||||
|
||||
A ring buffer of size $N$ stores the most recent $N$ AHRENS output values. The lagged value $\text{AHRENS}_{t-N}$ is retrieved from the buffer before it is overwritten with the current output.
|
||||
|
||||
### 2. Midpoint Correction
|
||||
|
||||
The correction term is:
|
||||
|
||||
$$
|
||||
\Delta = \frac{\text{source} - \frac{\text{AHRENS}_{t-1} + \text{AHRENS}_{t-N}}{2}}{N}
|
||||
$$
|
||||
|
||||
This blends current and historical average states, creating a damped response.
|
||||
|
||||
### 3. Recursive Update
|
||||
|
||||
$$
|
||||
\text{AHRENS}_t = \text{AHRENS}_{t-1} + \Delta
|
||||
$$
|
||||
|
||||
The update is O(1) per bar after buffer retrieval.
|
||||
|
||||
## Mathematical Foundation
|
||||
|
||||
The Ahrens recursive formula:
|
||||
|
||||
$$
|
||||
\text{AHRENS}_t = \text{AHRENS}_{t-1} + \frac{x_t - \frac{1}{2}\left(\text{AHRENS}_{t-1} + \text{AHRENS}_{t-N}\right)}{N}
|
||||
$$
|
||||
|
||||
Rearranging:
|
||||
|
||||
$$
|
||||
\text{AHRENS}_t = \text{AHRENS}_{t-1} + \frac{x_t}{N} - \frac{\text{AHRENS}_{t-1}}{2N} - \frac{\text{AHRENS}_{t-N}}{2N}
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{AHRENS}_t = \left(1 - \frac{1}{2N}\right)\text{AHRENS}_{t-1} + \frac{1}{N}x_t - \frac{1}{2N}\text{AHRENS}_{t-N}
|
||||
$$
|
||||
|
||||
**Transfer function analysis:** This is an ARMA(N,0) filter with two autoregressive taps: one at lag 1 with coefficient $(1 - 1/2N)$ and one at lag $N$ with coefficient $-1/2N$. The lag-$N$ tap creates a notch in the frequency response near $f = 1/N$, providing additional suppression of periodic noise at the averaging period.
|
||||
|
||||
**Stability:** For $N \geq 1$, the sum of absolute autoregressive coefficients is $|1-1/2N| + |1/2N| = 1$, which is on the stability boundary. The filter is marginally stable and does not diverge, but convergence is slower than a standard EMA.
|
||||
|
||||
**Default parameters:** `period = 9`, `minPeriod = 1`.
|
||||
|
||||
**Pseudo-code (streaming):**
|
||||
|
||||
```
|
||||
buffer ← circular_buffer(period) // stores past AHRENS values
|
||||
prev = nz(result, source)
|
||||
lagged = nz(buffer[head], source) // AHRENS from N bars ago
|
||||
|
||||
midpoint = (prev + lagged) / 2
|
||||
result = prev + (source - midpoint) / period
|
||||
|
||||
buffer[head] = result
|
||||
head = (head + 1) % period
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
- Ahrens, R.D. (2013). "Build A Better Moving Average." *Technical Analysis of Stocks & Commodities*, 31(11).
|
||||
- Ehlers, J.F. (2001). *Rocket Science for Traders*. Wiley. Chapter 4: Finite and Infinite Impulse Response Filters.
|
||||
@@ -0,0 +1,90 @@
|
||||
# GDEMA: Generalized Double Exponential Moving Average
|
||||
|
||||
> "Patrick Mulloy created DEMA to cancel first-order lag. GDEMA adds a volume knob: turn it past 1 and you cancel more lag than Mulloy thought possible. Turn it to 0 and you are back to a plain EMA. The generalization is the point."
|
||||
|
||||
GDEMA extends the standard DEMA (Double Exponential Moving Average) with a tunable gain factor $v$ that controls the aggressiveness of lag compensation. The formula $\text{GDEMA} = (1+v) \cdot \text{EMA}_1 - v \cdot \text{EMA}_2$ reduces to plain EMA when $v=0$, standard DEMA when $v=1$, and progressively more aggressive lag removal for $v>1$. This parametric flexibility allows traders to dial in the exact smoothness-responsiveness trade-off for their application, rather than being locked into DEMA's fixed 2:1 ratio.
|
||||
|
||||
## Historical Context
|
||||
|
||||
Patrick G. Mulloy published DEMA in "Smoothing Data with Faster Moving Averages" (*Technical Analysis of Stocks & Commodities*, February 1994). The original DEMA uses the fixed formula $2 \cdot \text{EMA} - \text{EMA}(\text{EMA})$, which cancels the first-order lag of the EMA by subtracting the double-smoothed version.
|
||||
|
||||
The generalization to an arbitrary volume factor $v$ is a natural extension that was explored by several authors in the late 1990s. Tim Tillson's T3 indicator (1998) uses a similar parameterized approach with six cascaded EMAs and a volume factor. GDEMA is the simplest member of this family: two cascaded EMAs combined with a single gain parameter.
|
||||
|
||||
The mathematical basis is the z-transform lag cancellation technique: EMA has a group delay of approximately $(N-1)/2$ samples. EMA(EMA) has approximately double that delay. The linear combination $(1+v) \cdot \text{EMA} - v \cdot \text{EMA}(\text{EMA})$ cancels $v/(v+1)$ of the total lag. At $v=1$ (DEMA), half the lag is cancelled. At $v=2$, two-thirds is cancelled, but overshoot increases proportionally.
|
||||
|
||||
## Architecture & Physics
|
||||
|
||||
### 1. Dual Cascaded EMAs
|
||||
|
||||
Two EMA stages share the same period $N$ and smoothing constant $\alpha = 2/(N+1)$:
|
||||
- **EMA1:** Standard EMA of the source.
|
||||
- **EMA2:** EMA of EMA1 (double-smoothed).
|
||||
|
||||
### 2. Warmup Compensation
|
||||
|
||||
Both EMAs use the exponential warmup compensator $c = 1/(1-\beta^n)$ to produce valid output from bar 1, eliminating the cold-start bias.
|
||||
|
||||
### 3. Parameterized Combination
|
||||
|
||||
$$
|
||||
\text{GDEMA} = (1+v) \cdot \text{EMA}_1 - v \cdot \text{EMA}_2
|
||||
$$
|
||||
|
||||
## Mathematical Foundation
|
||||
|
||||
Given smoothing constant $\alpha = 2/(N+1)$, decay $\beta = 1-\alpha$:
|
||||
|
||||
$$
|
||||
\text{EMA}_1[t] = \alpha \cdot x_t + \beta \cdot \text{EMA}_1[t-1]
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{EMA}_2[t] = \alpha \cdot \text{EMA}_1[t] + \beta \cdot \text{EMA}_2[t-1]
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{GDEMA}[t] = (1+v) \cdot \text{EMA}_1[t] - v \cdot \text{EMA}_2[t]
|
||||
$$
|
||||
|
||||
**Z-domain transfer function:**
|
||||
|
||||
$$
|
||||
H(z) = (1+v) \cdot \frac{\alpha}{1-\beta z^{-1}} - v \cdot \left(\frac{\alpha}{1-\beta z^{-1}}\right)^2
|
||||
$$
|
||||
|
||||
**Lag characteristics:**
|
||||
|
||||
| $v$ | Equivalent | Lag reduction | Overshoot risk |
|
||||
| :---: | :--- | :---: | :---: |
|
||||
| 0 | EMA | 0% | None |
|
||||
| 0.5 | Mild DEMA | 33% | Low |
|
||||
| 1.0 | Standard DEMA | 50% | Moderate |
|
||||
| 1.5 | Aggressive | 60% | High |
|
||||
| 2.0 | Very aggressive | 67% | Very high |
|
||||
|
||||
**Default parameters:** `period = 10`, `vfactor = 1.0`, `minPeriod = 1`.
|
||||
|
||||
**Pseudo-code (streaming):**
|
||||
|
||||
```
|
||||
alpha = 2 / (period + 1); beta = 1 - alpha
|
||||
|
||||
// EMA1 with warmup
|
||||
ema1_raw = alpha * (source - ema1_raw) + ema1_raw
|
||||
e *= beta
|
||||
comp = 1 / (1 - e)
|
||||
ema1 = ema1_raw * comp
|
||||
|
||||
// EMA2 with warmup (of compensated EMA1)
|
||||
ema2_raw = alpha * (ema1 - ema2_raw) + ema2_raw
|
||||
ema2 = ema2_raw * comp
|
||||
|
||||
// Generalized combination
|
||||
return (1 + v) * ema1 - v * ema2
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
- Mulloy, P.G. (1994). "Smoothing Data with Faster Moving Averages." *Technical Analysis of Stocks & Commodities*, 12(1), 11-19.
|
||||
- Tillson, T. (1998). "Smoothing Techniques for More Accurate Signals." *Technical Analysis of Stocks & Commodities*, 16(1).
|
||||
- Ehlers, J.F. (2001). *Rocket Science for Traders*. Wiley. Chapter 3: Smoothing Filters.
|
||||
@@ -0,0 +1,112 @@
|
||||
# HW: Holt-Winters Triple Exponential Smoothing
|
||||
|
||||
> "Charles Holt tracked level and slope. Peter Winters added seasonality. This implementation drops seasonality and adds acceleration, the second derivative that tells you when the trend is speeding up or slowing down. Three state variables, three smoothing constants, one second-order Taylor expansion."
|
||||
|
||||
HW implements Holt-Winters triple exponential smoothing with level (F), velocity (V), and acceleration (A) components. Instead of the seasonal component from classical Holt-Winters, this variant tracks the second derivative of the time series, enabling it to anticipate curvature in price trends. The output is a second-order Taylor expansion forecast: $F + V + \frac{1}{2}A$, providing smooth trend tracking that naturally leads price during acceleration phases and dampens during deceleration.
|
||||
|
||||
## Historical Context
|
||||
|
||||
Charles C. Holt developed double exponential smoothing in 1957 (published in 2004 after a 47-year delay), adding a slope component to simple exponential smoothing. Peter R. Winters extended this to triple smoothing in 1960, adding a seasonal component for periodic data.
|
||||
|
||||
The acceleration variant used here replaces the seasonal component with a second-order derivative tracker. This approach is common in control theory and tracking filters (e.g., the alpha-beta-gamma filter used in radar tracking), where the goal is to follow a target whose acceleration changes over time. In financial applications, acceleration corresponds to the rate of change of momentum, a signal that often leads price reversals.
|
||||
|
||||
The three smoothing constants ($\alpha$, $\beta$, $\gamma$) control the responsiveness of level, velocity, and acceleration respectively. When set to auto-derive from the period ($\alpha = 2/(N+1)$, $\beta = \gamma = 1/N$), the filter provides balanced tracking. Manual overrides allow fine-tuning for specific market regimes.
|
||||
|
||||
## Architecture & Physics
|
||||
|
||||
### 1. Three-State IIR System
|
||||
|
||||
The filter maintains three state variables updated sequentially:
|
||||
|
||||
- **F (Level):** Exponentially smoothed estimate of the current value.
|
||||
- **V (Velocity):** Exponentially smoothed estimate of the first derivative.
|
||||
- **A (Acceleration):** Exponentially smoothed estimate of the second derivative.
|
||||
|
||||
### 2. Update Equations
|
||||
|
||||
Each state depends on the previous values of all three states, creating a coupled IIR system:
|
||||
|
||||
$$
|
||||
F_t = \alpha \cdot x_t + (1-\alpha)(F_{t-1} + V_{t-1} + \tfrac{1}{2}A_{t-1})
|
||||
$$
|
||||
|
||||
$$
|
||||
V_t = \beta(F_t - F_{t-1}) + (1-\beta)(V_{t-1} + A_{t-1})
|
||||
$$
|
||||
|
||||
$$
|
||||
A_t = \gamma(V_t - V_{t-1}) + (1-\gamma)A_{t-1}
|
||||
$$
|
||||
|
||||
### 3. Taylor Forecast Output
|
||||
|
||||
$$
|
||||
\text{HW}_t = F_t + V_t + \tfrac{1}{2}A_t
|
||||
$$
|
||||
|
||||
## Mathematical Foundation
|
||||
|
||||
**State-space formulation:**
|
||||
|
||||
$$
|
||||
\mathbf{s}_t = \begin{bmatrix} F_t \\ V_t \\ A_t \end{bmatrix}
|
||||
$$
|
||||
|
||||
The update equations form the state transition:
|
||||
|
||||
$$
|
||||
F_t = \alpha \cdot x_t + (1-\alpha)\left(F_{t-1} + V_{t-1} + \tfrac{1}{2}A_{t-1}\right)
|
||||
$$
|
||||
|
||||
$$
|
||||
V_t = \beta\left(F_t - F_{t-1}\right) + (1-\beta)\left(V_{t-1} + A_{t-1}\right)
|
||||
$$
|
||||
|
||||
$$
|
||||
A_t = \gamma\left(V_t - V_{t-1}\right) + (1-\gamma) A_{t-1}
|
||||
$$
|
||||
|
||||
**Output (second-order Taylor expansion):**
|
||||
|
||||
$$
|
||||
\hat{x}_{t+1} = F_t + V_t + \tfrac{1}{2}A_t
|
||||
$$
|
||||
|
||||
**Smoothing constant relationships:**
|
||||
|
||||
| Parameter | Auto-value | Controls |
|
||||
| :---: | :--- | :--- |
|
||||
| $\alpha$ | $2/(N+1)$ | Level responsiveness |
|
||||
| $\beta$ | $1/N$ | Velocity responsiveness |
|
||||
| $\gamma$ | $1/N$ | Acceleration responsiveness |
|
||||
|
||||
**Stability conditions:** All three smoothing constants must be in $(0, 1]$. The system is stable when the eigenvalues of the state transition matrix lie within the unit circle, which is guaranteed for standard parameter ranges.
|
||||
|
||||
**Default parameters:** `period = 10`, `alpha = 0` (auto), `beta = 0` (auto), `gamma = 0` (auto), `minPeriod = 1`.
|
||||
|
||||
**Pseudo-code (streaming):**
|
||||
|
||||
```
|
||||
alpha = (na > 0) ? na : 2/(period+1)
|
||||
beta = (nb > 0) ? nb : 1/period
|
||||
gamma = (ng > 0) ? ng : 1/period
|
||||
|
||||
if first_bar:
|
||||
F = source; V = 0; A = 0
|
||||
return source
|
||||
|
||||
forecast = F + V + 0.5*A
|
||||
F_new = alpha * source + (1-alpha) * forecast
|
||||
V_new = beta * (F_new - F) + (1-beta) * (V + A)
|
||||
A_new = gamma * (V_new - V) + (1-gamma) * A
|
||||
|
||||
F = F_new; V = V_new; A = A_new
|
||||
return F + V + 0.5*A
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
- Holt, C.C. (1957/2004). "Forecasting Seasonals and Trends by Exponentially Weighted Moving Averages." *International Journal of Forecasting*, 20(1), 5-10.
|
||||
- Winters, P.R. (1960). "Forecasting Sales by Exponentially Weighted Moving Averages." *Management Science*, 6(3), 324-342.
|
||||
- Brown, R.G. (1963). *Smoothing, Forecasting and Prediction of Discrete Time Series*. Prentice-Hall. Chapter 10: Higher-Order Smoothing.
|
||||
- Benedict, T.R. & Bordner, G.W. (1962). "Synthesis of an Optimal Set of Radar Track-While-Scan Smoothing Equations." *IRE Trans. Automatic Control*, 7(4), 27-32.
|
||||
@@ -0,0 +1,103 @@
|
||||
# LEMA: Leader Exponential Moving Average
|
||||
|
||||
> "George Siligardos asked a simple question: what if you smoothed the EMA's own error and added it back? The answer is a moving average that leads price changes instead of lagging behind them. The error becomes the signal."
|
||||
|
||||
LEMA (Leader EMA) adds a smoothed error correction to the standard EMA, creating a moving average that anticipates price movement. The formula $\text{LEMA} = \text{EMA}(x, N) + \text{EMA}(x - \text{EMA}(x, N), N)$ decomposes price into a smooth component (EMA) and an error component (residual), then re-smooths the error and adds it back. The re-smoothed error represents the systematic part of the EMA's tracking deficit, and adding it back shifts the output toward where the next price is likely to be.
|
||||
|
||||
## Historical Context
|
||||
|
||||
George E. Siligardos published "Leader of the MACD" in *Technical Analysis of Stocks & Commodities* (Volume 26, Issue 7, July 2008). The article introduced LEMA as part of a broader MACD improvement, but the Leader EMA component proved useful as a standalone indicator.
|
||||
|
||||
The mathematical basis is straightforward: the EMA error $e_t = x_t - \text{EMA}_t$ is non-random during trends. When price is rising, the error is consistently positive (EMA lags below price). By smoothing this error and adding it to the EMA, the Leader compensates for the systematic lag component while filtering out the random noise component. The result is a moving average with approximately half the group delay of a standard EMA.
|
||||
|
||||
LEMA is structurally similar to DEMA ($2 \cdot \text{EMA} - \text{EMA}(\text{EMA})$), but the computational pathway differs: LEMA smooths the error signal explicitly, while DEMA derives the same correction algebraically. For identical periods, LEMA and DEMA produce similar (but not identical) outputs because the warmup compensation interacts differently with the two formulations.
|
||||
|
||||
## Architecture & Physics
|
||||
|
||||
### 1. Primary EMA
|
||||
|
||||
Standard EMA of the source with warmup compensation:
|
||||
|
||||
$$
|
||||
\text{EMA}_1 = \alpha \cdot x + (1-\alpha) \cdot \text{EMA}_1
|
||||
$$
|
||||
|
||||
### 2. Error Computation
|
||||
|
||||
$$
|
||||
e_t = x_t - \text{EMA}_1[t]
|
||||
$$
|
||||
|
||||
The error captures the tracking deficit: positive during uptrends, negative during downtrends, zero-mean during consolidation.
|
||||
|
||||
### 3. Error EMA
|
||||
|
||||
A second EMA smooths the error series, extracting the systematic (trend-related) component:
|
||||
|
||||
$$
|
||||
\text{EMA}_2 = \alpha \cdot e_t + (1-\alpha) \cdot \text{EMA}_2
|
||||
$$
|
||||
|
||||
### 4. Leader Output
|
||||
|
||||
$$
|
||||
\text{LEMA}_t = \text{EMA}_1[t] + \text{EMA}_2[t]
|
||||
$$
|
||||
|
||||
Both EMAs use warmup compensation for valid output from bar 1.
|
||||
|
||||
## Mathematical Foundation
|
||||
|
||||
With $\alpha = 2/(N+1)$ and $\beta = 1-\alpha$:
|
||||
|
||||
$$
|
||||
\text{EMA}_1[t] = \alpha \cdot x_t + \beta \cdot \text{EMA}_1[t-1]
|
||||
$$
|
||||
|
||||
$$
|
||||
e_t = x_t - \text{EMA}_1[t]
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{EMA}_2[t] = \alpha \cdot e_t + \beta \cdot \text{EMA}_2[t-1]
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{LEMA}[t] = \text{EMA}_1[t] + \text{EMA}_2[t]
|
||||
$$
|
||||
|
||||
**Expanding:** Since $e_t = x_t - \text{EMA}_1[t]$:
|
||||
|
||||
$$
|
||||
\text{LEMA} = \text{EMA}_1 + \text{EMA}(x - \text{EMA}_1) = \text{EMA}_1 + \text{EMA}(x) - \text{EMA}(\text{EMA}_1)
|
||||
$$
|
||||
|
||||
This shows LEMA is equivalent to $\text{EMA}_1 + \text{EMA}_1 - \text{EMA}_2 = 2\text{EMA}_1 - \text{EMA}_2$ in steady state, which is the DEMA formula. The distinction lies in the transient behavior during warmup.
|
||||
|
||||
**Group delay:** Approximately $\frac{N-1}{4}$ samples (half of EMA's $\frac{N-1}{2}$).
|
||||
|
||||
**Default parameters:** `period = 14`, `minPeriod = 1`.
|
||||
|
||||
**Pseudo-code (streaming):**
|
||||
|
||||
```
|
||||
alpha = 2/(period+1); beta = 1-alpha
|
||||
|
||||
// EMA1 with warmup
|
||||
ema1 = alpha*(price - ema1) + ema1
|
||||
e1 *= beta; comp_ema1 = ema1 / (1-e1)
|
||||
|
||||
// Error
|
||||
error = price - comp_ema1
|
||||
|
||||
// EMA2 (of error) with warmup
|
||||
ema2 = alpha*(error - ema2) + ema2
|
||||
e2 *= beta; comp_ema2 = ema2 / (1-e2)
|
||||
|
||||
return comp_ema1 + comp_ema2
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
- Siligardos, G.E. (2008). "Leader of the MACD." *Technical Analysis of Stocks & Commodities*, 26(7), 30-37.
|
||||
- Mulloy, P.G. (1994). "Smoothing Data with Faster Moving Averages." *Technical Analysis of Stocks & Commodities*, 12(1). (DEMA, the algebraic equivalent.)
|
||||
@@ -0,0 +1,102 @@
|
||||
# LTMA: Linear Trend Moving Average
|
||||
|
||||
> "Estimate the level. Estimate the slope. Project forward. It is the same trick radar operators use to track aircraft, applied to price data. LTMA extrapolates the EMA's implicit linear trend by a full period into the future."
|
||||
|
||||
LTMA uses dual cascaded EMAs to estimate both the level and the instantaneous slope of the price series, then extrapolates the linear trend forward by the full period length. Unlike DEMA (which cancels first-order lag algebraically), LTMA explicitly estimates the slope from the EMA difference and projects it: $\text{LTMA} = \text{EMA}_1 + \text{slope} \times N$, where $\text{slope} = \text{EMA}_1 - \text{EMA}_2$. This produces a predictive moving average with zero steady-state error on linear trends, at the cost of significant overshoot on reversals.
|
||||
|
||||
## Historical Context
|
||||
|
||||
Linear trend extrapolation from dual exponential smoothing is a core technique in time-series forecasting, originating with Brown's linear exponential smoothing (1963) and Holt's two-parameter method (1957). The application to technical analysis leverages the same principle: if you can estimate both where price is and how fast it is moving, you can project where it will be.
|
||||
|
||||
LTMA differs from Holt's method in that both EMAs share the same smoothing constant $\alpha = 2/(N+1)$, simplifying the parameter space to a single period. The slope estimate $\text{EMA}_1 - \text{EMA}_2$ approximates the first derivative of the exponentially smoothed series, and projecting by $N$ bars creates an aggressive lead that compensates for the EMA's inherent lag.
|
||||
|
||||
The projection distance of $N$ bars (the full period) makes LTMA more aggressive than DEMA or TEMA. While DEMA effectively projects by approximately $N/2$ bars via its $2 \cdot \text{EMA}_1 - \text{EMA}_2$ formula, LTMA's full-period projection creates a stronger lead that can anticipate trend continuation but overshoots badly on sharp reversals.
|
||||
|
||||
## Architecture & Physics
|
||||
|
||||
### 1. Dual Cascaded EMAs
|
||||
|
||||
Two EMAs with shared $\alpha = 2/(N+1)$:
|
||||
|
||||
- **EMA1:** Standard EMA of source.
|
||||
- **EMA2:** EMA of EMA1.
|
||||
|
||||
### 2. Slope Estimation
|
||||
|
||||
$$
|
||||
\text{slope} = \text{EMA}_1 - \text{EMA}_2
|
||||
$$
|
||||
|
||||
The difference between single and double-smoothed EMAs approximates the first derivative scaled by a factor related to $\alpha$.
|
||||
|
||||
### 3. Linear Extrapolation
|
||||
|
||||
$$
|
||||
\text{LTMA} = \text{EMA}_1 + \text{slope} \times N
|
||||
$$
|
||||
|
||||
### 4. Warmup Compensation
|
||||
|
||||
Both EMAs use the exponential warmup compensator for valid output from bar 1.
|
||||
|
||||
## Mathematical Foundation
|
||||
|
||||
With $\alpha = 2/(N+1)$, $\beta = 1 - \alpha$:
|
||||
|
||||
$$
|
||||
\text{EMA}_1[t] = \alpha \cdot x_t + \beta \cdot \text{EMA}_1[t-1]
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{EMA}_2[t] = \alpha \cdot \text{EMA}_1[t] + \beta \cdot \text{EMA}_2[t-1]
|
||||
$$
|
||||
|
||||
**Slope and output:**
|
||||
|
||||
$$
|
||||
\text{slope}_t = \text{EMA}_1[t] - \text{EMA}_2[t]
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{LTMA}[t] = \text{EMA}_1[t] + N \cdot \text{slope}_t
|
||||
$$
|
||||
|
||||
$$
|
||||
= (1+N) \cdot \text{EMA}_1[t] - N \cdot \text{EMA}_2[t]
|
||||
$$
|
||||
|
||||
**Comparison with DEMA/GDEMA:** LTMA is equivalent to GDEMA with $v = N$:
|
||||
|
||||
| Method | Formula | Projection |
|
||||
| :--- | :--- | :---: |
|
||||
| EMA | $\text{EMA}_1$ | 0 bars |
|
||||
| DEMA | $2\text{EMA}_1 - \text{EMA}_2$ | ~$N/2$ bars |
|
||||
| LTMA | $(1+N)\text{EMA}_1 - N\text{EMA}_2$ | $N$ bars |
|
||||
|
||||
**Steady-state error on linear trend:** Zero. If $x_t = a + bt$, then $\text{LTMA}_t = a + bt$ exactly (after transient).
|
||||
|
||||
**Default parameters:** `period = 14`, `minPeriod = 1`.
|
||||
|
||||
**Pseudo-code (streaming):**
|
||||
|
||||
```
|
||||
alpha = 2/(period+1); beta = 1-alpha
|
||||
|
||||
ema1 = alpha*(src - ema1) + ema1
|
||||
ema2 = alpha*(ema1 - ema2) + ema2
|
||||
|
||||
if warmup:
|
||||
e *= beta; c = 1/(1-e)
|
||||
comp1 = c*ema1; comp2 = c*ema2
|
||||
slope = comp1 - comp2
|
||||
result = comp1 + slope * period
|
||||
else:
|
||||
slope = ema1 - ema2
|
||||
result = ema1 + slope * period
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
- Holt, C.C. (1957/2004). "Forecasting Seasonals and Trends by Exponentially Weighted Moving Averages." *International Journal of Forecasting*, 20(1), 5-10.
|
||||
- Brown, R.G. (1963). *Smoothing, Forecasting and Prediction of Discrete Time Series*. Prentice-Hall. Chapter 5: Linear Exponential Smoothing.
|
||||
- Gardner, E.S. (1985). "Exponential Smoothing: The State of the Art." *Journal of Forecasting*, 4(1), 1-28.
|
||||
@@ -0,0 +1,103 @@
|
||||
# MCNMA: McNicholl EMA (Zero-Lag TEMA)
|
||||
|
||||
> "Dennis McNicholl applied TEMA to itself and subtracted the result, producing six cascaded EMA stages that cancel lag through three layers of triple-smoothing. When single TEMA is not enough, double it."
|
||||
|
||||
MCNMA computes $2 \times \text{TEMA}(x, N) - \text{TEMA}(\text{TEMA}(x, N), N)$, applying the DEMA lag-cancellation technique to TEMA itself. This requires six cascaded EMA stages: three for the inner TEMA and three for the outer TEMA of the inner TEMA's output. The result is an extremely responsive moving average that tracks fast trends with minimal lag, at the cost of significant overshoot on reversals. Published by Dennis McNicholl in "Better Bollinger Bands" (*Futures Magazine*, October 1998) as a component for improved volatility band construction.
|
||||
|
||||
## Historical Context
|
||||
|
||||
Dennis McNicholl published MCNMA as part of his "Better Bollinger Bands" article in *Futures Magazine* (October 1998), where he argued that standard Bollinger Bands use SMA as the center line, introducing unnecessary lag. His solution was to use a zero-lag moving average derived from nested triple exponential smoothing.
|
||||
|
||||
MCNMA is the logical extension of Mulloy's lag-cancellation hierarchy:
|
||||
- **DEMA** (1994): $2\text{EMA}_1 - \text{EMA}_2$ (2 stages, cancels first-order lag)
|
||||
- **TEMA** (1994): $3\text{EMA}_1 - 3\text{EMA}_2 + \text{EMA}_3$ (3 stages, cancels first and second-order lag)
|
||||
- **MCNMA** (1998): $2\text{TEMA}_1 - \text{TEMA}_2$ where $\text{TEMA}_2 = \text{TEMA}(\text{TEMA}_1)$ (6 stages, cancels through third order)
|
||||
|
||||
Each additional stage of nesting removes another order of lag, but also amplifies noise and overshoot. MCNMA represents the practical limit of this approach; further nesting produces filters that oscillate around price rather than tracking it.
|
||||
|
||||
## Architecture & Physics
|
||||
|
||||
### 1. Inner TEMA (Stages 1-3)
|
||||
|
||||
Three cascaded EMAs compute $\text{TEMA}_1 = 3 \cdot C_1 - 3 \cdot C_2 + C_3$, where $C_i$ is the warmup-compensated output of EMA stage $i$.
|
||||
|
||||
### 2. Outer TEMA (Stages 4-6)
|
||||
|
||||
Three more EMAs receive $\text{TEMA}_1$ as input and compute $\text{TEMA}_2 = 3 \cdot C_4 - 3 \cdot C_5 + C_6$.
|
||||
|
||||
### 3. DEMA Combination
|
||||
|
||||
$$
|
||||
\text{MCNMA} = 2 \cdot \text{TEMA}_1 - \text{TEMA}_2
|
||||
$$
|
||||
|
||||
### 4. Shared Warmup Compensator
|
||||
|
||||
All six stages share a single decay tracker $e = \beta^n$, with compensation factor $c = 1/(1-e)$.
|
||||
|
||||
## Mathematical Foundation
|
||||
|
||||
With $\alpha = 2/(N+1)$, $\beta = 1 - \alpha$, and warmup compensator $c = 1/(1-\beta^n)$:
|
||||
|
||||
**Inner TEMA:**
|
||||
|
||||
$$
|
||||
C_1 = c \cdot E_1, \quad C_2 = c \cdot E_2, \quad C_3 = c \cdot E_3
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{TEMA}_1 = 3C_1 - 3C_2 + C_3
|
||||
$$
|
||||
|
||||
where $E_1 = \alpha(x - E_1) + E_1$, $E_2 = \alpha(C_1 - E_2) + E_2$, $E_3 = \alpha(C_2 - E_3) + E_3$.
|
||||
|
||||
**Outer TEMA:**
|
||||
|
||||
$$
|
||||
C_4 = c \cdot E_4, \quad C_5 = c \cdot E_5, \quad C_6 = c \cdot E_6
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{TEMA}_2 = 3C_4 - 3C_5 + C_6
|
||||
$$
|
||||
|
||||
where $E_4 = \alpha(\text{TEMA}_1 - E_4) + E_4$, etc.
|
||||
|
||||
**Output:**
|
||||
|
||||
$$
|
||||
\text{MCNMA} = 2 \cdot \text{TEMA}_1 - \text{TEMA}_2
|
||||
$$
|
||||
|
||||
**Effective lag:** Near zero for polynomial trends up to degree 3. The six-stage cascade provides approximately $5\times$ less lag than a single EMA of the same period.
|
||||
|
||||
**Overshoot risk:** High. The $2\text{TEMA} - \text{TEMA}(\text{TEMA})$ formula amplifies the TEMA's already aggressive lag compensation.
|
||||
|
||||
**Default parameters:** `period = 14`, `minPeriod = 1`.
|
||||
|
||||
**Pseudo-code (streaming):**
|
||||
|
||||
```
|
||||
alpha = 2/(period+1); beta = 1-alpha
|
||||
e_decay *= beta; comp = 1/(1-e_decay)
|
||||
|
||||
// Inner TEMA: 3 cascaded EMAs
|
||||
e1 += alpha*(src - e1); c1 = e1*comp
|
||||
e2 += alpha*(c1 - e2); c2 = e2*comp
|
||||
e3 += alpha*(c2 - e3); c3 = e3*comp
|
||||
tema1 = 3*c1 - 3*c2 + c3
|
||||
|
||||
// Outer TEMA: 3 cascaded EMAs of tema1
|
||||
e4 += alpha*(tema1 - e4); c4 = e4*comp
|
||||
e5 += alpha*(c4 - e5); c5 = e5*comp
|
||||
e6 += alpha*(c5 - e6); c6 = e6*comp
|
||||
tema2 = 3*c4 - 3*c5 + c6
|
||||
|
||||
return 2*tema1 - tema2
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
- McNicholl, D. (1998). "Better Bollinger Bands." *Futures Magazine*, October 1998.
|
||||
- Mulloy, P.G. (1994). "Smoothing Data with Faster Moving Averages." *Technical Analysis of Stocks & Commodities*, 12(1), 11-19. (DEMA and TEMA originals.)
|
||||
- Mulloy, P.G. (1994). "Smoothing Data with Less Lag." *Technical Analysis of Stocks & Commodities*, 12(2). (TEMA continuation.)
|
||||
@@ -0,0 +1,92 @@
|
||||
# NLMA: Non-Lag Moving Average
|
||||
|
||||
> "Igorad at TrendLaboratory borrowed a trick from digital filter design: use a damped cosine kernel with negative weights in the mid-section to cancel the lag that positive-only kernels always produce. The result looks like an FIR filter but behaves like nothing else."
|
||||
|
||||
NLMA uses a damped cosine (fading sinusoid) kernel where the weight at position $i$ is $w(i) = \cos(2\pi i/N) \times (1 - i/N)$. The cosine oscillation creates negative weights in the mid-section of the kernel, which subtract lagged price components and reduce the filter's group delay. The linear decay envelope $(1 - i/N)$ ensures the kernel tapers to zero at the window edge. Normalization by the signed weight sum preserves DC gain of 1.0. The result is a moving average with substantially less lag than an SMA of the same period.
|
||||
|
||||
## Historical Context
|
||||
|
||||
NLMA was developed by Igorad (username on trading forums) at TrendLaboratory, inspired by the FATL/SATL digital filter coefficient sets published by Finware. The FATL (Fast Adaptive Trend Line) and SATL (Slow Adaptive Trend Line) filters use fixed FIR coefficients derived from optimal filter design, with negative weights that provide lag cancellation. Igorad's contribution was to replace the fixed coefficients with a parametric damped-cosine formula, allowing the filter to be configured for any period.
|
||||
|
||||
The damped cosine kernel has a natural interpretation in signal processing: it is the impulse response of a damped resonator at frequency $f = 1/N$. The resonance frequency matches the filter period, meaning the negative portion of the cosine systematically cancels the frequency component that causes the most lag. This is analogous to how DEMA uses $2\text{EMA} - \text{EMA}(\text{EMA})$ to cancel lag, but NLMA achieves it through the kernel shape itself rather than algebraic subtraction.
|
||||
|
||||
The presence of negative weights means NLMA is not a convex combination of input prices. The output can exceed the input range (overshoot), similar to DEMA and HMA.
|
||||
|
||||
## Architecture & Physics
|
||||
|
||||
### 1. Damped Cosine Weight Function
|
||||
|
||||
For each lag position $j = 0, 1, \ldots, N-1$ (where $j=0$ is newest):
|
||||
|
||||
$$
|
||||
w(j) = \cos\!\left(\frac{2\pi j}{N}\right) \times \left(1 - \frac{j}{N}\right)
|
||||
$$
|
||||
|
||||
### 2. Signed-Sum Normalization
|
||||
|
||||
The weight sum includes both positive and negative weights:
|
||||
|
||||
$$
|
||||
\text{NLMA}_t = \frac{\sum_{j=0}^{N-1} w(j) \cdot x_{t-j}}{\sum_{j=0}^{N-1} w(j)}
|
||||
$$
|
||||
|
||||
Because some weights are negative, $\sum w < \sum |w|$, which amplifies the effective contribution of recent (positive-weighted) bars.
|
||||
|
||||
### 3. Adaptive Warmup
|
||||
|
||||
During the warmup period ($\text{count} < N$), the kernel is recomputed with the effective period $p = \min(\text{bar\_count}, N)$, providing valid output from bar 1.
|
||||
|
||||
## Mathematical Foundation
|
||||
|
||||
The NLMA kernel function:
|
||||
|
||||
$$
|
||||
w[j] = \cos\!\left(\frac{2\pi j}{N}\right) \cdot \left(1 - \frac{j}{N}\right), \quad j = 0, 1, \ldots, N-1
|
||||
$$
|
||||
|
||||
**Weight structure analysis:**
|
||||
|
||||
| Region | Range of $j$ | $\cos$ sign | Weight sign | Effect |
|
||||
| :--- | :---: | :---: | :---: | :--- |
|
||||
| Recent | $0 \leq j < N/4$ | + | + | Track price |
|
||||
| Mid-lag | $N/4 \leq j < 3N/4$ | - | - | Cancel lag |
|
||||
| Old | $3N/4 \leq j < N$ | + | + | Mild stabilization |
|
||||
|
||||
The negative mid-section weights are the lag-cancellation mechanism. They subtract the delayed price component that would otherwise pull the output backward.
|
||||
|
||||
**Frequency response:** The damped cosine kernel creates a bandpass notch near $f = 1/N$, suppressing the frequency most responsible for lag while passing lower frequencies (trend) and attenuating higher frequencies (noise).
|
||||
|
||||
**DC gain normalization:**
|
||||
|
||||
$$
|
||||
H(0) = \frac{\sum w[j]}{\sum w[j]} = 1
|
||||
$$
|
||||
|
||||
**Default parameters:** `period = 14`, `minPeriod = 1`.
|
||||
|
||||
**Pseudo-code (streaming):**
|
||||
|
||||
```
|
||||
p = min(bar_count, period)
|
||||
|
||||
// Compute weights (recompute during warmup)
|
||||
for j = 0 to p-1:
|
||||
angle = 2π * j / p
|
||||
decay = 1 - j/p
|
||||
w[j] = cos(angle) * decay
|
||||
|
||||
// Weighted sum with signed normalization
|
||||
sum_wv = 0; sum_w = 0
|
||||
for i = 0 to p-1:
|
||||
if not NaN(source[i]):
|
||||
sum_wv += source[i] * w[i]
|
||||
sum_w += w[i]
|
||||
|
||||
return sum_w != 0 ? sum_wv / sum_w : source
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
- Igorad / TrendLaboratory. "NonLagMA" indicator documentation. Available on TradingView and various trading forums.
|
||||
- Finware Ltd. "FATL/SATL Digital Filters." Technical documentation for FinWare trading software.
|
||||
- Ehlers, J.F. (2001). *Rocket Science for Traders*. Wiley. Chapter 4: FIR Filters with Negative Weights.
|
||||
@@ -0,0 +1,108 @@
|
||||
# NMA: Natural Moving Average
|
||||
|
||||
> "Jim Sloman looked at how volatility distributes across a window and asked: if the most volatile bars are recent, should the filter not respond faster? NMA derives its smoothing constant from the volatility profile itself, weighted by a square-root kernel that emphasizes recent action."
|
||||
|
||||
NMA is an adaptive IIR filter whose smoothing ratio is derived from a volatility-weighted square-root kernel analysis of log-price movements over a lookback window. When volatility concentrates in recent bars, the ratio approaches 1.0 (fast tracking). When volatility is spread uniformly, the ratio approaches $1/\sqrt{N}$ (heavy smoothing). The square-root kernel $(\sqrt{i+1} - \sqrt{i})$ gives a concave-down weighting that gently emphasizes recency, while the log-price transformation normalizes for price level, making the adaptation scale-invariant.
|
||||
|
||||
## Historical Context
|
||||
|
||||
Jim Sloman introduced the Natural Moving Average in *Ocean Theory* (pages 63-70), a book that applied chaos and complexity theory metaphors to financial markets. The NMA was designed as a "natural" filter that lets the market's own volatility structure determine the smoothing rate, rather than imposing an arbitrary period.
|
||||
|
||||
The core innovation is the square-root differencing kernel $\sqrt{i+1} - \sqrt{i}$ as the weighting function for volatility. This kernel has the property that its cumulative sum $\sqrt{N}$ grows sublinearly, meaning each additional bar in the lookback contributes less weight than the previous one. This creates a "diminishing returns" effect: extending the lookback adds context without drowning out recent information.
|
||||
|
||||
The log-price transformation ($\ln(\text{price}) \times 1000$) serves two purposes: (1) it makes the volatility measure proportional to percentage moves rather than absolute dollar moves, and (2) the scaling factor of 1000 brings typical values into a numerically convenient range for the ratio computation.
|
||||
|
||||
NMA belongs to the family of adaptive moving averages alongside KAMA, VIDYA, and ADXVMA, but uses a unique adaptation mechanism based on the spatial distribution of volatility rather than a single efficiency or strength metric.
|
||||
|
||||
## Architecture & Physics
|
||||
|
||||
### 1. Log-Price Buffer
|
||||
|
||||
A circular buffer of size $N+1$ stores $\ln(\text{price}) \times 1000$ for each bar, providing the lookback data for volatility computation.
|
||||
|
||||
### 2. Volatility-Weighted Square-Root Ratio
|
||||
|
||||
For each bar $i$ in the lookback:
|
||||
|
||||
$$
|
||||
o_i = |\ln_i - \ln_{i+1}|
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{num} = \sum_{i=0}^{N-1} o_i \cdot \left(\sqrt{i+1} - \sqrt{i}\right)
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{denom} = \sum_{i=0}^{N-1} o_i
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{ratio} = \frac{\text{num}}{\text{denom}}
|
||||
$$
|
||||
|
||||
### 3. Adaptive EMA Step
|
||||
|
||||
$$
|
||||
\text{NMA}_t = \text{NMA}_{t-1} + \text{ratio} \times (x_t - \text{NMA}_{t-1})
|
||||
$$
|
||||
|
||||
## Mathematical Foundation
|
||||
|
||||
**Log-price volatility:**
|
||||
|
||||
$$
|
||||
o_i = \left|\ln(x_{t-i}) - \ln(x_{t-i-1})\right| \times 1000
|
||||
$$
|
||||
|
||||
**Square-root kernel weights:**
|
||||
|
||||
$$
|
||||
\phi_i = \sqrt{i+1} - \sqrt{i} = \frac{1}{\sqrt{i+1} + \sqrt{i}}
|
||||
$$
|
||||
|
||||
Note: $\phi_i \approx \frac{1}{2\sqrt{i}}$ for large $i$, confirming the $1/\sqrt{i}$ decay rate.
|
||||
|
||||
**Adaptive ratio:**
|
||||
|
||||
$$
|
||||
r = \frac{\sum_{i=0}^{N-1} o_i \cdot \phi_i}{\sum_{i=0}^{N-1} o_i}
|
||||
$$
|
||||
|
||||
**Ratio bounds:**
|
||||
|
||||
- If all volatility is at $i = 0$ (most recent): $r = \phi_0 = \sqrt{1} - \sqrt{0} = 1$
|
||||
- If volatility is uniform: $r = \frac{\sum \phi_i}{N} = \frac{\sqrt{N}}{N} = \frac{1}{\sqrt{N}}$
|
||||
- For $N = 40$: uniform ratio $\approx 0.158$, equivalent to EMA period $\approx 11$
|
||||
|
||||
**IIR update:**
|
||||
|
||||
$$
|
||||
\text{NMA}_t = \text{NMA}_{t-1} + r_t \cdot (x_t - \text{NMA}_{t-1})
|
||||
$$
|
||||
|
||||
**Default parameters:** `period = 40`, `minPeriod = 1`.
|
||||
|
||||
**Pseudo-code (streaming):**
|
||||
|
||||
```
|
||||
// Store scaled log-price
|
||||
lnBuf[head] = log(src) * 1000
|
||||
|
||||
// Compute volatility-weighted ratio
|
||||
num = 0; denom = 0
|
||||
for i = 0 to bars-1:
|
||||
oi = |lnBuf[t-i] - lnBuf[t-i-1]|
|
||||
num += oi * (sqrt(i+1) - sqrt(i))
|
||||
denom += oi
|
||||
|
||||
ratio = denom != 0 ? num/denom : 0
|
||||
|
||||
// Adaptive EMA step
|
||||
result = result + ratio * (src - result)
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
- Sloman, J. *Ocean Theory*. Pages 63-70. (Original NMA description.)
|
||||
- Kaufman, P.J. (2013). *Trading Systems and Methods*, 5th ed. Wiley. Chapter 7: Adaptive Moving Averages.
|
||||
- Chande, T.S. & Kroll, S. (1994). *The New Technical Trader*. Wiley. (Adaptive filter framework.)
|
||||
@@ -0,0 +1,91 @@
|
||||
# NYQMA: Nyquist Moving Average
|
||||
|
||||
> "Manfred Dürschner applied the Nyquist-Shannon sampling theorem to cascaded moving averages: the second smoothing period must not exceed half the first, or you get aliasing artifacts. Respect the theorem and the ghost signals disappear."
|
||||
|
||||
NYQMA combines a primary LWMA (Linear Weighted Moving Average) with a secondary LWMA applied to the first, using lag-compensating extrapolation: $\text{NYQMA} = (1+\alpha) \cdot \text{MA}_1 - \alpha \cdot \text{MA}_2$, where $\alpha = N_2 / (N_1 - N_2)$. The Nyquist constraint $N_2 \leq \lfloor N_1/2 \rfloor$ ensures the second smoothing does not introduce aliasing artifacts ("ghost signals") into the output. This produces a lag-reduced moving average grounded in sampling theory rather than ad-hoc coefficient tuning.
|
||||
|
||||
## Historical Context
|
||||
|
||||
Dr. Manfred G. Dürschner published NYQMA in *Gleitende Durchschnitte 3.0* ("Moving Averages 3.0"), a German-language work that applies rigorous signal-processing theory to financial moving average design. Dürschner's key insight was that cascading two smoothing operations is mathematically equivalent to sampling a continuous signal at two rates, and the Nyquist-Shannon sampling theorem dictates that the second rate cannot exceed half the first without introducing aliasing.
|
||||
|
||||
The Nyquist-Shannon theorem (1949) states that a signal must be sampled at more than twice its highest frequency to avoid aliasing. In the context of cascaded MAs, the "sampling rate" analogy maps to the smoothing period: a primary MA with period $N_1$ has an effective frequency cutoff, and the secondary MA with period $N_2$ must have a cutoff at no more than half that frequency (i.e., $N_2 \leq N_1/2$) to avoid passing through frequency components that the first MA was designed to suppress.
|
||||
|
||||
The lag compensation formula $(1+\alpha) \cdot \text{MA}_1 - \alpha \cdot \text{MA}_2$ is structurally identical to DEMA and GDEMA, but with the critical distinction that both MAs are LWMAs (not EMAs) and the gain factor $\alpha$ is derived from the period ratio rather than being a free parameter.
|
||||
|
||||
## Architecture & Physics
|
||||
|
||||
### 1. Primary LWMA
|
||||
|
||||
A standard Linear Weighted Moving Average with period $N_1$:
|
||||
|
||||
$$
|
||||
\text{MA}_1 = \text{WMA}(x, N_1)
|
||||
$$
|
||||
|
||||
### 2. Secondary LWMA
|
||||
|
||||
A LWMA applied to $\text{MA}_1$ with Nyquist-constrained period $N_2 \leq \lfloor N_1/2 \rfloor$:
|
||||
|
||||
$$
|
||||
\text{MA}_2 = \text{WMA}(\text{MA}_1, N_2)
|
||||
$$
|
||||
|
||||
### 3. Lag-Compensating Extrapolation
|
||||
|
||||
$$
|
||||
\alpha = \frac{N_2}{N_1 - N_2}
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{NYQMA} = (1 + \alpha) \cdot \text{MA}_1 - \alpha \cdot \text{MA}_2
|
||||
$$
|
||||
|
||||
### 4. Nyquist Enforcement
|
||||
|
||||
The implementation clamps $N_2 = \min(N_2, \lfloor N_1/2 \rfloor)$ to enforce the sampling constraint.
|
||||
|
||||
## Mathematical Foundation
|
||||
|
||||
**LWMA (period $N$):**
|
||||
|
||||
$$
|
||||
\text{WMA}(x, N) = \frac{\sum_{i=0}^{N-1} (N-i) \cdot x_{t-i}}{\sum_{i=0}^{N-1} (N-i)} = \frac{\sum_{i=0}^{N-1} (N-i) \cdot x_{t-i}}{N(N+1)/2}
|
||||
$$
|
||||
|
||||
**Lag compensation coefficient:**
|
||||
|
||||
$$
|
||||
\alpha = \frac{N_2}{N_1 - N_2}
|
||||
$$
|
||||
|
||||
**Output:**
|
||||
|
||||
$$
|
||||
\text{NYQMA} = (1 + \alpha) \cdot \text{WMA}(x, N_1) - \alpha \cdot \text{WMA}(\text{WMA}(x, N_1), N_2)
|
||||
$$
|
||||
|
||||
**Nyquist constraint (hard rule):**
|
||||
|
||||
$$
|
||||
N_2 \leq \left\lfloor \frac{N_1}{2} \right\rfloor
|
||||
$$
|
||||
|
||||
**Lag analysis:** WMA has group delay $(N-1)/3$. The extrapolation compensates a fraction $\alpha/(1+\alpha) = N_2/N_1$ of the primary MA's lag.
|
||||
|
||||
**Default parameters:** `period = 89` ($N_1$), `nyquist_period = 21` ($N_2$), `minPeriod = 2`.
|
||||
|
||||
**Pseudo-code (streaming):**
|
||||
|
||||
```
|
||||
n2 = min(nyquist_period, period / 2) // enforce Nyquist
|
||||
ma1 = WMA(src, period)
|
||||
ma2 = WMA(ma1, n2)
|
||||
alpha = n2 / (period - n2)
|
||||
return (1 + alpha) * ma1 - alpha * ma2
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
- Dürschner, M.G. *Gleitende Durchschnitte 3.0*. (Original NYQMA publication, German language.)
|
||||
- Shannon, C.E. (1949). "Communication in the Presence of Noise." *Proceedings of the IRE*, 37(1), 10-21.
|
||||
- Nyquist, H. (1928). "Certain Topics in Telegraph Transmission Theory." *Transactions of the AIEE*, 47(2), 617-644.
|
||||
@@ -0,0 +1,92 @@
|
||||
# RAIN: Rainbow Moving Average
|
||||
|
||||
> "Mel Widner applied SMA ten times recursively, then weighted the layers like a rainbow: brightest at the top, fading toward the base. Ten colors of smoothing, one composite average that sees both fast and slow structure simultaneously."
|
||||
|
||||
RAIN recursively applies SMA 10 times, producing 10 layers of progressively smoother price representation, then computes a weighted average across all layers. Layers 1-4 receive weights 5, 4, 3, 2 (emphasizing the more responsive layers), while layers 5-10 each receive weight 1, for a total divisor of 20. This multi-scale composition produces a moving average that responds to short-term price changes through the lightly smoothed upper layers while maintaining stability through the heavily smoothed lower layers.
|
||||
|
||||
## Historical Context
|
||||
|
||||
Mel Widner published "Rainbow Charts" in *Technical Analysis of Stocks & Commodities* (1998), introducing the concept of recursive SMA application as both a visualization technique and a composite smoothing method. The thinkorswim platform later standardized the weight vector as $[5, 4, 3, 2, 1, 1, 1, 1, 1, 1]$, which became the canonical RAIN MA.
|
||||
|
||||
The recursive SMA application has a deep mathematical interpretation: applying SMA $k$ times is equivalent to convolving the rectangular kernel with itself $k$ times, which produces a B-spline kernel of order $k$. Thus RAIN's 10 layers correspond to B-splines of orders 1 through 10, and the weighted average blends these spline approximations. The B-spline interpretation explains why higher layers are smoother: each convolution adds a degree of polynomial reproduction and reduces the spectral sidelobe level.
|
||||
|
||||
The weight vector $[5, 4, 3, 2, 1, 1, 1, 1, 1, 1]$ with sum 20 was chosen empirically rather than derived from optimization theory. The declining weights for layers 1-4 bias the output toward the more responsive layers, making RAIN track trends more closely than a uniform average of all 10 layers would.
|
||||
|
||||
## Architecture & Physics
|
||||
|
||||
### 1. Ten Cascaded SMA Layers
|
||||
|
||||
Each layer is an SMA applied to the previous layer's output:
|
||||
|
||||
$$
|
||||
\text{MA}_1 = \text{SMA}(x, N), \quad \text{MA}_k = \text{SMA}(\text{MA}_{k-1}, N), \quad k = 2, \ldots, 10
|
||||
$$
|
||||
|
||||
### 2. O(1) Running-Sum SMA
|
||||
|
||||
Each of the 10 SMA layers uses a circular buffer with a running sum, giving O(1) per-bar update cost per layer. Total cost: O(10) per bar, with O($10 \times N$) memory for the 10 buffers.
|
||||
|
||||
### 3. Weighted Composite
|
||||
|
||||
$$
|
||||
\text{RAIN} = \frac{5 \cdot \text{MA}_1 + 4 \cdot \text{MA}_2 + 3 \cdot \text{MA}_3 + 2 \cdot \text{MA}_4 + \sum_{k=5}^{10} \text{MA}_k}{20}
|
||||
$$
|
||||
|
||||
## Mathematical Foundation
|
||||
|
||||
**Layer computation (recursive SMA):**
|
||||
|
||||
$$
|
||||
\text{MA}_1[t] = \frac{1}{N}\sum_{i=0}^{N-1} x_{t-i}
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{MA}_k[t] = \frac{1}{N}\sum_{i=0}^{N-1} \text{MA}_{k-1}[t-i], \quad k = 2, \ldots, 10
|
||||
$$
|
||||
|
||||
**Equivalent kernel:** The $k$-fold SMA is the $k$-th order B-spline kernel:
|
||||
|
||||
$$
|
||||
B_k(x) = \underbrace{B_0 * B_0 * \cdots * B_0}_{k \text{ times}}(x)
|
||||
$$
|
||||
|
||||
where $B_0$ is the rectangular pulse.
|
||||
|
||||
**Weighted output:**
|
||||
|
||||
$$
|
||||
\text{RAIN} = \frac{\sum_{k=1}^{10} w_k \cdot \text{MA}_k}{20}
|
||||
$$
|
||||
|
||||
with weights $\mathbf{w} = [5, 4, 3, 2, 1, 1, 1, 1, 1, 1]$.
|
||||
|
||||
**Group delay:** Each SMA layer adds $(N-1)/2$ bars of lag. However, the weighted composite lag is:
|
||||
|
||||
$$
|
||||
\bar{d} = \frac{\sum w_k \cdot k \cdot (N-1)/2}{\sum w_k}
|
||||
$$
|
||||
|
||||
For $N = 2$: $\bar{d} \approx 1.85$ bars. The upper-layer weighting significantly reduces the effective lag below what layer 10 alone would produce.
|
||||
|
||||
**Default parameters:** `period = 2`, `fixed layers = 10`, `minPeriod = 1`.
|
||||
|
||||
**Pseudo-code (streaming):**
|
||||
|
||||
```
|
||||
// 10 circular buffers with running sums
|
||||
for layer = 1 to 10:
|
||||
sum[layer] -= buf[layer][head]
|
||||
sum[layer] += input[layer] // input is price for layer 1, MA[layer-1] for others
|
||||
buf[layer][head] = input[layer]
|
||||
MA[layer] = sum[layer] / count
|
||||
|
||||
head = (head + 1) % period
|
||||
|
||||
return (5*MA[1] + 4*MA[2] + 3*MA[3] + 2*MA[4] + MA[5] + MA[6] + MA[7] + MA[8] + MA[9] + MA[10]) / 20
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
- Widner, M. (1998). "Rainbow Charts." *Technical Analysis of Stocks & Commodities*.
|
||||
- thinkorswim / TD Ameritrade. "RainbowAverage" study documentation.
|
||||
- Schoenberg, I.J. (1946). "Contributions to the Problem of Approximation of Equidistant Data by Analytic Functions." *Quarterly of Applied Mathematics*, 4(1), 45-99. (B-spline theory underlying recursive SMA.)
|
||||
@@ -0,0 +1,96 @@
|
||||
# TRAMA: Trend Regularity Adaptive Moving Average
|
||||
|
||||
> "LuxAlgo counted how often price makes new highs and new lows within a window, squared that fraction, and used it as an EMA smoothing constant. Trending markets produce frequent HH/LLs and the filter tracks fast. Ranging markets produce few, and the filter stops moving. Simple, effective, elegant."
|
||||
|
||||
TRAMA is an adaptive EMA where the smoothing factor derives from the "trend regularity" of the lookback window, measured as the fraction of bars that produce either a new highest-high (HH) or a new lowest-low (LL). This fraction is squared to create a convex penalty: low regularity (ranging) produces near-zero smoothing (filter barely moves), while high regularity (trending) produces aggressive smoothing (filter tracks closely). Developed by LuxAlgo (TradingView, December 2020).
|
||||
|
||||
## Historical Context
|
||||
|
||||
TRAMA was published by LuxAlgo on TradingView in December 2020 as a novel approach to adaptive smoothing. While earlier adaptive MAs (KAMA, VIDYA, ADXVMA) derive their adaptation from efficiency ratios, standard deviations, or ADX, TRAMA uses a purely non-parametric measure: the frequency of new extremes.
|
||||
|
||||
The key insight is that trending markets are characterized by a high rate of new highest-highs and lowest-lows, while ranging markets produce new extremes only occasionally (at the range boundaries). This binary event (new extreme or not) is robust to the magnitude of price changes and immune to the scale issues that affect volatility-based adaptive methods.
|
||||
|
||||
The squaring of the trend coefficient $tc = [\text{SMA}(\text{HH or LL occurred}, N)]^2$ is critical to TRAMA's behavior. Without squaring, a market with 50% HH/LL bars (typical for a mild trend) would use $tc = 0.5$, producing moderate smoothing. With squaring, $tc = 0.25$, producing heavier smoothing. This convex penalty ensures that TRAMA switches between "tracking" and "holding" regimes more sharply than a linear adaptation would, reducing whipsaws in ambiguous market conditions.
|
||||
|
||||
## Architecture & Physics
|
||||
|
||||
### 1. Extreme Detection
|
||||
|
||||
On each bar, check whether the rolling highest-high or lowest-low (over the lookback period) has changed:
|
||||
|
||||
$$
|
||||
\text{HH} = \max\left(\text{sign}\left(\Delta\, \text{Highest}(N)\right), 0\right)
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{LL} = \max\left(\text{sign}\left(-\Delta\, \text{Lowest}(N)\right), 0\right)
|
||||
$$
|
||||
|
||||
### 2. Trend Regularity Coefficient
|
||||
|
||||
$$
|
||||
tc = \left[\text{SMA}\left(\text{HH or LL} \neq 0 \;\;?\;\; 1 : 0, \;\;N\right)\right]^2
|
||||
$$
|
||||
|
||||
This gives the squared fraction of bars with new extremes.
|
||||
|
||||
### 3. Adaptive EMA Step
|
||||
|
||||
$$
|
||||
\text{TRAMA}_t = \text{TRAMA}_{t-1} + tc \times (x_t - \text{TRAMA}_{t-1})
|
||||
$$
|
||||
|
||||
## Mathematical Foundation
|
||||
|
||||
**Extreme indicators:**
|
||||
|
||||
$$
|
||||
\text{HH}_t = \begin{cases} 1 & \text{if } \max(x_{t}, \ldots, x_{t-N+1}) > \max(x_{t-1}, \ldots, x_{t-N}) \\ 0 & \text{otherwise} \end{cases}
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{LL}_t = \begin{cases} 1 & \text{if } \min(x_{t}, \ldots, x_{t-N+1}) < \min(x_{t-1}, \ldots, x_{t-N}) \\ 0 & \text{otherwise} \end{cases}
|
||||
$$
|
||||
|
||||
**Trend coefficient (squared SMA of binary events):**
|
||||
|
||||
$$
|
||||
tc_t = \left[\frac{1}{N}\sum_{i=0}^{N-1} \mathbf{1}\left(\text{HH}_{t-i} \vee \text{LL}_{t-i}\right)\right]^2
|
||||
$$
|
||||
|
||||
**Adaptive update:**
|
||||
|
||||
$$
|
||||
\text{TRAMA}_t = \text{TRAMA}_{t-1} + tc_t \cdot (x_t - \text{TRAMA}_{t-1})
|
||||
$$
|
||||
|
||||
**Regime behavior:**
|
||||
|
||||
| Market Regime | HH/LL frequency | Raw $tc$ | Squared $tc$ | Equivalent EMA period |
|
||||
| :--- | :---: | :---: | :---: | :---: |
|
||||
| Strong trend | ~80% | 0.8 | 0.64 | ~2.6 |
|
||||
| Moderate trend | ~50% | 0.5 | 0.25 | ~7 |
|
||||
| Mild trend | ~30% | 0.3 | 0.09 | ~20 |
|
||||
| Range-bound | ~10% | 0.1 | 0.01 | ~199 |
|
||||
|
||||
**Default parameters:** `period = 14`, `minPeriod = 1`.
|
||||
|
||||
**Pseudo-code (streaming):**
|
||||
|
||||
```
|
||||
// Detect new highest-high or lowest-low
|
||||
hh = max(sign(change(highest(src, length))), 0)
|
||||
ll = max(sign(change(lowest(src, length)) * -1), 0)
|
||||
|
||||
// Trend regularity: fraction of bars with HH or LL, squared
|
||||
tc = sma((hh or ll) ? 1 : 0, length) ^ 2
|
||||
|
||||
// Adaptive EMA
|
||||
trama = trama[1] + tc * (src - trama[1])
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
- LuxAlgo (2020). "TRAMA - Trend Regularity Adaptive Moving Average." TradingView. Published December 2020.
|
||||
- Kaufman, P.J. (1995). *Smarter Trading*. McGraw-Hill. Chapter 7: Adaptive Techniques. (KAMA framework, precursor to adaptive MA design.)
|
||||
- Chande, T.S. (1997). *Beyond Technical Analysis*, 2nd ed. Wiley. (VIDYA and adaptive smoothing theory.)
|
||||
Reference in New Issue
Block a user