Smoothed Moving Average (SMMA)
I. What is SMMA
The Smoothed Moving Average (SMMA) is a special type of moving average that achieves an extremely high degree of smoothness by blending the previous period’s moving average value with the current price. It is also known as RMA (Running Moving Average) or Wilder’s Smoothing, because J. Welles Wilder extensively used this smoothing method in his classic 1978 book New Concepts in Technical Trading Systems.
Historical Background
J. Welles Wilder is one of the most influential figures in the field of technical analysis, having invented RSI, ATR, ADX, Parabolic SAR, and many other classic indicators. When computing these indicators, Wilder consistently used a special smoothing method — SMMA. In the 1970s, when computing power was limited, SMMA’s concise recursive formula was ideal for manual calculation and early spreadsheets.
Indicator Classification
- Type: Overlay indicator, plotted on the price chart
- Category: Moving Averages
- Default Parameters: Period , data source is closing price (Close)
SMMA(n) is mathematically equivalent to EMA(2n - 1). That is, a 14-period SMMA equals a 27-period EMA. Understanding this equivalence is critical for correctly replicating Wilder’s indicators.
II. Mathematical Principles and Calculation
Core Formula
The recursive formula for SMMA is:
Equivalent form:
The initial value uses the simple moving average of the first periods:
Mathematical Relationship with EMA
EMA’s formula is , where .
Rewriting SMMA’s formula in a similar form:
Therefore SMMA’s effective smoothing factor is .
Setting (where is the equivalent EMA period) and solving:
Thus SMMA(14) = EMA(27) and SMMA(20) = EMA(39).
Weight Decay
SMMA’s historical weight decay rate is . The weight of the price periods ago is:
Since is smaller than EMA’s , SMMA’s weight decay is slower and historical data influence persists longer.
Wilder chose over in 1978 for practical reasons:
- is easier to compute mentally than
- Slower decay produces smoother curves, reducing noise in oscillators like RSI
- In the era of manual calculation, simplicity was paramount
III. Python Implementation
import numpy as np
import pandas as pd
def smma(close: pd.Series, period: int = 20) -> pd.Series:
"""
Calculate the Smoothed Moving Average (SMMA / RMA / Wilder's Smoothing)
Parameters
----------
close : pd.Series
Closing price series
period : int
Calculation period, default is 20
Returns
-------
pd.Series
SMMA value series
"""
# Method 1: Using the SMMA(n) = EMA(2n-1) equivalence
# return close.ewm(span=2*period-1, adjust=False).mean()
# Method 2: Direct recursive implementation (more faithful to Wilder's original definition)
result = pd.Series(np.nan, index=close.index)
# Initial value is SMA of first 'period' data points
result.iloc[period - 1] = close.iloc[:period].mean()
# Recursive calculation
for i in range(period, len(close)):
result.iloc[i] = (result.iloc[i - 1] * (period - 1) + close.iloc[i]) / period
return result
def smma_numpy(close: np.ndarray, period: int = 20) -> np.ndarray:
"""
SMMA implementation using numpy (high-performance version)
"""
n = len(close)
result = np.full(n, np.nan)
if n < period:
return result
result[period - 1] = np.mean(close[:period])
alpha = 1.0 / period
for i in range(period, n):
result[i] = result[i - 1] + alpha * (close[i] - result[i - 1])
return result
# ========== Usage Example ==========
if __name__ == "__main__":
np.random.seed(42)
dates = pd.date_range("2024-01-01", periods=120, freq="D")
price = 100 + np.cumsum(np.random.randn(120) * 0.5)
df = pd.DataFrame({
"date": dates,
"open": price + np.random.randn(120) * 0.2,
"high": price + np.abs(np.random.randn(120) * 0.5),
"low": price - np.abs(np.random.randn(120) * 0.5),
"close": price,
"volume": np.random.randint(1000, 10000, size=120),
})
df.set_index("date", inplace=True)
# SMMA compared with EMA/SMA
df["SMA_14"] = df["close"].rolling(14).mean()
df["EMA_14"] = df["close"].ewm(span=14, adjust=False).mean()
df["SMMA_14"] = smma(df["close"], period=14)
df["EMA_27"] = df["close"].ewm(span=27, adjust=False).mean() # Equivalence check
print("=== SMMA(14) vs EMA(14) vs EMA(27) Comparison ===")
print(df[["close", "SMA_14", "EMA_14", "SMMA_14", "EMA_27"]].tail(10))
print("\nNote: SMMA(14) and EMA(27) values are very close (except for initialization differences)")
# SMMA application in RSI calculation
delta = df["close"].diff()
gain = delta.where(delta > 0, 0.0)
loss = (-delta).where(delta < 0, 0.0)
avg_gain = smma(gain, period=14)
avg_loss = smma(loss, period=14)
rs = avg_gain / avg_loss
rsi = 100 - (100 / (1 + rs))
df["RSI_14"] = rsi
print("\n=== RSI(14) Calculated Using SMMA ===")
print(df[["close", "RSI_14"]].tail(10))
IV. Problems the Indicator Solves
1. Core Smoothing Engine for Wilder’s Indicators
SMMA’s most important application is not as a standalone moving average, but as the internal smoothing component of the following classic indicators:
| Indicator | Role of SMMA |
|---|---|
| RSI | Smoothing average gain and average loss |
| ATR | Smoothing the True Range |
| ADX | Smoothing the directional movement index |
| Parabolic SAR | Internal smoothing step in the calculation |
When replicating Wilder’s indicators such as RSI and ATR, you must use SMMA () rather than standard EMA (). Using the wrong smoothing method will cause systematic deviation from standard values.
2. Ultra-Smooth Long-Term Trend Line
Because SMMA decays more slowly than EMA, it produces a smoother curve, making it suitable as a long-term trend reference line. SMMA(20) has smoothness comparable to EMA(39) or SMA(39).
3. Reducing Trading Noise
In ranging markets, SMMA’s ultra-smooth characteristics produce fewer crossover signals than EMA, helping to reduce overtrading.
4. Dynamic Support / Resistance
SMMA’s extremely high smoothness makes it an excellent dynamic support/resistance level. Since the curve changes slowly, price interactions with SMMA are more regular.
V. Advantages, Disadvantages, and Use Cases
Advantages
| Advantage | Description |
|---|---|
| Extremely high smoothness | Smoother than same-period EMA; strong noise filtering capability |
| Standard component | The standard smoothing method for classic indicators like RSI, ATR, and ADX |
| Efficient recursion | recursive update; very computationally efficient |
| Long track record | Validated through decades of market use |
Disadvantages
| Disadvantage | Description |
|---|---|
| High lag | SMMA(n) lag is close to EMA(2n-1); much slower than same-period EMA |
| Sluggish response | Responds very slowly to short-term price changes |
| Confusion risk | The distinction from EMA is often overlooked, leading to calculation errors |
| Rarely used independently | Seldom used as a standalone trading indicator |
Use Cases
- Internal indicator component: Must be used when calculating RSI, ATR, and ADX
- Long-term trend assessment: As an ultra-smooth long-term trend reference line
- Low-frequency trading: Suitable for investors who prefer infrequent trading
SMMA vs EMA Comparison
| Feature | SMMA(14) | EMA(14) | EMA(27) |
|---|---|---|---|
| Smoothing factor | 0.0714 | 0.1333 | 0.0714 |
| Smoothness | High | Medium | High |
| Lag | High | Medium | High |
| Equivalence | = EMA(27) | - | = SMMA(14) |
- The key to understanding SMMA is mastering the equivalence SMMA(n) = EMA(2n-1).
- When replicating Wilder’s indicators in Python, you can use
ewm(span=2*n-1)to quickly achieve the SMMA effect. - If a platform’s RSI uses EMA instead of SMMA, the results will differ from the classic RSI. Always confirm the smoothing method in quantitative research.