Indicator TutorialPine Script v6

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.
ParameterDefaultDescription
Entry length20 bars in this exampleThe 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 length10 bars in this exampleAn optional second range for testing exit rules. These lines do not execute orders and are not a complete historical Turtle trading system.
Window alignmentCurrent channel plus prior-bar referenceSolid bands include the current bar. Gray step lines use the previous completed window and remain fixed during the current bar.
ConfirmationChart bar closeMarkers 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 candleHigh / closeResult against prior upper 102
Touches102 / 101Equality is a touch, not a strict breakout.
Trades beyond, returns103 / 101.5Intrabar penetration; no closing breakout.
Closes beyond103 / 102.5Confirmed 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.

Pine Script v6
//@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.

FeatureManual Pine ScriptPineify Visual Editor
Channel calculationWrite and inspect highest-high and lowest-low calculations.Configure the Donchian Channel module and its Length input.
Visual settingsEdit plot colors, widths and fill in source.Configure basis, upper, lower and channel background settings.
Custom breakout timingReference the prior window and gate signals at bar close.Describe the exact rule to the AI Coding Agent and inspect the generated source.
ValidationCompile 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

1

Open the Visual Editor

Start a script and add the Donchian Channel indicator module.

2

Set the channel length

Choose a bar count and inspect the basis, upper and lower outputs. Match the TradingView chart timeframe and session.

3

Choose the drawing settings

Set line colors, widths and background fill for the range you want to inspect.

4

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.

5

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

The unshifted ta.highest(high, length) and ta.lowest(low, length) calculations include the current bar. The example uses their [1] values for a breakout reference formed from the preceding completed bars.

A touch reaches a reference level. An intrabar penetration trades beyond it. The closing breakout rule here requires a finished candle to close strictly beyond the prior channel. Equality and a wick that closes back inside do not qualify.

Current-bar channel values can change before the candle closes. This example waits for chart-bar confirmation before marking a breakout and uses prior completed bars for the reference. That does not guarantee unchanged outputs after data revisions or protect higher-timeframe modifications from lookahead errors.

No best length is established here. Twenty is a conventional starting input, not an optimized recommendation. Compare lengths with fixed execution assumptions and test the selected rule on data that was not used to choose it.

The script tests each close against its own preceding window. Consecutive new closing highs may each qualify. A one-entry-per-position strategy needs a separate position-state rule; the displayed indicator does not place trades.

Add the example to a TradingView chart, select one of its confirmed breakout conditions in the alert dialog and choose Once Per Bar Close. The script condition already requires a closing update. Recreate the alert after editing inputs or code so the saved alert uses the intended version.

The visible source links point to TradingView documentation for Donchian Channels, bar states, repainting and strategies. The numerical table is hypothetical. The code is an indicator example and does not provide evidence of profitable trading.

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.