feat: add new indicators (Decay, Edecay, MinusDi, MinusDm, PlusDi, PlusDm, Maxindex, Minindex, Sarext) and update pine scripts, core libs, validation tests, and python bindings
2026-03-09 13:45:46 -07:00
|
|
|
|
// Licensed under the Apache License, Version 2.0
|
2026-02-20 18:44:56 -08:00
|
|
|
|
// © mihakralj
|
|
|
|
|
|
//@version=6
|
|
|
|
|
|
indicator("Linear Trend Moving Average (LTMA)", "LTMA", overlay=true)
|
|
|
|
|
|
|
2026-02-23 17:27:35 -08:00
|
|
|
|
//@function Calculates LTMA using dual cascaded EMAs with linear trend extrapolation
|
2026-02-20 18:44:56 -08:00
|
|
|
|
//@param source Series to smooth
|
|
|
|
|
|
//@param period Lookback period (determines alpha = 2/(period+1))
|
2026-02-23 17:27:35 -08:00
|
|
|
|
//@returns LTMA value: lag-corrected EMA (equivalent to DEMA = 2·EMA1 − EMA2)
|
|
|
|
|
|
//@description Removes the EMA lag by estimating the per-bar slope from the spread
|
|
|
|
|
|
// between two cascaded EMAs and projecting forward by exactly one lag interval.
|
|
|
|
|
|
// EMA1 lags by τ = (1−α)/α bars; EMA1−EMA2 ≈ slope·τ; result = EMA1 + (EMA1−EMA2).
|
|
|
|
|
|
// Initializing both EMAs to source on bar 1 gives zero warmup bias with no compensator needed.
|
2026-02-20 18:44:56 -08:00
|
|
|
|
ltma(series float source, simple int period) =>
|
|
|
|
|
|
float alpha = 2.0 / (period + 1)
|
|
|
|
|
|
float beta = 1.0 - alpha
|
|
|
|
|
|
|
2026-02-23 17:27:35 -08:00
|
|
|
|
var float ema1 = na
|
|
|
|
|
|
var float ema2 = na
|
2026-02-20 18:44:56 -08:00
|
|
|
|
|
|
|
|
|
|
float src = nz(source)
|
|
|
|
|
|
|
2026-02-23 17:27:35 -08:00
|
|
|
|
if na(ema1)
|
|
|
|
|
|
ema1 := src
|
|
|
|
|
|
ema2 := src
|
2026-02-20 18:44:56 -08:00
|
|
|
|
else
|
2026-02-23 17:27:35 -08:00
|
|
|
|
ema1 := alpha * src + beta * ema1
|
|
|
|
|
|
ema2 := alpha * ema1 + beta * ema2
|
|
|
|
|
|
|
|
|
|
|
|
// slope = EMA1 − EMA2 ≈ slope_per_bar × lag
|
|
|
|
|
|
// result = EMA1 + slope × 1.0 → 2·EMA1 − EMA2
|
|
|
|
|
|
ema1 + (ema1 - ema2)
|
2026-02-20 18:44:56 -08:00
|
|
|
|
|
|
|
|
|
|
// ---------- Main loop ----------
|
|
|
|
|
|
|
|
|
|
|
|
i_period = input.int(14, "Period", minval=1)
|
|
|
|
|
|
i_source = input.source(close, "Source")
|
|
|
|
|
|
|
|
|
|
|
|
ltma_value = ltma(i_source, period=i_period)
|
|
|
|
|
|
|
2026-02-23 17:27:35 -08:00
|
|
|
|
plot(ltma_value, "LTMA", color=color.yellow, linewidth=2)
|