Strategi ini menggunakan Indeks Arah Rata-rata (DI +) dan Indeks Arah Negatif (DI-) pada dua kerangka waktu untuk menentukan arah tren untuk perdagangan panjang dan pendek. Ketika DI + lebih tinggi dari DI- pada kedua kerangka waktu yang lebih besar dan lebih kecil, itu menunjukkan tren naik dan sinyal panjang dipicu. Ketika DI- lebih tinggi dari DI + pada kedua kerangka waktu, itu menunjukkan tren menurun dan sinyal pendek dipicu.
Strategi ini didasarkan pada beberapa prinsip:
Menghitung DI + dan DI-. Dapatkan DI + dan DI- dengan menggunakan harga tinggi, dekat dan rendah.
Bandingkan DI+ dan DI- pada dua kerangka waktu. Hitung DI+ dan DI- masing-masing pada kerangka waktu grafik utama (misalnya 1 jam) dan kerangka waktu yang lebih besar (misalnya setiap hari). Bandingkan nilai antara kedua kerangka waktu.
Tentukan arah tren. Ketika DI + lebih besar dari DI- pada kedua kerangka waktu yang lebih besar dan lebih kecil, ini menunjukkan tren kenaikan. Ketika DI - lebih besar dari DI + pada kedua kerangka waktu, ini menunjukkan tren penurunan.
DI+>DI- pada kedua frame memberikan sinyal panjang. DI->DI+ pada kedua frame memberikan sinyal pendek.
Gunakan ATR untuk menghitung stop loss dinamis untuk mengikuti tren.
Kondisi keluar. Keluar ketika stop loss tercapai atau harga terbalik.
Strategi ini memiliki keuntungan berikut:
Menggunakan dual timeframe DI menyaring beberapa kabur palsu.
ATR trailing stop memaksimalkan perlindungan keuntungan dan menghindari berhenti terlalu ketat.
Stop loss tepat waktu mengendalikan kerugian pada perdagangan tunggal.
Perdagangan dengan tren memungkinkan terus menangkap tren.
Aturan sederhana dan jelas, mudah diterapkan untuk perdagangan langsung.
Ada juga beberapa risiko:
DI memiliki efek keterlambatan, mungkin melewatkan waktu masuk.
Kerangka waktu ganda mungkin memiliki divergensi antara TF yang lebih besar dan lebih kecil. Tambahkan validasi kerangka waktu lebih banyak.
Stop loss yang terlalu agresif bisa menyebabkan over-trading.
Whipsaw di pasar samping dapat menyebabkan perdagangan yang sering.
Optimasi parameter bergantung pada data historis dan mungkin terlalu banyak.
Strategi ini dapat ditingkatkan dalam hal berikut:
Mengoptimalkan parameter perhitungan DI untuk set parameter terbaik.
Tambahkan filter indikator lain untuk meningkatkan akurasi sinyal, misalnya MACD, KDJ dll.
Meningkatkan strategi stop loss untuk menyesuaikan lebih banyak kondisi pasar, seperti trailing stop atau pending orders.
Tambahkan filter sesi perdagangan untuk menghindari peristiwa berita penting.
Uji ketahanan parameter pada produk yang berbeda untuk meningkatkan kemampuan beradaptasi.
Memperkenalkan pembelajaran mesin untuk melatih model pada data historis.
Singkatnya, ini adalah strategi trend following khas yang menggunakan DI untuk menentukan arah tren dan mengatur stop loss untuk mengunci keuntungan di sepanjang tren. Keuntungannya terletak pada logika yang jelas dan kemudahan implementasi untuk perdagangan langsung. Ada juga ruang untuk perbaikan melalui optimasi parameter, menambahkan filter dll. Dengan optimasi lebih lanjut dan pengujian ketahanan, ini bisa menjadi strategi trend following yang sangat praktis.
/*backtest start: 2022-10-31 00:00:00 end: 2023-11-06 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © DojiEmoji //@version=5 strategy("DI+/- multi TF Strat [KL]", overlay=true, pyramiding=1, initial_capital=1000000000, default_qty_type=strategy.percent_of_equity, default_qty_value=5) var string GROUP_ALERT = "Alerts" var string GROUP_SL = "Stop loss" var string GROUP_ORDER = "Order size" var string GROUP_TP = "Profit taking" var string GROUP_HORIZON = "Time horizon of backtests" var string GROUP_IND = "Directional IndicatorDI+ DI-" // ADX Indicator { adx_len = input(14, group=GROUP_IND, tooltip="Typically 14") tf1 = input.timeframe("", title="DI +/- in Timeframe 1", group=GROUP_IND, tooltip="Main: DI+ > DI-") tf2 = input.timeframe("1D", title="DI +/- in Timeframe 2", group=GROUP_IND, tooltip="Confirmation: DI+ > DI-") // adx_thres = input(20, group=GROUP_IND) //threshold not used in this strategy get_ADX(_high, _close, _low) => // (high, close, mid) -> [plus_DM, minus_DM] // Based on TradingView user BeikabuOyaji's implementation _tr = math.max(math.max(_high - _low, math.abs(_high - nz(_close[1]))), math.abs(_low - nz(_close[1]))) smooth_tr = 0.0 smooth_tr := nz(smooth_tr[1]) - nz(smooth_tr[1]) / adx_len + _tr smooth_directional_mov_plus = 0.0 smooth_directional_mov_plus := nz(smooth_directional_mov_plus[1]) - nz(smooth_directional_mov_plus[1]) / adx_len + (_high - nz(_high[1]) > nz(_low[1]) - _low ? math.max(_high - nz(_high[1]), 0) : 0) smooth_directional_mov_minus = 0.0 smooth_directional_mov_minus := nz(smooth_directional_mov_minus[1]) - nz(smooth_directional_mov_minus[1]) / adx_len + (nz(_low[1]) - _low > _high - nz(_high[1]) ? math.max(nz(_low[1]) - _low, 0) : 0) plus_DM = smooth_directional_mov_plus / smooth_tr * 100 minus_DM = smooth_directional_mov_minus / smooth_tr * 100 // DX = math.abs(plus_DM - minus_DM) / (plus_DM + minus_DM) * 100 // DX not used in this strategy [plus_DM, minus_DM] // DI +/- from timeframes 1 and 2 [plus_DM_tf1, minus_DM_tf1] = get_ADX(request.security(syminfo.tickerid, tf1, high), request.security(syminfo.tickerid, tf1, close),request.security(syminfo.tickerid, tf1, low)) [plus_DM_tf2, minus_DM_tf2] = get_ADX(request.security(syminfo.tickerid, tf2, high),request.security(syminfo.tickerid, tf2, close),request.security(syminfo.tickerid, tf2, low)) // } end of block: ADX Indicator var string ENUM_LONG = "LONG" var string LONG_MSG_ENTER = input.string("Long entered", title="Alert MSG for buying (Long position)", group=GROUP_ALERT) var string LONG_MSG_EXIT = input.string("Long closed", title="Alert MSG for closing (Long position)", group=GROUP_ALERT) backtest_timeframe_start = input(defval=timestamp("01 Apr 2020 13:30 +0000"), title="Backtest Start Time", group=GROUP_HORIZON) within_timeframe = true // Signals for entry _uptrend_confirmed = plus_DM_tf1 > minus_DM_tf1 and plus_DM_tf2 > minus_DM_tf2 entry_signal_long = _uptrend_confirmed plotshape(_uptrend_confirmed, style=shape.triangleup, location=location.bottom, color=color.green) plotshape(not _uptrend_confirmed, style=shape.triangledown, location=location.bottom, color=color.red) // Trailing stop loss ("TSL") { tsl_multi = input.float(2.0, title="ATR Multiplier for trailing stoploss", group=GROUP_SL) SL_buffer = ta.atr(input.int(14, title="Length of ATR for trailing stoploss", group=GROUP_SL)) * tsl_multi TSL_source_long = low var stop_loss_price_long = float(0) var pos_opened_long = false stop_loss_price_long := pos_opened_long ? math.max(stop_loss_price_long, TSL_source_long - SL_buffer) : TSL_source_long - SL_buffer // MAIN: { if pos_opened_long and TSL_source_long <= stop_loss_price_long pos_opened_long := false alert(LONG_MSG_EXIT, alert.freq_once_per_bar) strategy.close(ENUM_LONG, comment=close < strategy.position_avg_price ? "stop loss" : "take profit") // (2) Update the stoploss to latest trailing amt. if pos_opened_long strategy.exit(ENUM_LONG, stop=stop_loss_price_long, comment="SL") // (3) INITIAL ENTRY: if within_timeframe and entry_signal_long pos_opened_long := true alert(LONG_MSG_ENTER, alert.freq_once_per_bar) strategy.entry(ENUM_LONG, strategy.long, comment="long") // Plotting: TSL_transp_long = pos_opened_long and within_timeframe ? 0 : 100 plot(stop_loss_price_long, color=color.new(color.green, TSL_transp_long)) // CLEAN UP: Setting variables back to default values once no longer in use if ta.change(strategy.position_size) and strategy.position_size == 0 pos_opened_long := false if not pos_opened_long stop_loss_price_long := float(0) // } end of MAIN block