The Double Donchian Channel Breakout strategy coded for TradingView
The Double Donchian Channel Breakout strategy coded for TradingView
Section titled “The Double Donchian Channel Breakout strategy coded for TradingView”TL;DR
Use a fast Donchian channel for entries, a slower one for exits, and optional pyramiding to capture sustained trends the way the original Turtle traders did.
At a Glance
Section titled “At a Glance”| Difficulty | Intermediate |
| Time to implement | 20-25 min |
| Category | Strategies |
Quick Actions
Section titled “Quick Actions”Quick Start
Section titled “Quick Start”//@version=5strategy("Double Donchian", overlay=true, pyramiding=2)
fastLen = input.int(20, "Fast channel")slowLen = input.int(55, "Slow channel")
upperFast = ta.highest(high, fastLen)lowerFast = ta.lowest(low, fastLen)upperSlow = ta.highest(high, slowLen)lowerSlow = ta.lowest(low, slowLen)
if ta.crossover(close, upperFast) strategy.entry("Long", strategy.long)if ta.crossunder(close, lowerFast) strategy.entry("Short", strategy.short)
strategy.exit("Long Exit", "Long", stop=lowerSlow)strategy.exit("Short Exit", "Short", stop=upperSlow)Why It Matters
Section titled “Why It Matters”The double Donchian technique adds structure to breakout trading: fast channels detect new highs/lows quickly, while slower channels keep you in trends until meaningful reversals occur. Pine Script makes the entire Turtle-style blueprint approachable in a few dozen lines.
What You’ll Learn
Section titled “What You’ll Learn”- Configure two Donchian channels and decide which powers entries vs. exits.
- Implement pyramiding with ATR-based risk so add-on trades stay proportionate.
- Align exits (slow channel, ATR stops, or both) with the trend you’re capturing.
- Plot channels and annotate fills for easier debugging.
Quick Reference
Section titled “Quick Reference”| Helper | Purpose |
|---|---|
ta.highest / ta.lowest | Construct Donchian channels (fast and slow). |
| `strategy(entry | exit)` |
ta.atr | Size positions and compute emergency stops. |
input.int, input.float, input.bool | Expose tunable channel lengths, pyramiding, risk. |
plot, fill | Visualise channels and the zones between them. |
Implementation Blueprint
Section titled “Implementation Blueprint”-
Capture channel settings & risk
Provide inputs for fast/slow lengths, pyramiding count, ATR risk per leg.fastLen = input.int(20, "Fast channel", minval=1)slowLen = input.int(55, "Slow channel", minval=1)pyramid = input.int(2, "Pyramiding", minval=0, maxval=4)riskATR = input.float(2.0, "Stop distance (ATR)", step=0.1)strategy("Double Donchian", overlay=true, pyramiding=pyramid) -
Compute channels and sizing
Generate upper/lower bands and calculate quantity from ATR.upperFast = ta.highest(high, fastLen)lowerFast = ta.lowest(low, fastLen)upperSlow = ta.highest(high, slowLen)lowerSlow = ta.lowest(low, slowLen)atr = ta.atr(14)riskCapital = strategy.equity * 0.01 // risk 1% by defaultqty = atr > 0 ? math.floor(riskCapital / (atr * riskATR)) : 0 -
Stage entries & exits
Use fast-channel breaks for entries; trail stops at the slow channel (or ATR-based fallbacks).if ta.crossover(close, upperFast) and qty > 0strategy.entry("Long", strategy.long, qty=qty)if ta.crossunder(close, lowerFast) and qty > 0strategy.entry("Short", strategy.short, qty=qty)strategy.exit("LX", "Long", stop=math.min(lowerSlow, strategy.position_avg_price - atr * riskATR))strategy.exit("SX", "Short", stop=math.max(upperSlow, strategy.position_avg_price + atr * riskATR))
Example Playbook
Section titled “Example Playbook”//@version=5strategy("Double Donchian Turtle", overlay=true, pyramiding=3, initial_capital=100_000, commission_type=strategy.commission.percent, commission_value=0.02)
// InputsdonchianFast = input.int(20, "Fast Donchian", minval=2)donchianSlow = input.int(55, "Slow Donchian", minval=2)atrLen = input.int(14, "ATR length", minval=1)riskPct = input.float(0.5, "Risk per leg (%)", minval=0.1, step=0.1)atrStopMult = input.float(2.0, "ATR stop multiple", step=0.1)
// ChannelsupperFast = ta.highest(high, donchianFast)lowerFast = ta.lowest(low, donchianFast)upperSlow = ta.highest(high, donchianSlow)lowerSlow = ta.lowest(low, donchianSlow)
plot(upperFast, "Fast upper", color=color.new(color.green, 0))plot(lowerFast, "Fast lower", color=color.new(color.green, 0))plot(upperSlow, "Slow upper", color=color.new(color.orange, 0))plot(lowerSlow, "Slow lower", color=color.new(color.orange, 0))fill(plot(upperFast, display=display.none), plot(lowerFast, display=display.none), color=color.new(color.green, 95))
aTR = ta.atr(atrLen)riskCash = strategy.equity * (riskPct * 0.01)qty = aTR > 0 ? math.floor(riskCash / (aTR * atrStopMult)) : 0
longBreak = ta.crossover(close, upperFast)shortBreak = ta.crossunder(close, lowerFast)
if longBreak and qty > 0 strategy.entry("Long", strategy.long, qty=qty)if shortBreak and qty > 0 strategy.entry("Short", strategy.short, qty=qty)
if strategy.position_size > 0 stopLong = math.min(lowerSlow, strategy.position_avg_price - aTR * atrStopMult) strategy.exit("Long Exit", "Long", stop=stopLong)if strategy.position_size < 0 stopShort = math.max(upperSlow, strategy.position_avg_price + aTR * atrStopMult) strategy.exit("Short Exit", "Short", stop=stopShort)
bgcolor(strategy.position_size > 0 ? color.new(color.green, 90) : strategy.position_size < 0 ? color.new(color.red, 90) : na)
var label status = naif barstate.islast if not na(status) label.delete(status) status = label.new(bar_index, close, text="Equity: " + str.tostring(strategy.equity, "##,###.00") + "\nOpen trades: " + str.tostring(strategy.opentrades, "0"), style=label.style_label_left, textcolor=color.white, bgcolor=color.new(color.blue, 70))- Dual Donchian channels separate breakout detection (fast) from trailing exits (slow).
- ATR-driven position sizing keeps each leg’s risk consistent as volatility changes.
- Visual overlays (plots, fills, background) make it easy to confirm entries, exits, and pyramiding behaviour.
Pro Tips & Pitfalls
Section titled “Pro Tips & Pitfalls”- Lower the fast-channel length to generate more trades, or raise it to filter noise—slow channel should be significantly longer to avoid premature exits.
- When pyramiding, consider limiting the maximum number of concurrent legs or scaling ATR stops tighter for late-stage entries.
- Add filters (trend, volatility, session) if you want to avoid choppy regimes where Donchian breakouts whipsaw.
- Always account for slippage and commission; longer-term breakouts can still suffer if costs aren’t factored in.
Troubleshooting & FAQ
Section titled “Troubleshooting & FAQ”The strategy opens too many positions
Section titled “The strategy opens too many positions”Reduce pyramiding or require a minimum distance from the previous entry (strategy.position_avg_price vs. current breakout level).
Stops are far away on slow markets
Section titled “Stops are far away on slow markets”Add a minimum stop distance based on syminfo.mintick or allow users to cap ATR multiples with a secondary input.
How do I prevent entries during sideways ranges?
Section titled “How do I prevent entries during sideways ranges?”Combine Donchian breakouts with volatility filters (e.g., ta.atr percentile) or only allow trades when the slow channel width exceeds a threshold.
Key Takeaways
Section titled “Key Takeaways”- Double Donchian systems pair fast breakout detection with slow trailing exits—perfect for trend following.
- Pine Script makes it straightforward to implement both channels, pyramiding, and ATR-based risk sizing.
- Visualise channels and annotate status to validate logic before live deployment.
- Fine-tune channel lengths, pyramiding, and stop multiples to match the market you’re trading.
Keep Going
Section titled “Keep Going”- Open AI Editor to apply the pattern with guided assistance
- Browse PineScript Examples for ready-to-run templates
- Connect to Live Trading when you are ready to automate
Adapted from tradingcode.net, optimised for Algo Trade Analytics users.