Donchian Channel: rolling highs, lows and breakout rules
A channel touch and a close beyond the previous channel are different events.
Donchian Channels plot the highest high and lowest low over a chosen number of bars, with their midpoint between them. A channel that includes the current bar expands with its high or low. For a close-based breakout, compare the close with the channel of the preceding bars and wait for that candle to finish. The Pine v6 example below makes both windows visible.
Add the Donchian indicator to TradingView
Open Indicators on your TradingView chart, search for Donchian Channels and select the built-in study. Check Length, Offset and the calculation timeframe before comparing it with a custom script. A length of 20 means 20 bars of the calculation timeframe, not always 20 days.
TradingView's Donchian Channels reference documents the extreme-based bands, a default length of 20 and an offset of zero. The midline averages the two extremes; it is not the average closing price.
A Donchian indicator describes an observed range. It does not establish that a boundary will hold as support or resistance. Repeated upper-band touches can accompany a rising market, while an isolated touch can reverse.
Browse the TradingView indicators directory or compare the construction with Bollinger Bands.
Why Traders Use This Indicator
- Locate the highest and lowest traded prices inside a defined rolling window.
- Separate an intrabar test of a previous extreme from a confirmed closing breakout.
- Specify entry and exit reference levels that can be checked against historical bars.
| Parameter | Default | Description |
|---|---|---|
| Entry length | 20 bars in this example | The number of bars in each rolling range. Changing length changes which extremes remain in the window; it does not establish an optimal setting. |
| Exit reference length | 10 bars in this example | An optional second range for testing exit rules. These lines do not execute orders and are not a complete historical Turtle trading system. |
| Window alignment | Current channel plus prior-bar reference | Solid bands include the current bar. Gray step lines use the previous completed window and remain fixed during the current bar. |
| Confirmation | Chart bar close | Markers and breakout alerts wait for barstate.isconfirmed. This trades earlier intrabar notification for a decision based on the completed candle. |
Donchian Channel formula and the current-bar trap
For bar t and length n, the inclusive upper band is the maximum high from t − n + 1 through t. The lower band is the minimum low over that same interval. The midpoint is (upper + lower) / 2. When an old extreme leaves the window, a band can move even without a new extreme.
In Pine, calculate upper = ta.highest(high, length) and lower = ta.lowest(low, length). On ordinary OHLC bars, close ≤ high ≤ upper, so close > upper cannot detect an upward breakout. The corresponding downward test against the inclusive lower band is also impossible.
Use upper[1] and lower[1] for the preceding n completed bars. This is a data-history reference. Moving a plot with an offset only changes where it is drawn and does not change the values used by a signal condition.
A hypothetical three-bar window
Suppose the preceding three bars have highs of 100, 102 and 101 and lows of 96, 97 and 98. Their upper reference is 102, lower reference 96 and midpoint 99. Each row below is a separate hypothetical next candle, not historical market data.
| Next candle | High / close | Result against prior upper 102 |
|---|---|---|
| Touches | 102 / 101 | Equality is a touch, not a strict breakout. |
| Trades beyond, returns | 103 / 101.5 | Intrabar penetration; no closing breakout. |
| Closes beyond | 103 / 102.5 | Confirmed closing breakout. Inclusive upper is already 103. |
Signal Interpretation
The example marks every completed candle whose close is strictly above the prior upper or below the prior lower. Consecutive new closing highs can therefore produce consecutive markers. This is an outside-window condition, not a one-entry-per-trend system. Position state, exits and repeat-entry rules belong in a separate strategy.
The current channel can change while a candle is open. Breakout markers wait for its closing update, as described in TradingView's bar-state documentation. With a 60-minute chart, the closing decision is unavailable until that hour ends.
There are no higher-timeframe requests or shifted plots in this example. If you add them, chart-bar confirmation alone does not confirm a higher-timeframe candle. A higher-timeframe request with lookahead enabled and no suitable historical offset can leak future values into historical bars. Read TradingView's repainting explanation before changing the data context.
Combining with Other Indicators
An ATR reference can express a proposed stop distance in price units. An ADX or moving-average filter can restrict which breakouts qualify, but each filter changes the hypothesis and needs a separate comparison. It does not automatically improve results.
For custom prior-bar conditions, ask the AI Coding Agent to preserve the window and confirmation rules. Once a strategy has explicit orders and editable inputs, use Strategy Optimizer to compare lengths. Hold commission and slippage assumptions constant within a comparison, then rerun with different costs.
TradingView documents strategy order timing, commission and slippage. Source references checked on October 16, 2026.
This tutorial is educational, not investment advice. Channel signals and historical tests do not guarantee future returns.
Writing Pine Script Manually
Challenges of Manual Coding
Keep the plotted current window separate from the previous completed window used by signals.
Require enough preceding bars before enabling alerts; early partial windows are not the stated full-length rule.
Define whether repeated outside closes, first crosses or position transitions should trigger a new action.
Treat higher-timeframe confirmation and simulated order fills as separate timing decisions.
//@version=6
indicator("Donchian windows and confirmed breakouts", overlay=true)
entryLength = input.int(20, "Entry channel length", minval=1)
exitLength = input.int(10, "Exit reference length", minval=1)
showExit = input.bool(true, "Show prior exit references")
showMidline = input.bool(true, "Show current midpoint")
showFill = input.bool(true, "Fill current channel")
showSqueeze = input.bool(true, "Highlight narrow channel")
squeezePct = input.float(2.0, "Narrow width threshold (%)", minval=0.1, step=0.1)
upper = ta.highest(high, entryLength)
lower = ta.lowest(low, entryLength)
midpoint = (upper + lower) / 2.0
priorUpper = upper[1]
priorLower = lower[1]
exitUpper = ta.highest(high, exitLength)[1]
exitLower = ta.lowest(low, exitLength)[1]
entryReady = bar_index >= entryLength
exitReady = bar_index >= exitLength
widthPct = midpoint != 0 ? (upper - lower) / math.abs(midpoint) * 100.0 : na
narrow = entryReady and not na(widthPct) and widthPct < squeezePct
bullBreakout = entryReady and barstate.isconfirmed and close > priorUpper
bearBreakout = entryReady and barstate.isconfirmed and close < priorLower
narrowStart = barstate.isconfirmed and narrow and not narrow[1]
pUpper = plot(upper, "Current upper", color=color.teal, linewidth=2)
pLower = plot(lower, "Current lower", color=color.red, linewidth=2)
plot(showMidline ? midpoint : na, "Current midpoint", color=color.orange)
plot(entryReady ? priorUpper : na, "Prior upper: breakout reference", color=color.gray, style=plot.style_stepline)
plot(entryReady ? priorLower : na, "Prior lower: breakout reference", color=color.gray, style=plot.style_stepline)
plot(showExit and exitReady ? exitUpper : na, "Prior exit upper", color=color.new(color.orange, 50))
plot(showExit and exitReady ? exitLower : na, "Prior exit lower", color=color.new(color.orange, 50))
fill(pUpper, pLower, color=showFill ? color.new(color.teal, 92) : na)
bgcolor(showSqueeze and barstate.isconfirmed and narrow ? color.new(color.yellow, 85) : na)
plotshape(bullBreakout, title="Close above prior channel", style=shape.triangleup, location=location.belowbar, color=color.teal, size=size.small)
plotshape(bearBreakout, title="Close below prior channel", style=shape.triangledown, location=location.abovebar, color=color.red, size=size.small)
alertcondition(bullBreakout, "Confirmed upper breakout", "Close above prior Donchian upper on {{ticker}}")
alertcondition(bearBreakout, "Confirmed lower breakout", "Close below prior Donchian lower on {{ticker}}")
alertcondition(narrowStart, "Narrow channel begins", "Donchian width below configured threshold on {{ticker}}")Maintenance Note: This is an indicator, not an order-executing strategy. Current bands may use a partial window at the start of available history; signals require a full preceding window. The optional width threshold is illustrative and undefined at a zero midpoint. A narrow channel does not predict the direction or timing of a future move.
Build with Pineify Visual Editor
Pineify lets you configure supported indicators and export Pine Script. Available settings and plan requirements vary by indicator. Compare the generated rules with the example before using its signals.
| Feature | Manual Pine Script | Pineify Visual Editor |
|---|---|---|
| Channel calculation | Write and inspect highest-high and lowest-low calculations. | Configure the Donchian Channel module and its Length input. |
| Visual settings | Edit plot colors, widths and fill in source. | Configure basis, upper, lower and channel background settings. |
| Custom breakout timing | Reference the prior window and gate signals at bar close. | Describe the exact rule to the AI Coding Agent and inspect the generated source. |
| Validation | Compile and compare signal bars with the stated rule. | Review generated code and verify the same rule on a TradingView chart. |
The Visual Editor includes a Donchian Channel module with an adjustable Length input.
Basis, upper and lower outputs are available alongside line and background settings.
The AI Coding Agent can help draft custom Pine logic from specified window and confirmation rules.
Strategy Optimizer supports parameter comparisons after the indicator is converted into a strategy.
Step-by-Step Tutorial
Open the Visual Editor
Start a script and add the Donchian Channel indicator module.
Set the channel length
Choose a bar count and inspect the basis, upper and lower outputs. Match the TradingView chart timeframe and session.
Choose the drawing settings
Set line colors, widths and background fill for the range you want to inspect.
Specify custom signal rules
For the example on this page, use the AI Coding Agent to request previous-bar channel references, full-window warm-up and bar-close confirmation. Verify those conditions in the output.
Review on TradingView
Generate the source, paste it into Pine Editor and add it to a chart. Compare markers against the prior window before creating alerts.
Trading Strategies & Pro Tips
Illustrative close-based breakout test
A testable long-only hypothesis enters while flat after a confirmed close above the prior 20-bar upper band and exits after a confirmed close below the prior 10-bar lower band. Use no pyramiding and define position size before testing. The indicator above supplies reference levels; it does not implement these orders.
Pro Tip: Under default Pine strategy execution, a market order created at bar close generally fills at the next bar open. That price can differ from the signal close, especially across gaps.
Window and cost comparison
Compare illustrative entry lengths of 10, 20 and 55 with the same exit rule, symbol, session, date range and order sizing. Record trade count, drawdown and net results after commission and slippage. Reserve a later period that was not used to select parameters.
Pro Tip: A winning in-sample length is a fitted result. Repeatedly choosing the best window can overfit noise, and higher costs can reverse a small simulated edge.
Channel-width filter experiment
The optional highlight measures width divided by the absolute midpoint. Compare the breakout rule with and without a predeclared width filter. The default 2% is an illustrative threshold, not evidence of an imminent breakout.
Common Mistakes to Avoid
- Testing close above an upper band that already includes the current high. Compare with the preceding completed window instead.
- Treating a wick beyond the prior band as a confirmed closing signal. The close can return inside the range before the bar ends.
- Treating a repeated marker as another entry without defining position state and pyramiding.
- Moving plots backward and then interpreting their apparent historical position as the time the information was available.
- Testing gaps at the signal close or omitting costs. Use explicit order-fill assumptions and standard candles when evaluating a strategy.
Frequently Asked Questions
Build a Donchian Channel with explicit signal rules
- Configure the channel length and drawings in the Visual Editor.
- Use the AI Coding Agent for custom prior-window and confirmation logic.
- Review the source and compare signals on TradingView before testing orders.
Disclaimer: Trading involves significant risk. The indicators, code, and strategies provided are for educational purposes only and do not constitute financial advice. Past performance is not indicative of future results.