Xu hướng DI hai khung thời gian theo chiến lược

Tác giả:ChaoZhang, Ngày: 2023-11-07 16:31:07
Tags:

img

Tổng quan

Chiến lược này sử dụng chỉ số hướng trung bình (DI +) và chỉ số hướng tiêu cực (DI-) trên hai khung thời gian để xác định hướng xu hướng cho các giao dịch dài và ngắn. Khi DI + cao hơn DI - trên cả hai khung thời gian lớn và nhỏ hơn, nó chỉ ra xu hướng tăng và tín hiệu dài được kích hoạt. Khi DI - cao hơn DI + trên cả hai khung thời gian, nó chỉ ra xu hướng giảm và tín hiệu ngắn được kích hoạt.

Làm thế nào nó hoạt động

Chiến lược dựa trên một số nguyên tắc:

  1. Tính toán DI + và DI-. Nhận DI + và DI- bằng cách sử dụng giá cao, gần và thấp.

  2. So sánh DI + và DI- trên hai khung thời gian. Tính toán DI + và DI- tương ứng trên khung thời gian biểu chính (ví dụ 1 giờ) và khung thời gian lớn hơn (ví dụ hàng ngày). So sánh các giá trị giữa hai khung thời gian.

  3. Xác định hướng xu hướng. Khi DI + lớn hơn DI- trên cả hai khung thời gian lớn và nhỏ hơn, nó cho thấy xu hướng tăng. Khi DI- lớn hơn DI + trên cả hai khung thời gian, nó cho thấy xu hướng giảm.

  4. DI+>DI- trên cả hai khung cung cấp tín hiệu dài DI->DI+ trên cả hai khung cung cấp tín hiệu ngắn

  5. Thiết lập stop loss. Sử dụng ATR để tính toán stop loss động để theo xu hướng.

  6. Điều kiện thoát. thoát khi dừng lỗ bị tấn công hoặc giá đảo ngược.

Ưu điểm

Chiến lược có những lợi thế sau:

  1. Sử dụng khung thời gian hai DI lọc ra một số sự đột phá sai.

  2. ATR trailing stop tối đa hóa bảo vệ lợi nhuận và tránh dừng quá chặt.

  3. Dừng lỗ kịp thời kiểm soát lỗ trên các giao dịch đơn.

  4. Giao dịch theo xu hướng cho phép liên tục bắt được xu hướng.

  5. Quy tắc đơn giản và rõ ràng, dễ thực hiện cho giao dịch trực tiếp.

Rủi ro và giải pháp

Ngoài ra còn có một số rủi ro:

  1. DI có hiệu ứng chậm trễ, có thể bỏ lỡ thời gian nhập. Có thể tối ưu hóa các thông số hoặc thêm các chỉ số khác.

  2. Khung thời gian kép có thể có sự khác biệt giữa TF lớn hơn và nhỏ hơn. Thêm xác nhận khung thời gian nhiều hơn.

  3. Giữ lỗ quá mạnh có thể gây ra giao dịch quá mức.

  4. Whipsaw trong thị trường bên có thể gây ra các giao dịch thường xuyên.

  5. Tối ưu hóa tham số dựa trên dữ liệu lịch sử và có thể bị quá tải. Đánh giá độ bền của tham số một cách thận trọng.

Hướng dẫn tối ưu hóa

Chiến lược có thể được cải thiện trong các khía cạnh sau:

  1. Tối ưu hóa các tham số tính toán DI cho bộ tham số tốt nhất.

  2. Thêm các bộ lọc chỉ số khác để cải thiện độ chính xác tín hiệu, ví dụ: MACD, KDJ v.v.

  3. Cải thiện chiến lược dừng lỗ để thích nghi với nhiều điều kiện thị trường hơn, chẳng hạn như dừng lại hoặc lệnh đang chờ.

  4. Thêm các bộ lọc phiên giao dịch để tránh các sự kiện tin tức quan trọng.

  5. Kiểm tra độ bền của tham số trên các sản phẩm khác nhau để cải thiện khả năng thích nghi.

  6. giới thiệu máy học để đào tạo mô hình trên dữ liệu lịch sử.

Kết luận

Tóm lại, đây là một chiến lược theo xu hướng điển hình sử dụng DI để xác định hướng xu hướng và đặt dừng lỗ để khóa lợi nhuận dọc theo xu hướng. Ưu điểm nằm trong logic rõ ràng và dễ thực hiện cho giao dịch trực tiếp.


/*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


Thêm nữa