Trading Strategy

Donchian Channel Strategy

A volatility breakout strategy using Donchian Channels to identify strong trend momentum and capture explosive price movements.

Classic Breakout System

The Donchian Channel is a trend-following indicator that plots the highest high and lowest low over a specified period. This strategy identifies breakout moments when price breaks above the upper channel (bullish) or below the lower channel (bearish). Combined with a 200 EMA trend filter and ATR confirmation, it captures high-momentum moves while filtering out false breakouts.

Volatility Breakout Type
4h Chart Timeframe
Beginner Complexity
Trending Best Market

Signal Logic

Long (Buy)

Price breaks above upper Donchian Channel while above 200 EMA, with bullish candle confirmation.

Short (Sell)

Price breaks below lower Donchian Channel while below 200 EMA, with bearish candle confirmation.

Implementation

//@version=6
strategy("Donchian Channel Strategy", overlay=true, initial_capital=1000000, default_qty_type=strategy.percent_of_equity, default_qty_value=100)

// ==========================================
// 🔹 INPUTS
// ==========================================
// Group: Donchian Channel Settings
grp_dc = "Donchian Channel Settings"
lookback = input.int(20, "Channel Length (Periods)", minval=1, group=grp_dc)

// Group: Trend Filter
grp_trend = "Trend Filter"
use_trend = input.bool(true, "Use Trend Filter (EMA 200)", group=grp_trend)
ema_len   = input.int(200, "Trend EMA Length", minval=1, group=grp_trend)

// Group: Confirmation
grp_confirm = "Confirmation"
use_atr = input.bool(true, "Use ATR Confirmation", group=grp_confirm)
atr_len = input.int(14, "ATR Length", minval=1, group=grp_confirm)
atr_mult = input.float(1.5, "ATR Multiplier", step=0.1, group=grp_confirm)

// Group: Risk Management
grp_risk = "Risk Management"
tp_ratio = input.float(2.0, "Risk:Reward Ratio", step=0.1, group=grp_risk)

// ==========================================
// 🔹 CALCULATIONS
// ==========================================
// Donchian Channel - Highest high and lowest low over lookback period
upper_channel = ta.highest(high, lookback)
lower_channel = ta.lowest(low, lookback)
middle_channel = (upper_channel + lower_channel) / 2

// EMA for trend filter
ema_val = ta.ema(close, ema_len)

// ATR for confirmation
atr_val = ta.atr(atr_len)

// Trend conditions
trend_up = use_trend ? close > ema_val : true
trend_down = use_trend ? close < ema_val : true

// Breakout conditions
price_breaks_above_upper = close > upper_channel[1] and close[1] <= upper_channel[1]
price_below_lower = close < lower_channel[1] and close[1] >= lower_channel[1]

// ==========================================
// 🔹 STRATEGY LOGIC
// ==========================================
// Long Entry: Price breaks above upper Donchian Channel (bullish breakout)
// Optional: Confirm with ATR volatility
long_signal = price_breaks_above_upper and trend_up

if use_atr
    long_signal := long_signal and close > open // Confirm with bullish candle

// Short Entry: Price breaks below lower Donchian Channel (bearish breakout)
short_signal = price_below_lower and trend_down

if use_atr
    short_signal := short_signal and close < open // Confirm with bearish candle

// ==========================================
// 🔹 EXECUTION & RISK MANAGEMENT
// ==========================================

if long_signal
    strategy.entry("Long", strategy.long, comment="L | DC Breakout")

if short_signal
    strategy.entry("Short", strategy.short, comment="S | DC Breakout")

// Risk management
if strategy.position_size > 0
    stop_level = use_atr ? strategy.position_avg_price - (atr_val * atr_mult) : lower_channel
    profit_level = strategy.position_avg_price + (strategy.position_avg_price - stop_level) * tp_ratio
    strategy.exit("Exit Long", "Long", stop=stop_level, limit=profit_level, comment_loss="SL", comment_profit="TP")

if strategy.position_size < 0
    stop_level = use_atr ? strategy.position_avg_price + (atr_val * atr_mult) : upper_channel
    profit_level = strategy.position_avg_price - (stop_level - strategy.position_avg_price) * tp_ratio
    strategy.exit("Exit Short", "Short", stop=stop_level, limit=profit_level, comment_loss="SL", comment_profit="TP")

// ==========================================
// 🔹 VISUALS
// ==========================================
// Plot Donchian Channel
plot(upper_channel, "Upper Channel", color=color.new(color.red, 0), linewidth=1)
plot(lower_channel, "Lower Channel", color=color.new(color.green, 0), linewidth=1)
plot(middle_channel, "Middle Channel", color=color.new(color.gray, 50), linewidth=1, linestyle=plot.style_dashed)

// Plot EMA
plot(use_trend ? ema_val : na, "Trend EMA", color=color.new(color.orange, 0), linewidth=2)

// Plot Signals
plotshape(long_signal, title="Long Signal", location=location.belowbar, color=color.green, style=shape.labelup, text="BUY", textcolor=color.white)
plotshape(short_signal, title="Short Signal", location=location.abovebar, color=color.red, style=shape.labeldown, text="SELL", textcolor=color.white)

// Background for channel
fill(plot(upper_channel), plot(lower_channel), color=color.new(color.blue, 95))