mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-18 10:38:05 +00:00
61 lines
2.0 KiB
Plaintext
61 lines
2.0 KiB
Plaintext
// The MIT License (MIT)
|
||
// © mihakralj
|
||
//@version=6
|
||
indicator("Linear Trend Moving Average (LTMA)", "LTMA", overlay=true)
|
||
|
||
//@function Calculates Linear Trend MA using dual EMA with linear extrapolation
|
||
//@param source Series to smooth
|
||
//@param period Lookback period (determines alpha = 2/(period+1))
|
||
//@returns LTMA value: EMA-based linear trend projection from first bar
|
||
//@description LTMA tracks both level and slope using two cascaded EMAs,
|
||
// then extrapolates the linear trend forward. Unlike DEMA (which cancels
|
||
// first-order lag via 2×EMA1 − EMA2), LTMA estimates the instantaneous
|
||
// slope from the EMA difference and projects it forward by the full period:
|
||
// slope = (EMA1 − EMA2) / (decay − 1)
|
||
// LTMA = EMA1 + slope × period
|
||
// where decay = (1 − alpha). This produces a predictive moving average
|
||
// that follows linear trends with zero steady-state error.
|
||
// Uses §2 exponential warmup compensator on both EMAs (e*=beta,
|
||
// c=1/(1-e)) for valid output from bar 1.
|
||
ltma(series float source, simple int period) =>
|
||
if period <= 0
|
||
runtime.error("Period must be greater than 0")
|
||
float alpha = 2.0 / (period + 1)
|
||
float beta = 1.0 - alpha
|
||
|
||
var bool warmup = true
|
||
var float e = 1.0
|
||
var float ema1 = 0.0
|
||
var float ema2 = 0.0
|
||
var float result = source
|
||
|
||
float src = nz(source)
|
||
|
||
ema1 := alpha * (src - ema1) + ema1
|
||
ema2 := alpha * (ema1 - ema2) + ema2
|
||
|
||
if warmup
|
||
e *= beta
|
||
float c = 1.0 / (1.0 - e)
|
||
float comp1 = c * ema1
|
||
float comp2 = c * ema2
|
||
float slope = comp1 - comp2
|
||
result := comp1 + slope * period
|
||
warmup := e > 1e-10
|
||
else
|
||
float slope = ema1 - ema2
|
||
result := ema1 + slope * period
|
||
result
|
||
|
||
// ---------- Main loop ----------
|
||
|
||
// Inputs
|
||
i_period = input.int(14, "Period", minval=1)
|
||
i_source = input.source(close, "Source")
|
||
|
||
// Calculation
|
||
ltma_value = ltma(i_source, period=i_period)
|
||
|
||
// Plot
|
||
plot(ltma_value, "LTMA", color=color.yellow, linewidth=2)
|