Triple Exponential Moving Average (TEMA)
I. What is TEMA
The Triple Exponential Moving Average (TEMA) is a further extension of DEMA that achieves even lower lag than DEMA through a mathematical combination of three layers of EMA. It was also proposed by Patrick Mulloy in the same 1994 article published in Technical Analysis of Stocks & Commodities magazine.
Historical Background
While designing DEMA, Mulloy found that although the two-layer EMA combination significantly reduced lag, it did not completely eliminate it. He extended the method to a three-layer EMA combination, producing TEMA. In theory, TEMA nearly eliminates the lag of traditional EMA, at the cost of increased sensitivity to market noise and potential overshoot during sharp price changes.
Indicator Classification
- Type: Overlay indicator, plotted on the price chart
- Category: Moving Averages
- Default Parameters: Period , data source is closing price (Close)
DEMA uses a two-layer EMA combination to eliminate first-order lag. TEMA uses a three-layer EMA combination to eliminate both first-order and second-order lag. From SMA to EMA to DEMA to TEMA, lag progressively decreases while sensitivity progressively increases.
II. Mathematical Principles and Calculation
Core Formula
TEMA is calculated in four steps:
Step 1: Calculate the EMA of price
Step 2: Apply EMA to
Step 3: Apply EMA to
Step 4: Combine to get TEMA
Mathematical Derivation
Assuming the lag operator introduced by EMA is , and the original price is :
- (lag )
- (lag )
- (lag )
Substituting into the TEMA formula:
That is, first-order lag is theoretically completely eliminated. However, in practice, higher-order lag terms and nonlinear effects mean TEMA retains a very small residual lag.
Equivalent Interpretation
The TEMA formula can be rewritten as:
Where:
- : Base EMA
- : First-order correction term (already present in DEMA)
- : Second-order correction term (new in TEMA)
TEMA’s extremely low lag means that during sharp price changes, the indicator value may temporarily exceed the actual price (overshoot) before reverting. This almost never occurs with SMA or EMA. Be aware of this characteristic when using TEMA.
III. Python Implementation
import numpy as np
import pandas as pd
def ema(close: pd.Series, period: int) -> pd.Series:
"""Calculate EMA"""
return close.ewm(span=period, adjust=False).mean()
def tema(close: pd.Series, period: int = 20) -> pd.Series:
"""
Calculate the Triple Exponential Moving Average (TEMA)
Parameters
----------
close : pd.Series
Closing price series
period : int
Calculation period, default is 20
Returns
-------
pd.Series
TEMA value series
"""
ema1 = ema(close, period)
ema2 = ema(ema1, period)
ema3 = ema(ema2, period)
return 3 * ema1 - 3 * ema2 + ema3
def tema_numpy(close: np.ndarray, period: int = 20) -> np.ndarray:
"""
Manual TEMA implementation using numpy
"""
alpha = 2.0 / (period + 1)
n = len(close)
def _ema_array(src: np.ndarray, start_idx: int) -> np.ndarray:
"""Calculate EMA for src starting from start_idx"""
result = np.full(n, np.nan)
valid = src[~np.isnan(src)]
if len(valid) < period:
return result
first_valid = np.where(~np.isnan(src))[0][0]
init_end = first_valid + period
if init_end > n:
return result
result[init_end - 1] = np.mean(src[first_valid:init_end])
for i in range(init_end, n):
if not np.isnan(src[i]):
result[i] = alpha * src[i] + (1 - alpha) * result[i - 1]
return result
ema1 = _ema_array(close, 0)
ema2 = _ema_array(ema1, period - 1)
ema3 = _ema_array(ema2, 2 * (period - 1))
return 3 * ema1 - 3 * ema2 + ema3
# ========== Usage Example ==========
if __name__ == "__main__":
np.random.seed(42)
dates = pd.date_range("2024-01-01", periods=150, freq="D")
price = 100 + np.cumsum(np.random.randn(150) * 0.8)
df = pd.DataFrame({
"date": dates,
"open": price + np.random.randn(150) * 0.3,
"high": price + np.abs(np.random.randn(150) * 0.6),
"low": price - np.abs(np.random.randn(150) * 0.6),
"close": price,
"volume": np.random.randint(1000, 10000, size=150),
})
df.set_index("date", inplace=True)
# Compare multiple moving averages
df["SMA_20"] = df["close"].rolling(20).mean()
df["EMA_20"] = ema(df["close"], 20)
df["DEMA_20"] = 2 * ema(df["close"], 20) - ema(ema(df["close"], 20), 20)
df["TEMA_20"] = tema(df["close"], 20)
print("=== Four Moving Averages Comparison (last 10 rows) ===")
print(df[["close", "SMA_20", "EMA_20", "DEMA_20", "TEMA_20"]].tail(10))
# TEMA trend signal
df["tema_slope"] = df["TEMA_20"].diff()
df["trend"] = np.where(df["tema_slope"] > 0, "UP",
np.where(df["tema_slope"] < 0, "DOWN", "FLAT"))
print("\n=== TEMA Slope Trend Signal ===")
print(df[["close", "TEMA_20", "tema_slope", "trend"]].tail(10))
IV. Problems the Indicator Solves
1. Extremely Low-Lag Trend Detection
TEMA nearly eliminates first-order lag, making it the lowest-lag indicator among all EMA-based moving averages. In trending markets, TEMA can provide the earliest directional signal.
2. Rapid Reversal Detection
Because TEMA closely tracks price movement, when a trend reverses, the change in TEMA’s direction (slope) is the fastest. Traders can watch for sign changes in TEMA’s slope to identify reversal points.
3. EMA Replacement for Improved Strategy Performance
In any strategy that uses EMA, TEMA can serve as a low-lag substitute:
- TEMA crossover strategies
- TEMA-based MACD variants
- TEMA as a trend filter
4. High-Frequency and Short-Term Trading
TEMA’s fast response makes it particularly suited for intraday and high-frequency strategies, where every moment of lag can translate to significant profit differences.
A unique use of TEMA is to directly observe its slope (first derivative) rather than price-to-TEMA crossovers. Going long when TEMA slope turns from negative to positive, and short when it turns from positive to negative, produces signals that are even more leading than crossover signals.
V. Advantages, Disadvantages, and Use Cases
Advantages
| Advantage | Description |
|---|---|
| Minimal lag | Lowest lag among all EMA-based moving averages |
| Trend sensitive | Fastest response to trend changes |
| Elegant formula | A concise linear combination based on EMA |
| Universal substitute | Can replace EMA in any indicator system |
Disadvantages
| Disadvantage | Description |
|---|---|
| Notable overshoot | May exceed actual price during sharp price changes |
| Extremely noise sensitive | Overreacts to short-term fluctuations; many false signals in ranging markets |
| Longest startup period | Requires initialization data for three layers of EMA |
| Less smooth curve | Compared to SMA and EMA, TEMA’s curve is more jagged |
Use Cases
- Strong trending markets: The stronger the trend, the more pronounced TEMA’s low-lag advantage
- Short-term and intraday trading: Scenarios requiring extremely fast signal response
- Post-confirmation entry: Use TEMA for precise entry after confirming a trend with indicators like ADX
Moving Average Family Lag Ranking
TEMA has the lowest lag but the highest noise sensitivity. The choice of moving average depends on the trader’s preference for the trade-off between “lag” and “smoothness.”
- TEMA is not suitable for standalone use in ranging markets; it must be paired with a trend filter.
- If backtesting reveals that a TEMA strategy trades too frequently, the market may lack a clear trend — consider pausing trading or switching to longer-period parameters.
- Before live trading, thoroughly backtest and compare TEMA vs EMA/DEMA strategies across different market conditions.