◆ New — Strategy Validator, Code Fixer & Prop Compliance Checker are live. Try one free →
Home / Learn / Keltner Channels vs Bollinger Bands: Which Should You Use?
comparison

Keltner Channels vs Bollinger Bands: Which Should You Use?

A deterministic comparison of Keltner Channels and Bollinger Bands: how ATR-based width and standard-deviation-based width actually behave differently on the same data, complete Pine Script v6 code for plotting both, and how the two combine into the squeeze (Bollinger Bands closing inside Keltner Channels). This is educational material only, not financial advice — neither channel predicts price, a band touch is not a signal by itself, and trading carries a real risk of loss.

Should you use Keltner Channels or Bollinger Bands?

Use Bollinger Bands when you want a channel that reacts sharply to changes in the dispersion of closing prices, and Keltner Channels when you want a smoother envelope that tracks average true range — including gaps — and ignores single-bar outliers. The two indicators answer subtly different questions, so the honest answer is that neither is universally better: they measure volatility with different mathematics, and that difference is the entire decision.

Both are volatility channels: a moving-average centreline with an upper and lower band offset by some multiple of a volatility estimate. Bollinger Bands (John Bollinger, 1980s) use a simple moving average of close, typically 20 periods, offset by a multiple — typically 2 — of the standard deviation of close over the same window. Keltner Channels in their modern form (Chester Keltner's 1960 original used a moving average of typical price; Linda Bradford Raschke popularised the ATR-based version) use an exponential moving average offset by a multiple of the Average True Range.

That one substitution — standard deviation versus ATR — drives every visible difference between them. Standard deviation squares deviations from the mean, so it over-weights outliers and reacts violently; ATR is a smoothed average of true range, so it responds gradually and also "sees" overnight gaps that close-to-close standard deviation partially misses. Everything else — the trading folklore, the squeeze setups, the mean-reversion claims — sits on top of that mathematical distinction.

One framing note before we go deeper: a price channel is a description of recent volatility, not a forecast. A close outside either channel tells you the move was large relative to recent history — it does not tell you what happens next. Nothing in this article is financial advice.

How the width is computed: standard deviation vs ATR

The behavioural differences between the two channels are deterministic — you can predict them from the formulas without any backtest.

Bollinger width = k × stdev(close, n). Standard deviation squares each bar's deviation from the window mean before averaging. Consequences: (1) a single large bar — a news spike, an earnings gap — inflates the bands immediately and disproportionately; (2) exactly n bars later, when that outlier falls out of the lookback window, the bands snap tighter in one step even if nothing happened on that bar. That second effect surprises people: Bollinger Bands can visibly contract on a quiet bar purely because an old shock aged out of the window. (3) Because the input is close-to-close dispersion, a market that gaps overnight but trades quietly intraday can look calmer than it is.

Keltner width = k × ATR(m). Pine's ta.atr() smooths true range with Wilder's RMA — an exponential-style average. Consequences: (1) a volatility shock widens the channel gradually and decays gradually, with no window-exit artifact, because old bars fade out exponentially rather than dropping off a cliff; (2) true range includes the gap between yesterday's close and today's range, so Keltner Channels register gap risk that close-based standard deviation understates; (3) the channel is visually smoother, which is why trend-followers tend to prefer it as a dynamic envelope.

A useful mental model: Bollinger Bands are a statistical channel (how unusual is this close relative to recent closes?) while Keltner Channels are a range channel (how far does this instrument typically travel per bar?). Same family, different sensor. Neither sensor knows anything about the future.

Both channels in one Pine v6 script

Plotting both on one chart is the fastest way to internalise the difference — watch how the blue Bollinger Bands balloon on a shock bar and snap back n bars later, while the orange Keltner Channels swell and decay smoothly.

//@version=6
// Educational only — validate before trading; not financial advice.
indicator("BB vs KC comparison", overlay = true)

len    = input.int(20, "Basis length", minval = 1)
bbMult = input.float(2.0, "BB stdev multiple", minval = 0.1)
kcMult = input.float(2.0, "KC ATR multiple", minval = 0.1)
atrLen = input.int(20, "KC ATR length", minval = 1)

// Bollinger Bands: SMA basis ± multiple of standard deviation of close
bbBasis = ta.sma(close, len)
bbDev   = bbMult * ta.stdev(close, len)
bbUpper = bbBasis + bbDev
bbLower = bbBasis - bbDev

// Keltner Channels: EMA basis ± multiple of ATR
kcBasis = ta.ema(close, len)
kcBand  = kcMult * ta.atr(atrLen)
kcUpper = kcBasis + kcBand
kcLower = kcBasis - kcBand

plot(bbUpper, "BB upper", color = color.blue)
plot(bbLower, "BB lower", color = color.blue)
plot(kcUpper, "KC upper", color = color.orange)
plot(kcLower, "KC lower", color = color.orange)

Implementation notes worth being precise about. Every built-in is namespaced (ta.sma, ta.stdev, ta.ema, ta.atr) — bare calls do not compile in v6. The classic defaults differ slightly between the two indicators: Bollinger convention is SMA(20) with a 2× multiplier; Keltner convention is EMA(20) with a 2× ATR multiplier, though ATR length 10 is also common. Matching the basis lengths, as this script does, isolates the width mathematics so you are comparing the volatility estimators rather than the centrelines.

Both channels update on the live bar and settle only when the bar confirms — that is normal live-bar behaviour, not repainting, but any signal you derive from them should wait for bar close.

What is the squeeze — Bollinger Bands inside Keltner Channels?

Because standard deviation compresses harder than ATR in quiet markets, there are stretches where the Bollinger Bands fit entirely inside the Keltner Channels. That condition — BB upper below KC upper and BB lower above KC lower — is the core of the TTM Squeeze, popularised by John Carter. It is read as a period of unusually low close-to-close dispersion relative to average range: statistical volatility has contracted faster than range volatility.

The deterministic detection is a two-line boolean on top of the previous script:

//@version=6
// Educational only — validate before trading; not financial advice.
indicator("BB-inside-KC squeeze", overlay = true)

len    = input.int(20, "Basis length", minval = 1)
bbMult = input.float(2.0, "BB stdev multiple", minval = 0.1)
kcMult = input.float(1.5, "KC ATR multiple", minval = 0.1)

bbBasis = ta.sma(close, len)
bbDev   = bbMult * ta.stdev(close, len)
kcBasis = ta.ema(close, len)
kcBand  = kcMult * ta.atr(len)

squeezeOn = bbBasis + bbDev < kcBasis + kcBand and bbBasis - bbDev > kcBasis - kcBand

plotshape(squeezeOn and barstate.isconfirmed, "Squeeze on",
     style = shape.circle, location = location.bottom, color = color.gray)

Two correctness details. First, the squeeze marker is gated with and barstate.isconfirmed: on the live bar the boolean can flip on and off as ticks arrive, and an ungated marker would appear and vanish intrabar — the classic self-inflicted repaint. Second, the conventional TTM parameterisation uses a 1.5× ATR multiplier for the Keltner side (as above); with 2×/2× the squeeze fires less often. That choice changes the frequency of the condition, not its meaning.

Be careful with the folklore. A squeeze says volatility contracted; it does not say when expansion comes, in which direction, or whether it is tradeable after costs. Treat it as a measurement, not a promise.

Which one should you actually choose?

A practical decision guide, grounded in the mathematics rather than folklore.

Choose Bollinger Bands when your logic is explicitly statistical — you care about how unusual the current close is relative to recent closes, you want the channel to react instantly to a dispersion shock, or you are building squeeze-style compression measures where stdev's fast contraction is the point. Accept in exchange the outlier sensitivity and the window-exit artifact, both of which can create band touches that say more about the estimator than the market.

Choose Keltner Channels when you want a smooth dynamic envelope for trend context, when overnight gaps matter to your risk picture (ATR sees them; close-based stdev largely does not), or when you want channel width to change gradually so that width-derived logic — position sizing, stop distances — does not jump discontinuously. Accept in exchange a slower response to genuine regime changes.

Use both when you specifically want the squeeze: the whole construction depends on having the two estimators disagree.

Whichever you pick, the honest caveats are the same. A band touch or band close-outside is a description, not a signal — mean-reversion and breakout interpretations of the identical event are both popular, which should tell you the event alone carries no direction. Parameters (length, multiplier) materially change behaviour, and a combination tuned to look good historically may simply be fitted to noise — the multiple-testing problem that Bailey and López de Prado formalised applies to indicator settings as much as to strategies. And nothing about either channel makes a strategy profitable: they shape where you look, not whether an edge exists. Validate the mechanics, test signals on confirmed bars only, and hold any backtest result loosely. Trading carries a real risk of loss.

Key takeaways

Educational only — not financial advice. Trading involves substantial risk of loss.

Catch the bug that compiles.Run auditGet Pro