0bps

Strategy vault / Breakout

Donchian Channel Breakout Strategy 426772

The Donchian channel breakout strategy is a trend following strategy based on the Donchian channel. It uses the highest high and lowest low over specified periods to determine entry and stop loss points for long and…

Author
ChaoZhang
Complexity
Intermediate · 78 lines
Parameters
16
Backtest bar
2h · intraday
Tested on
BTC/USDT · futures

Strategy Logic

The Donchian channel breakout strategy is a trend following strategy based on the Donchian channel. It uses the highest high and lowest low over specified periods to determine entry and stop loss points for long and short positions.

The entry rules are: go long when the price breaks above the highest high over a lookback period (e.g. 20 days), and go short when the price breaks below the lowest low over another lookback period (e.g. 10 days).

The EXIT rules are: Long positions are stopped out at the middle or lower band of the channel; short positions are stopped out at the middle or upper band. The middle band is the average of the highest high and lowest low over a specified period (e.g. 10 days).

For example, trading BTCUSDT with the following parameters:

  • Long entry lookback period: 20 days
  • Long stop loss lookback period: 10 days
  • Stop loss at middle band: Yes
  • Short entry lookback period: 10 days
  • Short stop loss lookback period: 20 days
  • Stop loss at middle band: Yes

The entry and stop rules would be:

  • Go long when price breaks above the 20-day high
  • Long stop loss at midpoint of 10-day high and low
  • Go short when price breaks below 10-day low
  • Short stop loss at midpoint of 20-day high and low

By dynamically adjusting the lookback periods, the strategy can be optimized across market cycles to capture trends with better reward/risk.

Advantages

  • Breakouts can identify trend direction early on
  • Stop losses close to price help manage risk
  • Flexible parameters allow optimization for different cycles

Risks

  • Breakouts prone to whipsaws, need to confirm validity
  • Close stop losses susceptible to shakeouts in choppy markets
  • Poor parameter tuning could lead to over-trading or insufficient stops

Summary

The Donchian channel breakout uses breakouts to identify trends, with channel midpoints/bands as stops to control risk. Optimizing lookback periods can improve trend capture in strong moves. However, caution is needed on breakout validity and shakeouts. Overall this strategy suits mid- to long-term trend trading, but may struggle in choppy markets.

Parameters

NameDefaultWhat it controls
v_input_110Channel Period for Long enter position
v_input_210Channel Period for Long exit position
v_input_3trueIs exit on Base Line? If 'no' - exit on bottom line
v_input_42.5Take Profit (%) for Long position
v_input_5trueAllow Long?
v_input_620Channel Period for Short enter position
v_input_720Channel Period for Short exit position
v_input_8trueIs exit on Base Line? If 'no' - exit on upper line
v_input_92.5Take Profit (%) for Short position
v_input_10trueAllow Short?
v_input_112005Test Start Year
v_input_12trueTest Start Month
v_input_13trueTest Start Day
v_input_142050Test End Year
v_input_1512Test End Month
v_input_1630Test End Day

Source Pine Script

/*backtest
start: 2023-08-14 00:00:00
end: 2023-09-13 00:00:00
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy("Donchian Channel Strategy", overlay=true, default_qty_type= strategy.percent_of_equity, initial_capital = 1000, default_qty_value = 20, commission_type=strategy.commission.percent, commission_value=0.036)

//Long optopns
buyPeriodEnter = input(10, "Channel Period for Long enter position")
buyPeriodExit = input(10, "Channel Period for Long exit position")
isMiddleBuy = input(true, "Is exit on Base Line? If 'no' - exit on bottom line")
takeProfitBuy = input(2.5, "Take Profit (%) for Long position")
isBuy = input(true, "Allow Long?")

//Short Options
sellPeriodEnter = input(20, "Channel Period for Short enter position")
sellPeriodExit = input(20, "Channel Period for Short exit position")
isMiddleSell = input(true, "Is exit on Base Line? If 'no' - exit on upper line")
takeProfitSell = input(2.5, "Take Profit (%) for Short position")
isSell = input(true, "Allow Short?")

// Test Start
startYear = input(2005, "Test Start Year")
startMonth = input(1, "Test Start Month")
startDay = input(1, "Test Start Day")
startTest = timestamp(startYear,startMonth,startDay,0,0)

//Test End
endYear = input(2050, "Test End Year")
endMonth = input(12, "Test End Month")
endDay = input(30, "Test End Day")
endTest = timestamp(endYear,endMonth,endDay,23,59)

timeRange = time > startTest and time < endTest ? true : false

// Long&Short Levels
BuyEnter = highest(buyPeriodEnter)
BuyExit = isMiddleBuy ? ((highest(buyPeriodExit) + lowest(buyPeriodExit)) / 2): lowest(buyPeriodExit)

SellEnter = lowest(sellPeriodEnter)
SellExit = isMiddleSell ? ((highest(sellPeriodExit) + lowest(sellPeriodExit)) / 2): highest(sellPeriodExit)

// Plot Data
plot(BuyEnter, style=plot.style_line, linewidth=2, color=color.blue, title="Buy Enter")
plot(BuyExit, style=plot.style_line, linewidth=1, color=color.blue, title="Buy Exit", transp=50)
plot(SellEnter, style=plot.style_line, linewidth=2, color=color.red, title="Sell Enter")
plot(SellExit, style=plot.style_line, linewidth=1, color=color.red, title="Sell Exit", transp=50)

// Calc Take Profits
TakeProfitBuy = 0.0
TakeProfitSell = 0.0
if strategy.position_size > 0
    TakeProfitBuy := strategy.position_avg_price*(1 + takeProfitBuy/100)
    
if strategy.position_size < 0
    TakeProfitSell := strategy.position_avg_price*(1 - takeProfitSell/100)

// Long Position    
if isBuy and timeRange
    strategy.entry("Long", strategy.long, stop = BuyEnter, when = strategy.position_size == 0) 
    
strategy.exit("Long Exit", "Long", stop=BuyExit, limit = TakeProfitBuy, when = strategy.position_size > 0)

// Short Position
if isSell and timeRange
    strategy.entry("Short", strategy.short, stop = SellEnter, when = strategy.position_size == 0) 
    
strategy.exit("Short Exit", "Short", stop=SellExit, limit = TakeProfitSell, when = strategy.position_size < 0)

// Close & Cancel when over End of the Test
if time > endTest
    strategy.close_all()
    strategy.cancel_all()

Published by ChaoZhang on the FMZ strategy square · last modified 2023-09-14. Collected in the Quant Trading Vault. Unvalidated research: re-test with your own data and costs before trusting it.

Build this with AgenKit

A spec is not a trading system. Paste this into your coding agent and AgenKit runs a specialist team — architecture, test-first build, risk gates, review — with paper trading on by default.

in Claude Code, Cursor, Codex & 4 more
/agenkit build a production-grade trading bot with a backtest engine, risk controls and paper trading by default from strategies/Donchian-Channel-Breakout-Strategy-426772.md
  1. npx agenkit install engineering-kit in your project
  2. Paste the command into your agent and approve each phase
  3. Get tests, backtest, risk controls and a paper-trading switch

Understand it first

Before you run this, read the lesson behind the idea and how to backtest it honestly. Specs like this one are the survivors of an unknown number of trials; deflate their results accordingly.

Related specs

esc

Try , , or .

↑↓ move↵ open