TradingView indicators

KAMA indicator · Pine Script v6

Kaufman Adaptive Moving Average on TradingView

KAMA changes how much weight it gives the latest price by comparing net movement with the total distance price traveled. Directional movement produces a faster response; repeated reversals produce a slower response. The final smoothing coefficient is squared, which matters when comparing KAMA with an EMA.

Use this page to check the formula, reproduce a small example and inspect a working script. The example defines its initialization and flat-window behavior explicitly; these choices can explain differences between implementations.

The KAMA formula, including the square

For source P and lookback N, calculate direction D and total movement V from N adjacent differences. Interpolate between the fast and slow EMA coefficients, square the result, then update the previous KAMA. This follows TradingView's KAMA calculation.

D = abs(P[t] - P[t-N])
V = sum(abs(P[t-i] - P[t-i-1]), i = 0 ... N-1)
ER = D / V
fast = 2 / (fastLength + 1)
slow = 2 / (slowLength + 1)
SC = (ER * (fast - slow) + slow)^2
KAMA[t] = KAMA[t-1] + SC * (P[t] - KAMA[t-1])

N changes require N+1 source values. Summing signed changes would cancel reversals and make the denominator equal the net move; that destroys the comparison. ER is between 0 and 1 for a complete finite window with nonzero V. It measures path efficiency, not bullish direction or the probability of a profitable trade.

Fast 2 and slow 30 are inputs before squaring

Direct substitution gives SC=0.444444 at ER=1, SC=0.133657 at ER=0.5, and SC=0.004162 at ER=0. These are about 44.44%, 13.37% and 0.42% weights on the current price. Solving L=2/SC-1 gives fixed-coefficient EMA equivalents of 3.5 and 479.5 at the endpoints. KAMA changes SC each bar, so these equivalents describe local weights, not an identical historical line.

Worked example: the same endpoint, different paths

These invented prices demonstrate arithmetic, not market performance. Set N=3, fast length=2 and slow length=30. Seed KAMA at the source on bar 3, when the first complete window exists. Keep full precision internally; the table rounds to six decimals.

Hypothetical bar-by-bar calculation with a current-source seed
BarTrend priceReversing priceTrend KAMAReversing KAMA
0100100Warm-upWarm-up
1101103Warm-upWarm-up
2102100Warm-upWarm-up
3103103103.000000 (seed)103.000000 (seed)
4104100103.444444102.788954
5105103104.135802102.803801

On bar 3, both paths go from 100 to 103. The trend path travels 1+1+1=3, so ER=3/3=1 and SC=0.444444. The reversing path travels 3+3+3=9, so ER=3/9=1/3 and SC=0.070349. Each series keeps that ER through bar 5. ER ignores the direction: the reversing path still has ER=1/3 on bar 4 even though its net movement is negative.

The bar 4 updates are 103+(4/9)×(104-103)=103.444444 and 103+0.070348594×(100-103)=102.788954. Bar 5 uses those updated values as its starting point. Reusing 103 as the seed on every bar would fail to reproduce the table.

A flat window needs a separate rule

For 100, 100, 100, 100, both D and V equal zero. This example assigns ER=0 instead of dividing 0 by 0. A seed of 100 stays at 100. If an earlier KAMA were 102 when a flat 100 window appeared, the next value would be 102+(4/961)×(100-102)=101.991675. A flat price window therefore does not force an existing average to become flat immediately.

Copyable Pine Script v6 with visible diagnostics

Paste the script into TradingView's Pine Editor, save it and add it to the chart. The inputs expose source, ER length and fast/slow lengths. The Data Window includes ER and SC, so a similar-looking line is not your only correctness check.

Pine Script v6 · indicator example
//@version=6
indicator("KAMA: inspect the adaptive calculation", overlay=true)

source = input.source(close, "Source")
length = input.int(10, "ER length", minval=1)
fastLength = input.int(2, "Fast length", minval=1)
slowLength = input.int(30, "Slow length", minval=2)

if fastLength >= slowLength
    runtime.error("Fast length must be smaller than slow length.")

direction = math.abs(source - source[length])
noise = math.sum(math.abs(source - source[1]), length)
validCount = math.sum(na(source) ? 0.0 : 1.0, length + 1)
ready = not na(direction) and not na(noise) and validCount == length + 1
er = ready ? (noise == 0.0 ? 0.0 : direction / noise) : na
fastSC = 2.0 / (fastLength + 1)
slowSC = 2.0 / (slowLength + 1)
sc = math.pow(er * (fastSC - slowSC) + slowSC, 2)

var float kama = na
if not ready
    kama := na
else if na(kama[1])
    kama := source
else
    kama := kama[1] + sc * (source - kama[1])

crossUp = ta.crossover(source, kama)
confirmedCrossUp = barstate.isconfirmed and crossUp

plot(kama, "KAMA", color=color.blue, linewidth=2)
plot(er, "Efficiency ratio", display=display.data_window)
plot(sc, "Squared smoothing constant", display=display.data_window)
plotshape(confirmedCrossUp, title="Confirmed cross above", style=shape.triangleup, location=location.belowbar, color=color.blue, size=size.tiny)
alertcondition(confirmedCrossUp, title="Confirmed cross above KAMA", message="Source crossed above KAMA on a confirmed chart bar.")

This script waits for N+1 consecutive valid source values, then seeds at the current source without applying a recursive update on that same bar. A missing value resets the result to na until another complete window exists. It rejects fast length greater than or equal to slow length. These are explicit example policies, not a claim that every KAMA implementation uses them.

The line remains live on an open chart bar. The triangle and alert condition require a confirmed crossover above KAMA. Pine indicators recalculate during realtime updates, and barstate.isconfirmed becomes true on the closing update. A confirmed marker fixes the observation time; it does not establish a profitable entry.

Check disagreements before interpreting the line

  1. Match the exact symbol/feed, session, chart timeframe and source. The example uses the chart timeframe and makes no higher-timeframe requests.
  2. Match all four inputs. ER length controls the observation window; the fast and slow lengths set coefficient bounds. A KAMA length of 10 and an EMA length of 10 do not imply matching weights.
  3. Compare ER and SC on closed bars first. If ER disagrees, inspect the N absolute adjacent changes and missing values. If only SC disagrees, inspect the exact fractions and the square.
  4. If ER and SC agree but KAMA differs, compare the seed and available history. For identical subsequent inputs, the difference between two seeds shrinks by a factor of 1-SC each update. Small SC can preserve that difference for many bars.
  5. Keep line calculations separate from crossover confirmation. See Pine's execution model when historical bars agree but the live bar differs.

What the calculation cannot tell you

Scaling every price change by the same factor leaves ER unchanged, so high volatility does not necessarily mean low efficiency. A single directional jump after flat prices can yield ER=1. Neither that ratio nor a crossover tells you whether the next bar will continue. Price can cross a slowly moving KAMA repeatedly in a range.

A shorter ER window reacts to a different sample; it is not automatically a better intraday setting. Any strategy built around the line still needs entry timing, exits, sizing and trading costs. This page provides a calculation example, not investment advice or a performance comparison.

Turn the calculation into a checkable Pineify request

Ask the Pine Script AI Coding Agent to preserve the source, lengths, seed and zero-noise rule while adding your requested plots or confirmed conditions. Compare the generated values with the table before defining strategy exits and costs.

Create a KAMA indicator with source and ER/fast/slow inputs. Square the interpolated coefficient. Use ER=0 for zero total movement and seed from the current source after a complete window. Expose ER and SC in the Data Window, and confirm crossover markers only at chart-bar close.
Open Pine Script AI Coding Agent

KAMA questions

KAMA is an adaptive price average. Its efficiency ratio compares the absolute net change over a window with the sum of absolute adjacent changes. A high ratio gives the latest price more weight. The ratio has no sign: a steady decline can have the same efficiency as a steady rise.

No. KAMA squares the interpolated coefficient. With fast 2 and slow 30, the final coefficient ranges from (2/31) squared, about 0.004162, to (2/3) squared, about 0.444444. Holding those coefficients constant would correspond to EMA lengths of 479.5 and 3.5 respectively. A changing KAMA coefficient does not define one fixed EMA length.

Both net change and total adjacent change are zero, so the raw efficiency ratio is undefined. This page explicitly assigns ER=0 in that case. It uses the slow squared coefficient, so an existing KAMA approaches the constant price gradually. If the seeded KAMA already equals that price, it remains there.

Compare the source, ER length, fast and slow lengths, symbol feed, session and timeframe first. Then check initialization, missing-value handling and the zero-noise rule. This example seeds at the current source on the first complete window. Another implementation can start from an SMA or an earlier value and produce different results.

The plotted KAMA can change on the open chart bar as its source changes. This example confirms crossover markers only at bar close, while leaving the line live. That does not protect against revised source data or a different starting history. Compare closed bars with the same inputs when checking values.

There is no universally best setting. The example starts with ER length 10, fast length 2 and slow length 30. Length counts bars, so changing the timeframe changes the observations. Match settings to a defined measurement task and test any trading rules separately with exits, transaction costs and position sizing.