Logo
OFFLINEPIXEL
/ pinescript-strategies / pine-script-keltner-channels

$ Pinescript Keltner Channels

Master these dynamic volatility envelopes in TradingView's Pinescript for identifying trend direction, anticipating breakouts, and understanding market volatility.

500+ Clients Helped
100% Satisfaction
Live Trading Ready
⚠️
Trading financial markets carries risk. All content (PineScript code, indicators, strategies) on this website is for educational purposes only. Past performance is not indicative of future results. By using any code or information from this site, you agree that you are solely responsible for your trading decisions. The author disclaims all liability for any losses incurred. To gain from experts experiences, You can always try our Invite Only Scripts
01

What are Keltner Channels?

Keltner Channels (KC) are volatility-based envelopes plotted on either side of a central moving average. Originally developed by Chester Keltner in the 1960s and later updated by Linda Bradford Raschke, they are similar to Bollinger Bands but use the Average True Range (ATR) to set their width, rather than standard deviation. This makes Keltner Channels slightly less reactive to extreme price spikes than Bollinger Bands, often providing a smoother channel.

Keltner Channels consist of three lines:

  1. A Middle Line: Typically an Exponential Moving Average (EMA) or Simple Moving Average (SMA) of the closing price.
  2. An Upper Channel Line: Plotted a multiple of the Average True Range (ATR) above the Middle Line.
  3. A Lower Channel Line: Plotted the same multiple of the Average True Range (ATR) below the Middle Line.
02

Components and Calculation

The calculation of Keltner Channels involves a moving average and the Average True Range (ATR):

  1. Middle Line: An Exponential Moving Average (EMA) of the price, often based on `close` or `hlc3` (high+low+close/3), over a specified `length` (e.g., 20 periods).
    `Middle Line = EMA(source, length)`
  2. Average True Range (ATR): Calculated over the same `length` as the Middle Line.
    `ATR = ta.atr(length)`
  3. Upper Channel Line: Add a multiple of the ATR to the Middle Line. The `multiplier` is typically 1.5 or 2.0.
    `Upper Channel = Middle Line + (ATR * multiplier)`
  4. Lower Channel Line: Subtract the same multiple of the ATR from the Middle Line.
    `Lower Channel = Middle Line - (ATR * multiplier)`
03

Basic Keltner Channels Implementation in Pinescript

pine-script@terminal
//@version=5
indicator("My Keltner Channels", overlay=true) // overlay=true to plot directly on the price chart

// Inputs for Keltner Channels parameters
length = input.int(20, title="KC Length (EMA/ATR)", minval=1)
atrMultiplier = input.float(2.0, title="ATR Multiplier", minval=0.1, step=0.1)
source = input(close, title="Source") // Common sources: close, hlc3

// Calculate Keltner Channels using the built-in function
// ta.keltner returns the Middle, Upper, and Lower channel lines
[middleLine, upperChannel, lowerChannel] = ta.keltner(source, length, atrMultiplier)

// Plot the Middle Line
plot(middleLine, title="Middle Line", color=color.blue, linewidth=2)

// Plot the Upper and Lower Channel Lines
plot(upperChannel, title="Upper Channel", color=color.red, linewidth=1)
plot(lowerChannel, title="Lower Channel", color=color.green, linewidth=1)

// Fill the area between the channels for visual appeal
fill(upperChannel, lowerChannel, color.new(color.blue, 90), title="KC Background")
$ ✓ Compiled successfully
04

ATR-Based Volatility

ATR-Based Volatility

Keltner Channels use ATR, which is a robust measure of volatility that accounts for gaps, making them potentially more stable than standard deviation-based bands in certain markets.

05

Practical Keltner Channels Trading Strategies

06

1. Trend Following (Breaks of Channels)

pine-script@terminal
//@version=5
strategy("Keltner Channel Breakout Strategy", overlay=true)

length = input.int(20, title="KC Length", minval=1)
atrMultiplier = input.float(2.0, title="ATR Multiplier", minval=0.1, step=0.1)
source = input(close, title="Source")

[middleLine, upperChannel, lowerChannel] = ta.keltner(source, length, atrMultiplier)

plot(middleLine, "Middle Line", color.blue)
plot(upperChannel, "Upper Channel", color.red)
plot(lowerChannel, "Lower Channel", color.green)
fill(upperChannel, lowerChannel, color.new(color.blue, 90))

// Conditions for a bullish breakout
longCondition = close > upperChannel and close[1] <= upperChannel[1] // Current close above upper, previous below or equal

// Conditions for a bearish breakout
shortCondition = close < lowerChannel and close[1] >= lowerChannel[1] // Current close below lower, previous above or equal

if (longCondition)
    strategy.entry("Long Breakout", strategy.long)

if (shortCondition)
    strategy.entry("Short Breakout", strategy.short)

// Example exits: close on touch of opposite channel or Middle Line, or based on fixed stop/target
strategy.exit("Long Exit", from_entry="Long Breakout", stop=middleLine) // Exit if price returns to middle
strategy.exit("Short Exit", from_entry="Short Breakout", stop=middleLine)
$ ✓ Compiled successfully
07

2. Mean Reversion (Bounces within Channels)

pine-script@terminal
//@version=5
strategy("Keltner Channel Mean Reversion", overlay=true)

length = input.int(20, title="KC Length", minval=1)
atrMultiplier = input.float(1.5, title="ATR Multiplier (for range)", minval=0.1, step=0.1) // Smaller multiplier for ranging
source = input(close, title="Source")

[middleLine, upperChannel, lowerChannel] = ta.keltner(source, length, atrMultiplier)

plot(middleLine, "Middle Line", color.blue)
plot(upperChannel, "Upper Channel", color.red)
plot(lowerChannel, "Lower Channel", color.green)
fill(upperChannel, lowerChannel, color.new(color.blue, 90))

// A simple way to detect ranging: check if price has been mostly inside bands recently
// Or use an external indicator like Choppiness Index for ranging conditions.
isRanging = close > lowerChannel and close < upperChannel and (upperChannel - lowerChannel) / middleLine * 100 < 5.0 // Bands not too wide

// Buy when price bounces off Lower Channel
longReversion = isRanging and close > lowerChannel and close[1] <= lowerChannel[1]

// Sell when price bounces off Upper Channel
shortReversion = isRanging and close < upperChannel and close[1] >= upperChannel[1]

if (longReversion)
    strategy.entry("Buy Reversion", strategy.long)

if (shortReversion)
    strategy.entry("Sell Reversion", strategy.short)

// Exit at Middle Line (primary target) or if price breaks out of the range
strategy.close("Buy Reversion", when=close > middleLine or close < lowerChannel) // Close on middle or if it breaks down
strategy.close("Sell Reversion", when=close < middleLine or close > upperChannel) // Close on middle or if it breaks up
$ ✓ Compiled successfully
08

3. Keltner Channels & Bollinger Bands Squeeze (Advanced)

pine-script@terminal
//@version=5
indicator("BB-KC Squeeze Detection", overlay=true)

// Keltner Channel settings
kcLength = input.int(20, title="KC Length", minval=1)
kcAtrMultiplier = input.float(2.0, title="KC ATR Multiplier", minval=0.1, step=0.1)
kcSource = input(close, title="KC Source")

// Bollinger Bands settings
bbLength = input.int(20, title="BB Length", minval=1)
bbStdDevMultiplier = input.float(2.0, title="BB StdDev Multiplier", minval=0.1, step=0.1)
bbSource = input(close, title="BB Source")

// Calculate Keltner Channels
[kcMiddle, kcUpper, kcLower] = ta.keltner(kcSource, kcLength, kcAtrMultiplier)

// Calculate Bollinger Bands
[bbMiddle, bbUpper, bbLower] = ta.bb(bbSource, bbLength, bbStdDevMultiplier)

// Plot Keltner Channels
plot(kcMiddle, "KC Middle", color.blue, linewidth=2)
plot(kcUpper, "KC Upper", color.purple, linewidth=1, style=plot.style_linebr)
plot(kcLower, "KC Lower", color.purple, linewidth=1, style=plot.style_linebr)

// Plot Bollinger Bands
plot(bbUpper, "BB Upper", color.orange, linewidth=1)
plot(bbLower, "BB Lower", color.orange, linewidth=1)

// Detect squeeze: BBs are inside KCs (i.e., BB_Upper < KC_Upper AND BB_Lower > KC_Lower)
isSqueeze = bbUpper < kcUpper and bbLower > kcLower

// Highlight squeeze periods
bgcolor(isSqueeze ? color.new(color.yellow, 80) : na, title="Squeeze Detected")

alertcondition(isSqueeze, "BB-KC Squeeze", "Bollinger Bands are squeezing inside Keltner Channels.")
$ ✓ Compiled successfully
09

Optimizing Keltner Channels Performance

To get the most from Keltner Channels in Pinescript:

  • Parameter Tuning:
    • `Length` (EMA/SMA period): The standard 20 is common. Shorter lengths (e.g., 10) for more sensitivity, longer lengths (e.g., 40) for smoother channels and longer-term trends.
    • `ATR Multiplier`: Standard values are 1.5 or 2.0. A lower multiplier makes channels tighter (more signals, more noise). A higher multiplier makes them wider (fewer signals, potentially more reliable).
    • `Source`: `close` is common, but `hlc3` or `ohlc4` (`(open+high+low+close)/4`) can be used for a more representative price.
  • Context is Key: Like all indicators, Keltner Channels should not be used in isolation.
    • Combine with Trend Indicators: Confirm the main trend using longer-term moving averages or other trend indicators (e.g., ADX). Then use KC for entries/exits within that trend.
    • Combine with Momentum Oscillators: Use RSI, Stochastic, or MACD to confirm overbought/oversold conditions when price hits a channel, or to spot divergence.
    • Volume Analysis: Look for increased volume on channel breakouts for stronger confirmation.
  • Adapt to Market Conditions:
    • Trending Markets: Look for price riding an outer band or breaking out of a channel.
    • Ranging Markets: Look for price bouncing between the outer channels and reverting to the middle.
10

Keltner vs. Bollinger

Keltner vs. Bollinger

Keltner Channels are generally smoother due to using ATR, making them more suitable for identifying sustained trends and breakouts. Bollinger Bands, with standard deviation, are more reactive to single bar extremes and better for detecting short-term overextensions and squeezes.

11

Common Keltner Channels Pitfalls

  • False Breakouts: Price can temporarily poke outside a channel and then quickly revert, leading to false breakout signals, especially in choppy markets. Confirmation from other indicators (e.g., volume, candlestick patterns) is essential.
  • Lag: Keltner Channels, being based on moving averages and ATR, are lagging indicators. They won't always pinpoint exact tops or bottoms.
  • Whipsaws in Range-Bound Markets: While they can be used for mean reversion, in very tight ranges, crossovers and touches might lead to whipsaws.
  • Over-Optimization: Excessive tuning of parameters can lead to a strategy that performs well on historical data but poorly in live markets.
  • Not a Standalone Indicator: Keltner Channels are powerful but best utilized as part of a comprehensive trading strategy, not as the sole decision-making tool.
12

Conclusion

Conclusion

Keltner Channels are a robust and versatile technical analysis tool in Pinescript for TradingView. By providing dynamic price envelopes based on Average True Range, they offer traders a clear visual representation of price volatility and trend boundaries. Whether you are looking to capitalize on strong trend continuations, identify potential breakouts, or execute mean-reversion strategies, understanding and effectively applying Keltner Channels, ideally in conjunction with other indicators and sound risk management, can significantly enhance your trading decisions and overall performance. They provide a vital context for discerning trend strength and potential turning points in various market conditions.

Enhance Your Trading

Get a high-performance Pinescript analysis tool for actionable market insights, designed for traders on the move.

This strategy runs in live mode on TradingView, helping you identify potential opportunities.

Get Pinescript Strategy