Strategi Donchian Trend Following dikembangkan berdasarkan prinsip Donchian Channel yang dijelaskan dalam artikel
Strategi ini didasarkan pada indikator Saluran Donchian untuk menilai arah tren. Saluran Donchian terdiri dari saluran periode yang lebih lama dan saluran periode yang lebih pendek. Ketika harga menembus saluran periode yang lebih lama, itu menandakan awal tren. Ketika harga menembus saluran periode yang lebih pendek, itu menandakan akhir tren.
Secara khusus, panjang saluran jangka panjang adalah 50 hari atau 20 hari, dan panjang saluran jangka pendek adalah 50 hari, 20 hari atau 10 hari. Jika harga sama dengan harga tertinggi dalam 50 hari, posisi panjang dibuka. Jika harga sama dengan harga terendah dalam 50 hari, posisi pendek dibuka. Jika harga sama dengan harga terendah dalam 20 atau 10 hari, posisi panjang ditutup. Jika harga sama dengan harga tertinggi dalam 20 atau 10 hari, posisi pendek ditutup.
Dengan menggabungkan dua Saluran Donchian dari periode yang berbeda, dapat menentukan arah untuk menetapkan posisi ketika tren dimulai, dan menyadari stop loss tepat waktu ketika tren berakhir.
Keuntungan utama dari strategi ini adalah:
Kemampuan yang kuat untuk menangkap tren. Ini dapat melacak tren secara efektif dengan mengidentifikasi awal dan akhir tren menggunakan penyemburan Saluran Donchian.
Mengontrol risiko yang tepat. Ini menggunakan stop loss bergerak untuk mengendalikan kerugian perdagangan tunggal.
Penyesuaian parameter yang fleksibel. Kombinasi periode saluran dapat dipilih secara bebas untuk beradaptasi dengan produk dan lingkungan pasar yang berbeda.
Logika perdagangan yang sederhana dan jelas.
Risiko dari strategi ini meliputi:
Ketidakmampuan untuk beradaptasi dengan pasar yang terikat rentang.
Risiko kegagalan penembusan. Harga mungkin mundur setelah menembus saluran, menyebabkan stop loss.
Risiko pemilihan periode: pengaturan periode saluran yang tidak tepat dapat menyebabkan perdagangan kebisingan.
Risiko penurunan rasio Sharpe. Meningkatkan ukuran posisi tanpa menyesuaikan stop loss dapat menyebabkan penurunan rasio Sharpe.
Solusinya adalah:
Arah optimasi untuk strategi ini:
Menambahkan kondisi filter untuk menghindari whipsaws, misalnya menggabungkan volume untuk menilai breakout yang sebenarnya.
Mengoptimalkan kombinasi periode saluran dan ukuran posisi untuk meningkatkan rasio keuntungan. Stop loss adaptif dapat diperkenalkan.
Mencoba pengoptimalan titik putus untuk menemukan set parameter optimal.
Meningkatkan algoritma pembelajaran mesin untuk optimasi dinamis dan penyesuaian parameter.
Donchian Trend Following Strategy mengidentifikasi awal dan akhir tren harga menggunakan saluran ganda, dan mengadopsi gaya perdagangan trend dengan kontrol kerugian perdagangan tunggal yang efektif. Strategi ini memiliki penyesuaian parameter yang fleksibel dan penerapan yang mudah, menjadikannya strategi trend berikut yang sangat praktis.
/*backtest start: 2023-12-01 00:00:00 end: 2023-12-31 23:59:59 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=5 strategy(title="Donchian", overlay=true, pyramiding=0, initial_capital=1000, commission_type=strategy.commission.cash_per_order, commission_value=2, slippage=2) // ============================================================================= // VARIABLES // ============================================================================= donch_string = input.string(title="Length", options = ['20/10','50/20', '50/50', '20/20', '100/100'], defval='50/50') permit_long = input.bool(title = 'Permit long', defval = true) permit_short = input.bool(title = 'Permit short', defval = true) risk_percent = input.float(title="Position Risk %", defval=0.5, step=0.25) stopOffset = input.float(title="ATR mult", defval=2.0, step=0.5) atrLen = input.int(title="ATR Length", defval=20) close_in_end = input.bool(title = 'Close in end', defval = true) permit_stop = input.bool(title = 'Permit stop', defval = false) // ============================================================================= // CALCULATIONS // ============================================================================= donch_len_big = donch_string == '50/20' ? 50 : donch_string == '50/50' ? 50 : donch_string == '20/20' ? 20 : donch_string == '20/10' ? 20 : donch_string == '100/100' ? 100 : na donch_len_small = donch_string == '50/20' ? 20 : donch_string == '50/50' ? 50 : donch_string == '20/20' ? 20 : donch_string == '20/10' ? 10 : donch_string == '100/100' ? 100 : na big_maxclose = ta.highest(close, donch_len_big) big_minclose = ta.lowest(close, donch_len_big) small_maxclose = ta.highest(close, donch_len_small) small_minclose = ta.lowest(close, donch_len_small) atrValue = ta.atr(atrLen)[1] tradeWindow = true // ============================================================================= // NOTOPEN QTY // ============================================================================= risk_usd = (risk_percent / 100) * strategy.equity atr_currency = (atrValue * syminfo.pointvalue) notopen_qty = risk_usd / (stopOffset * atr_currency) // ============================================================================= // LONG STOP // ============================================================================= long_stop_price = 0.0 long_stop_price := strategy.position_size > 0 and na(long_stop_price[1]) ? strategy.position_avg_price - stopOffset * atrValue : strategy.position_size > 0 and strategy.openprofit > risk_usd ? strategy.position_avg_price: strategy.position_size > 0 ? long_stop_price[1] : na // ============================================================================= // SHORT STOP // ============================================================================= short_stop_price = 0.0 short_stop_price := strategy.position_size < 0 and na(short_stop_price[1]) ? strategy.position_avg_price + stopOffset * atrValue : strategy.position_size < 0 and strategy.openprofit > risk_usd ? strategy.position_avg_price : strategy.position_size < 0 ? short_stop_price[1] : na // ============================================================================= // PLOT VERTICAL COLOR BAR // ============================================================================= cross_up = strategy.position_size <= 0 and close == big_maxclose and close >= syminfo.mintick and tradeWindow and permit_long cross_dn = strategy.position_size >= 0 and close == big_minclose and close >= syminfo.mintick and tradeWindow and permit_short bg_color = cross_up ? color.green : cross_dn ? color.red : na bg_color := color.new(bg_color, 70) bgcolor(bg_color) // ============================================================================= // PLOT DONCHIAN LINES // ============================================================================= s1 = cross_up ? na : cross_dn ? na : strategy.position_size != 0 ? strategy.position_avg_price : na s2 = cross_up ? na : cross_dn ? na : strategy.position_size > 0 ? small_minclose : strategy.position_size < 0 ? small_maxclose : na s3 = cross_up ? na : cross_dn ? na : not permit_stop ? na : strategy.position_size > 0 ? long_stop_price : strategy.position_size < 0 ? short_stop_price : na plot(series=big_maxclose, style=plot.style_linebr, color=color.black, linewidth=1, title="Donch Big Maxclose Black") plot(series=big_minclose, style=plot.style_linebr, color=color.black, linewidth=1, title="Donch Big Minclose Black") plot(series=s1, style=plot.style_linebr, color=color.yellow, linewidth=2, title="Entry Yellow") plot(series=s2, style=plot.style_linebr, color=color.red, linewidth=1, title="Donch Small Red") plot(series=s3, style=plot.style_linebr, color=color.fuchsia, linewidth=2, title="Stop Fuchsia") // ============================================================================= // ENTRY ORDERS // ============================================================================= if strategy.position_size <= 0 and close == big_maxclose and close >= syminfo.mintick and tradeWindow and permit_long strategy.entry("Long", strategy.long, qty=notopen_qty) if strategy.position_size >= 0 and close == big_minclose and close >= syminfo.mintick and tradeWindow and permit_short strategy.entry("Short", strategy.short, qty=notopen_qty) // ============================================================================= // EXIT ORDERS // ============================================================================= if strategy.position_size > 0 and permit_stop strategy.exit(id="Stop", from_entry="Long", stop=long_stop_price) if strategy.position_size < 0 and permit_stop strategy.exit(id="Stop", from_entry="Short", stop=short_stop_price) // ========== if strategy.position_size > 0 and close == small_minclose and not barstate.islast strategy.close(id="Long", comment='Donch') if strategy.position_size < 0 and close == small_maxclose and not barstate.islast strategy.close(id="Short", comment='Donch') // ========== if close_in_end if not tradeWindow strategy.close_all(comment='Close in end') // ============================================================================= // END // =============================================================================