Edgoro
Volatility indicator

Keltner Channels: formula, settings and Pine Script v6 code

How Keltner Channels wrap an EMA in ATR-based bands, how traders read breakouts and pullbacks, how they differ from Bollinger Bands, and a free script.

What it measures

Keltner Channels draw a band above and below a moving average, with the width set by the Average True Range. When bars get larger the channel widens; when the market goes quiet it narrows. A close outside the channel means price moved further from its average than recent bar sizes would suggest.

Chester Keltner described the original version in 1960, using a 10-day average of the typical price and the average daily range. The version most platforms use today, with an exponential moving average and ATR, was popularised in the 1980s by Linda Bradford Raschke.

The formula in words

  1. Middle line: a 20-period exponential moving average of the close.
  2. ATR: the Average True Range over 10 periods (see ATR).
  3. Upper band = middle line + 2 × ATR. Lower band = middle line − 2 × ATR.

Compare that with Bollinger Bands, which use the standard deviation of closes. Standard deviation reacts strongly to a few large closes; ATR averages bar ranges, so Keltner bands are smoother and change width more gradually. That difference is what the squeeze indicator measures.

Pine Script has ta.kc(), but it uses one length for both the average and the range. The script below builds the bands from ta.ema() and ta.atr() so the two lengths can differ.

How traders read it

  • Trend direction. The slope of the middle line describes the trend; many traders only look for longs while it rises.
  • Breakouts. A close outside the channel is a larger-than-usual move. Trend followers read a close above the upper band as strength, especially after a quiet period.
  • Pullbacks to the middle. In trends price often returns to the EMA before continuing, so the middle line is used as a pullback zone and the opposite band as an extreme.
  • Mean reversion in ranges. When the middle line is flat, touches of the outer bands are read as stretched moves. This works until a trend starts, which is why the slope matters.
  • Distance in ATRs. Because the width is in ATR units, "two ATRs above the average" means the same thing on any symbol. The script shows that distance in the data window.

Common settings

SettingTypical valueNotes
EMA length20The middle line.
ATR length1014 or 20 for a steadier width.
Multiplier21.5 for a tighter channel (common in squeeze setups), 2.5 to 3 for fewer touches.
1960 original10-day SMA of typical price ± 10-day average rangeRarely used today.

Pine Script v6 code

The complete, self-contained script is below. Copy it into a new indicator in TradingView's Pine Editor, or download the .pine file.

Pine Script v6
//@version=6
indicator("Keltner Channels", shorttitle = "KC", overlay = true)

src    = input.source(close, "Source", group = "Middle line")
len    = input.int(20, "EMA length", minval = 1, group = "Middle line")
atrLen = input.int(10, "ATR length", minval = 1, group = "Bands")
mult   = input.float(2.0, "Width (x ATR)", minval = 0.1, step = 0.1, group = "Bands")

basis = ta.ema(src, len)
atr   = ta.atr(atrLen)
upper = basis + mult * atr
lower = basis - mult * atr

// First close outside a band, and the first close back inside after being outside.
closeAbove = ta.crossover(close, upper)
closeBelow = ta.crossunder(close, lower)
backBelow  = ta.crossunder(close, upper)
backAbove  = ta.crossover(close, lower)

plot(basis, "Middle (EMA)", color = color.new(color.gray, 0))
upperPlot = plot(upper, "Upper", color = color.new(color.teal, 0))
lowerPlot = plot(lower, "Lower", color = color.new(color.teal, 0))
fill(upperPlot, lowerPlot, color = color.new(color.teal, 92), title = "Channel")

plotshape(closeAbove, "Close above upper", shape.triangleup, location.belowbar, color.new(color.teal, 0), size = size.tiny)
plotshape(closeBelow, "Close below lower", shape.triangledown, location.abovebar, color.new(color.red, 0), size = size.tiny)

// Distance of the close from the middle line, in ATRs, shown in the data window.
plot(atr > 0 ? (close - basis) / atr : na, "Distance from middle (ATRs)", display = display.data_window)

alertcondition(closeAbove, "Close above upper band", "{{ticker}} closed above the upper Keltner band ({{interval}})")
alertcondition(closeBelow, "Close below lower band", "{{ticker}} closed below the lower Keltner band ({{interval}})")
alertcondition(backBelow, "Back inside from above", "{{ticker}} closed back below the upper Keltner band ({{interval}})")
alertcondition(backAbove, "Back inside from below", "{{ticker}} closed back above the lower Keltner band ({{interval}})")

The channel and middle line are drawn on the price chart with a light fill. Triangles mark the first close outside each band, and the close's distance from the middle line, in ATRs, is shown in the data window.

Four alert conditions cover a close above the upper band, a close below the lower band, and the first close back inside from either side. Set them to Once per bar close.

Add it to your chart

  1. Open any chart on TradingView and open the Pine Editor.
  2. Create a new indicator, delete the template code and paste the script.
  3. Click Save, then Add to chart. Change lengths and levels from the indicator's settings.

Stuck on an error? See how to add a Pine Script indicator to TradingView.

Pitfalls

  • Fading every touch. In trends price can ride the upper or lower band for many bars. Decide whether you trade breakouts or ranges before you use the bands.
  • Confusing it with Bollinger Bands. Same shape, different maths. A close outside a Keltner band and a close outside a Bollinger Band are different events that happen at different rates.
  • ATR smoothing differences. Some platforms average the range with an EMA, others with Wilder's smoothing or a simple average, so bands can differ slightly between charts.
  • Acting on the live bar. A close outside the band only counts once the bar closes.

The script is an educational example: test it on your own markets before relying on it. Indicators describe the past; they don't predict the future. Trading involves substantial risk of loss and is not suitable for every investor. Edgoro is a software tool, not a broker or financial adviser: nothing it produces is investment advice, and past or backtested performance does not guarantee future results.

Make it yours with Edgoro

Describe the change in plain English and Edgoro writes the Pine Script v6 for you, ready to paste. For example:

“Plot Keltner Channels (20 EMA, 2 × ATR 10), mark the first close above the upper band while the EMA is rising, and alert once per bar close.”

Build your Keltner Channels indicator