Files
QuanTAlib/lib/trends_IIR/tema/tema.pine
T
Miha Kralj 24e86d762a Add documentation links for various volatility indicators and channels
- Updated BBWN, BBWP, CCV, CV, CVI, EWMA, GKV, HLV, HV, Jvolty, JVOLTYN, MASSI, NATR, RSV, RV, RVI, TR, UI, VOV, VR, YZV indicators with documentation links.
- Added documentation links for Aberration, Acceleration Bands, Andrews' Pitchfork, Adaptive Price Zone, ATR Bands, Bollinger Bands, Center of Gravity, Donchian Channels, Decay Min-Max Channel, Detrended Synthetic Price, EACP, EBSW, HOMOD, Jurik Volatility Bands, Keltner Channel, MA Envelope, Min-Max Channel, Price Channel, Regression Channels, Standard Deviation Channel, Stoller Average Range Channel, Super Trend Bands, Ultimate Bands, Ultimate Channel, VWAP Bands, and VWAP with Standard Deviation Bands.
2026-02-18 11:55:48 -08:00

66 lines
2.2 KiB
Plaintext

// The MIT License (MIT)
// © mihakralj
//@version=6
indicator("Triple Exponential Moving Average (TEMA)", "TEMA", overlay=true)
//@function Calculates TEMA using triple exponential smoothing with compensator
//@param source Series to calculate TEMA from
//@param period Lookback period for TEMA calculation
//@param alpha Optional smoothing factor (overrides period if provided)
//@param corrected Use diminishing alpha factors for each stage
//@returns TEMA value from first bar with proper compensation
//@optimized Uses exponential warmup compensator on all three EMA stages for O(1) complexity
tema(series float source, simple int period=0, simple float alpha=0.0, simple bool corrected=false) =>
if alpha <= 0 and period <= 0
runtime.error("Alpha or period must be provided")
float a1 = alpha > 0 ? alpha : (period > 0 ? 2.0 / (period + 1) : 0.1)
float r = math.pow(1.0 / a1, 1.0 / 3.0)
float a2 = corrected ? a1 * r : a1
float a3 = corrected ? a2 * r : a1
float beta1 = 1.0 - a1
float beta2 = 1.0 - a2
float beta3 = 1.0 - a3
var float e1 = 1.0
var float e2 = 1.0
var float e3 = 1.0
var bool warmup = true
var float rema1 = 0.0
var float rema2 = 0.0
var float rema3 = 0.0
var float ema1 = source
var float ema2 = source
var float ema3 = source
rema1 := a1 * (source - rema1) + rema1
if warmup
e1 *= beta1
e2 *= beta2
e3 *= beta3
float c1 = 1.0 / (1.0 - e1)
float c2 = 1.0 / (1.0 - e2)
float c3 = 1.0 / (1.0 - e3)
ema1 := rema1 * c1
rema2 := a2 * (ema1 - rema2) + rema2
ema2 := rema2 * c2
rema3 := a3 * (ema2 - rema3) + rema3
ema3 := rema3 * c3
warmup := e1 > 1e-10
else
ema1 := rema1
rema2 := a2 * (ema1 - rema2) + rema2
ema2 := rema2
rema3 := a3 * (ema2 - rema3) + rema3
ema3 := rema3
3 * ema1 - 3 * ema2 + ema3
// ---------- Main loop ----------
// Inputs
i_period = input.int(10, "Period", minval=1)
i_source = input.source(close, "Source")
// Calculation
tema_value = tema(i_source, period=i_period)
// Plot
plot(tema_value, "TEMA", color=color.yellow, linewidth=2)