What is Kaufman’s Adaptive Moving Average (KAMA)?
Kaufman's Adaptive Moving Average (KAMA), developed by Perry Kaufman, is a sophisticated moving average that dynamically adjusts its smoothing period based on market volatility. Unlike traditional moving averages (like SMA or EMA) that use a fixed period, KAMA becomes more responsive when the market is trending (high volatility) and less responsive (more smoothed) when the market is ranging or choppy (low volatility). This unique adaptability allows KAMA to filter out noise effectively in sideways markets while remaining sensitive enough to capture real trend changes.
Components and Calculation
The core of KAMA's adaptability lies in its Efficiency Ratio (ER) and Smoothing Constant (SC).
- Change (Directional Movement): Measures the absolute price change over a specified KAMA length: `abs(close - close[length])`.
- Volatility (Total Movement): Measures the sum of absolute price changes over the same KAMA length: `sum(abs(close - close[1]), length)`.
- Efficiency Ratio (ER): `Change / Volatility`. This ratio varies between 0 and 1. An ER close to 1 indicates a strong trend (efficient movement), while an ER close to 0 indicates a choppy or ranging market (inefficient movement).
- Smoothing Constant (SC): `(ER * (fastestSC - slowestSC) + slowestSC)^2`. This formula converts the ER into a smoothing factor that adapts between a "fast" smoothing period (when ER is high) and a "slow" smoothing period (when ER is low).
- KAMA Calculation: KAMA is calculated recursively, similar to an EMA, but using the adaptive smoothing constant: `KAMA = KAMA[1] + SC * (price - KAMA[1])`.
The `fastestSC` and `slowestSC` are derived from short and long EMA lengths (e.g., 2 and 30 periods, respectively), which define the boundaries of KAMA's responsiveness.
Basic KAMA Implementation in Pine Script
Pine Script v5 provides a convenient built-in function `ta.kama()` for straightforward implementation.
//@version=5
indicator("My KAMA Indicator", overlay=true)
// Inputs for KAMA parameters
length = input.int(10, title="KAMA Length")
fastestLength = input.int(2, title="Fastest EMA Length")
slowestLength = input.int(30, title="Slowest EMA Length")
// Calculate KAMA using the built-in function
kamaValue = ta.kama(close, length, fastestLength, slowestLength)
// Plot the KAMA line
plot(kamaValue, title="KAMA", color=color.blue, linewidth=2)
Practical KAMA Strategies
1. KAMA as a Trend Filter / Trend Following
KAMA's ability to hug price during trends and flatten during choppy periods makes it an excellent trend filter. When price is consistently above KAMA, it indicates an uptrend. When consistently below, it indicates a downtrend.
//@version=5
strategy("KAMA Trend Filter Strategy", overlay=true)
// Inputs for KAMA
length = input.int(10, title="KAMA Length")
fastestLength = input.int(2, title="Fastest EMA Length")
slowestLength = input.int(30, title="Slowest EMA Length")
// Calculate KAMA
kamaValue = ta.kama(close, length, fastestLength, slowestLength)
// Plot KAMA
plot(kamaValue, title="KAMA", color=color.blue, linewidth=2)
// Trend conditions
uptrend = close > kamaValue
downtrend = close < kamaValue
// Highlight background based on trend
bgcolor(uptrend ? color.new(color.green, 90) : na)
bgcolor(downtrend ? color.new(color.red, 90) : na)
// Example entry logic: buy on crossover above KAMA, sell on crossunder below KAMA
longCondition = ta.crossover(close, kamaValue)
shortCondition = ta.crossunder(close, kamaValue)
if (longCondition)
strategy.entry("Long", strategy.long)
if (shortCondition)
strategy.entry("Short", strategy.short)
2. KAMA Crossover with another MA (e.g., SMA)
Combining KAMA with another moving average can generate powerful crossover signals, benefiting from KAMA's adaptive smoothing.
//@version=5
strategy("KAMA & SMA Crossover", overlay=true)
// KAMA Inputs
kamaLength = input.int(10, title="KAMA Length")
fastestLength = input.int(2, title="Fastest EMA Length")
slowestLength = input.int(30, title="Slowest EMA Length")
// SMA Input
smaLength = input.int(50, title="SMA Length")
// Calculate KAMA and SMA
kama = ta.kama(close, kamaLength, fastestLength, slowestLength)
sma = ta.sma(close, smaLength)
// Plot lines
plot(kama, title="KAMA", color=color.blue, linewidth=2)
plot(sma, title="SMA", color=color.orange, linewidth=2)
// Crossover conditions
longCondition = ta.crossover(kama, sma)
shortCondition = ta.crossunder(kama, sma)
// Strategy entries
if (longCondition)
strategy.entry("Long", strategy.long)
if (shortCondition)
strategy.entry("Short", strategy.short)
3. KAMA-Based Divergence
While KAMA is primarily a trend-following indicator, divergences between KAMA and price can sometimes signal potential trend exhaustion or reversals.
- Bullish Divergence: Price makes a lower low, but KAMA makes a higher low.
- Bearish Divergence: Price makes a higher high, but KAMA makes a lower high.
//@version=5
indicator("KAMA Divergence", overlay=true)
length = input.int(10, title="KAMA Length")
fastestLength = input.int(2, title="Fastest EMA Length")
slowestLength = input.int(30, title="Slowest EMA Length")
kamaValue = ta.kama(close, length, fastestLength, slowestLength)
plot(kamaValue, title="KAMA", color=color.blue, linewidth=2)
// Highlight divergence (simplified example, robust divergence detection is complex)
// This example is conceptual and requires robust peak/trough detection for practical use.
bullishDiv = kamaValue > kamaValue[1] and kamaValue[1] > kamaValue[2] and close < close[1] and close[1] < close[2]
bearishDiv = kamaValue < kamaValue[1] and kamaValue[1] < kamaValue[2] and close > close[1] and close[1] > close[2]
plotshape(bullishDiv, title="Bullish Divergence", location=location.belowbar, color=color.green, style=shape.triangleup, size=size.small)
plotshape(bearishDiv, title="Bearish Divergence", location=location.abovebar, color=color.red, style=shape.triangledown, size=size.small)
alertcondition(bullishDiv, "KAMA Bullish Divergence", "Potential bullish reversal based on KAMA divergence.")
alertcondition(bearishDiv, "KAMA Bearish Divergence", "Potential bearish reversal based on KAMA divergence.")
Optimizing KAMA Performance
To get the most from KAMA in Pine Script:
- Parameter Tuning: Experiment with `length`, `fastestLength`, and `slowestLength`. A longer `length` makes KAMA smoother overall. Adjusting `fastestLength` and `slowestLength` controls its range of adaptability.
- Multi-Timeframe Analysis: Use KAMA on higher timeframes to confirm the underlying trend, and on lower timeframes for precise entries and exits.
- Combine with Volume: Strong trends confirmed by high volume alongside KAMA signals can increase reliability.
- Confluence with Support/Resistance: KAMA often acts as dynamic support or resistance. Signals that occur at these levels are typically more powerful.
Common KAMA Pitfalls
- Lag during Sudden Reversals: While adaptive, KAMA still lags price like all moving averages. In very sharp and sudden reversals, it might be slow to react.
- Complex Calculation: Although Pine Script provides `ta.kama()`, understanding the underlying ER and SC calculations is important for advanced tuning and avoiding misinterpretations.
- Over-Optimization: As with any indicator, over-optimizing KAMA's parameters to past data can lead to poor performance in live market conditions.
- Not a Standalone Indicator: KAMA provides excellent trend identification and smoothing, but it should ideally be combined with other indicators (e.g., volume, oscillators) for entry/exit confirmation and overall market context.
Conclusion
Kaufman's Adaptive Moving Average (KAMA) is a powerful and intelligent indicator in Pine Script for TradingView. Its unique ability to adjust its smoothing based on market efficiency helps traders filter out noise and stay in tune with prevailing trends more effectively than traditional moving averages. By understanding its adaptive mechanism and incorporating it thoughtfully into your multi-indicator strategies, KAMA can be an invaluable tool for refining your trend analysis and improving your trading decisions.