Skip to content

Free TradingView indicator

KAMA Trend Filter

Kaufman Adaptive Moving Average with efficiency-ratio shading that separates trending phases from choppy, no-trend markets.

Trendv1.0TradingView (Pine Script v6) Non-repainting signals Alerts

What it does

The KAMA Trend Filter plots Perry Kaufman's Adaptive Moving Average and shades the chart in three states: trending up, trending down, or no trend. KAMA speeds up when price moves efficiently in one direction and slows almost to a halt when price chops sideways, so it naturally hugs trends and flattens in ranges.

The extra filter uses the same efficiency ratio that drives KAMA to decide whether there is a trend worth following at all. That makes it useful as a "should I be using a trend strategy right now?" switch on top of other tools.

How it works

  1. Efficiency ratio (ER) = |price − price n bars ago| ÷ sum of the absolute bar-to-bar changes over n bars. ER is 1 when price moved in a straight line and near 0 when it went nowhere.
  2. Fast constant = 2 ÷ (fast period + 1), slow constant = 2 ÷ (slow period + 1).
  3. Smoothing constant = (ER × (fast − slow) + slow)², which keeps KAMA between very slow and fairly fast.
  4. KAMA = previous KAMA + smoothing constant × (price − previous KAMA).
  5. For the filter, ER is smoothed with a short SMA. If it is at or above the threshold, the market is "trending"; direction comes from KAMA's change over the slope lookback. Otherwise the state is "no trend".

State changes are confirmed on bar close. The smoothed ER is visible in the Data Window.

How to use it

  • Green background with a rising KAMA: trend-following ideas in the long direction have context. Red: the same for shorts. Grey: the market is inefficient, and breakout or trend entries tend to struggle.
  • Many traders use the no-trend state to stand aside, or to switch to range tactics such as fading resistance and support.
  • KAMA itself can act as a dynamic trailing reference in a clean trend.
  • It suits H1–D1 on majors, gold, oil and indices. Raise the threshold for noisy instruments and lower it for smooth ones. The volatility lesson explains why the same settings behave differently across markets.

Settings

InputDefaultWhat it changes
SourceclosePrice used for ER and KAMA.
Efficiency ratio length10Window for the efficiency ratio.
Fast EMA period2Fastest KAMA speed.
Slow EMA period30Slowest KAMA speed.
Trend threshold (ER)0.30Higher = fewer bars classed as trending.
ER smoothing3Steadies the filter; 1 = raw ER.
Slope lookback (bars)3Bars used to judge KAMA direction.
Shade background by stateOnBackground color by state.
Show trend-start labelsOnUp/Down labels and a cross for no-trend.

Limitations

  • The efficiency ratio is backward-looking. By the time it crosses the threshold, part of the move has already happened.
  • A single fixed threshold does not fit every market or timeframe; you will need to tune it.
  • Sharp news spikes can produce a high ER for a few bars and briefly label the market as trending.
  • The filter describes the past only and does not forecast direction or the size of the next move.

Pine Script source

In TradingView open Pine Editor, paste the code, click Save and then Add to chart.

FXP_KamaTrendFilter.pine

67 lines

// © FXPIPS ONLINE — https://fxpips.online/tradingview-indicators/kama-trend-filter/
// License: MIT. Educational tool — not financial advice. Trading involves substantial risk.
//@version=6
// Kaufman Adaptive Moving Average plus an efficiency-ratio filter that shades the chart as
// trending up, trending down or no trend. State changes are confirmed on bar close.
indicator("FXP KAMA Trend Filter", shorttitle = "FXP KAMA", overlay = true)

// ── Inputs ─────────────────────────────────────────────────────────────
grpK    = "KAMA"
src     = input.source(close, "Source", group = grpK)
erLen   = input.int(10, "Efficiency ratio length", minval = 2, group = grpK)
fastLen = input.int(2, "Fast EMA period", minval = 1, group = grpK)
slowLen = input.int(30, "Slow EMA period", minval = 2, group = grpK)

grpF        = "Trend filter"
erThreshold = input.float(0.30, "Trend threshold (ER)", minval = 0.0, maxval = 1.0, step = 0.01, group = grpF, tooltip = "Smoothed efficiency ratio at or above this value counts as trending.")
erSmooth    = input.int(3, "ER smoothing", minval = 1, group = grpF)
slopeBars   = input.int(3, "Slope lookback (bars)", minval = 1, group = grpF)

grpV        = "Display"
showBg      = input.bool(true, "Shade background by state", group = grpV)
showSignals = input.bool(true, "Show trend-start labels", group = grpV)
colBull     = input.color(#26a69a, "Uptrend color", group = grpV)
colBear     = input.color(#ef5350, "Downtrend color", group = grpV)
colFlat     = input.color(#9e9e9e, "No-trend color", group = grpV)
bgTransp    = input.int(88, "Background transparency", minval = 0, maxval = 100, group = grpV)

// ── Efficiency ratio ───────────────────────────────────────────────────
direction  = math.abs(src - src[erLen])
noise      = math.sum(math.abs(src - src[1]), erLen)
erRaw      = nz(noise > 0 ? direction / noise : 0.0)
erSmoothed = ta.sma(erRaw, erSmooth)

// ── KAMA ───────────────────────────────────────────────────────────────
fastSc = 2.0 / (fastLen + 1)
slowSc = 2.0 / (slowLen + 1)
sc     = math.pow(erRaw * (fastSc - slowSc) + slowSc, 2)

var float kama = na
kama := na(kama) ? src : kama + sc * (src - kama)

// ── Trend state: 1 up, -1 down, 0 no trend ─────────────────────────────
kamaSlope = kama - kama[slopeBars]
trending  = erSmoothed >= erThreshold
int state = trending and kamaSlope > 0 ? 1 : trending and kamaSlope < 0 ? -1 : 0
prevState = nz(state[1])

bullStart = state == 1 and prevState != 1 and barstate.isconfirmed
bearStart = state == -1 and prevState != -1 and barstate.isconfirmed
flatStart = state == 0 and prevState != 0 and barstate.isconfirmed

stateColor = state == 1 ? colBull : state == -1 ? colBear : colFlat

// ── Plots ──────────────────────────────────────────────────────────────
plot(kama, "KAMA", color = stateColor, linewidth = 2)
plot(erSmoothed, "Efficiency ratio", display = display.data_window)
bgcolor(showBg ? color.new(stateColor, bgTransp) : na, title = "Trend state background")

plotshape(showSignals and bullStart, "Uptrend start", style = shape.labelup, location = location.belowbar, color = colBull, text = "Up", textcolor = color.white, size = size.small)
plotshape(showSignals and bearStart, "Downtrend start", style = shape.labeldown, location = location.abovebar, color = colBear, text = "Down", textcolor = color.white, size = size.small)
plotshape(showSignals and flatStart, "No-trend start", style = shape.xcross, location = location.abovebar, color = colFlat, size = size.tiny)

// ── Alerts ─────────────────────────────────────────────────────────────
alertcondition(bullStart, "KAMA uptrend start", "KAMA filter switched to uptrend on {{ticker}} ({{interval}})")
alertcondition(bearStart, "KAMA downtrend start", "KAMA filter switched to downtrend on {{ticker}} ({{interval}})")
alertcondition(flatStart, "KAMA no-trend start", "KAMA filter switched to no-trend on {{ticker}} ({{interval}})")

Key inputs

Key inputs of KAMA Trend Filter
InputDefaultDescription
Efficiency ratio length10Bars used to measure how directional price movement is.
Fast EMA period2Speed KAMA approaches when the market trends cleanly.
Slow EMA period30Speed KAMA falls back to when the market is noisy.
Trend threshold (ER)0.30Smoothed efficiency ratio needed to call the market trending.
ER smoothing3Simple moving average applied to the efficiency ratio for the filter.
Slope lookback (bars)3Bars over which the KAMA slope sets trend direction.

Educational tools, not advice. Indicators and Expert Advisors describe price; they do not predict it, and past behaviour does not guarantee future results. Test everything on a demo account first and never risk money you cannot afford to lose. See our disclaimer.

Keep exploring

Related tradingview indicators