Tren DI Dual Timeframe Mengikuti Strategi

Penulis:ChaoZhang, Tanggal: 2023-11-07 16:31:07
Tag:

img

Gambaran umum

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.

Cara Kerjanya

Strategi ini didasarkan pada beberapa prinsip:

  1. Menghitung DI + dan DI-. Dapatkan DI + dan DI- dengan menggunakan harga tinggi, dekat dan rendah.

  2. 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.

  3. 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.

  4. DI+>DI- pada kedua frame memberikan sinyal panjang. DI->DI+ pada kedua frame memberikan sinyal pendek.

  5. Gunakan ATR untuk menghitung stop loss dinamis untuk mengikuti tren.

  6. Kondisi keluar. Keluar ketika stop loss tercapai atau harga terbalik.

Keuntungan

Strategi ini memiliki keuntungan berikut:

  1. Menggunakan dual timeframe DI menyaring beberapa kabur palsu.

  2. ATR trailing stop memaksimalkan perlindungan keuntungan dan menghindari berhenti terlalu ketat.

  3. Stop loss tepat waktu mengendalikan kerugian pada perdagangan tunggal.

  4. Perdagangan dengan tren memungkinkan terus menangkap tren.

  5. Aturan sederhana dan jelas, mudah diterapkan untuk perdagangan langsung.

Risiko dan Solusi

Ada juga beberapa risiko:

  1. DI memiliki efek keterlambatan, mungkin melewatkan waktu masuk.

  2. Kerangka waktu ganda mungkin memiliki divergensi antara TF yang lebih besar dan lebih kecil. Tambahkan validasi kerangka waktu lebih banyak.

  3. Stop loss yang terlalu agresif bisa menyebabkan over-trading.

  4. Whipsaw di pasar samping dapat menyebabkan perdagangan yang sering.

  5. Optimasi parameter bergantung pada data historis dan mungkin terlalu banyak.

Arahan Optimasi

Strategi ini dapat ditingkatkan dalam hal berikut:

  1. Mengoptimalkan parameter perhitungan DI untuk set parameter terbaik.

  2. Tambahkan filter indikator lain untuk meningkatkan akurasi sinyal, misalnya MACD, KDJ dll.

  3. Meningkatkan strategi stop loss untuk menyesuaikan lebih banyak kondisi pasar, seperti trailing stop atau pending orders.

  4. Tambahkan filter sesi perdagangan untuk menghindari peristiwa berita penting.

  5. Uji ketahanan parameter pada produk yang berbeda untuk meningkatkan kemampuan beradaptasi.

  6. Memperkenalkan pembelajaran mesin untuk melatih model pada data historis.

Kesimpulan

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


Lebih banyak