Chiến lược DI theo xu hướng đa khung thời gian


Ngày tạo: 2023-11-07 16:31:07 sửa đổi lần cuối: 2023-11-07 16:31:07
sao chép: 0 Số nhấp chuột: 644
1
tập trung vào
1617
Người theo dõi

Chiến lược DI theo xu hướng đa khung thời gian

Tổng quan

Chiến lược này dựa trên chỉ số xu hướng trung bình DI + và DI - , sử dụng chỉ số DI của hai khung thời gian khác nhau để xác định xu hướng xu hướng và sau đó làm nhiều lỗ hổng. Khi cả DI + của khung thời gian lớn hơn và khung thời gian nhỏ hơn đều cao hơn DI - , đánh giá xu hướng lạc quan, làm nhiều; Khi cả hai khung thời gian DI - đều cao hơn DI +, đánh giá xu hướng giảm giá, làm nhiều lỗ hổng.

Nguyên tắc

Chiến lược này dựa trên các nguyên tắc sau:

  1. Tính DI+ và DI- bằng cách lấy giá cao, giá đóng cửa, giá thấp.

  2. So sánh hai khung thời gian DI+ và DI-。 tương ứng với khung thời gian chính (chẳng hạn như 1 giờ) và khung thời gian lớn hơn (chẳng hạn như đường mặt trời) tính DI+ và DI-, và so sánh mối quan hệ lớn nhỏ.

  3. Xác định hướng xu hướng. Khi cả DI + của khung thời gian lớn hơn và khung thời gian nhỏ hơn đều lớn hơn DI- thì đánh giá là xu hướng đa đầu; khi cả hai khung thời gian đều lớn hơn DI + thì đánh giá là xu hướng đầu không.

  4. Gửi tín hiệu giao dịch. Tín hiệu đa đầu cho hai khung thời gian DI+>DI-, làm nhiều; tín hiệu đầu trống cho hai khung thời gian DI->DI+, làm trống.

  5. Thiết lập dừng. Dựa trên ATR tính toán điểm dừng, thực hiện theo dõi xu hướng dừng.

  6. Điều kiện rút lui: Hạ lỗ khi kích hoạt hoặc giá đảo ngược.

Phân tích lợi thế

Chiến lược này có những ưu điểm sau:

  1. Sử dụng DI khung thời gian kép để đánh giá xu hướng, bạn có thể lọc ra một số đột phá giả.

  2. ATR theo dõi động các lệnh dừng để bảo vệ lợi nhuận tối đa và tránh các lệnh dừng quá nhỏ.

  3. Lưu ý rằng các khoản lỗ có thể được kiểm soát khi các khoản lỗ này được thực hiện.

  4. Giao dịch theo xu hướng có thể tiếp tục nắm bắt cơ hội xu hướng.

  5. Quy tắc rõ ràng, dễ hiểu và dễ sử dụng.

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

Chiến lược này cũng có những rủi ro sau:

  1. Chỉ số DI bị chậm trễ, có thể bỏ lỡ thời gian nhập cảnh. Các tham số có thể được tối ưu hóa thích hợp, hoặc kết hợp với các chỉ số khác.

  2. Có thể có sự phân biệt trên và dưới của phán đoán khung thời gian kép. Có thể thêm tín hiệu xác minh khung thời gian.

  3. Lệnh dừng quá mạnh có thể dẫn đến giao dịch quá thường xuyên. ATR có thể được nới lỏng thích hợp.

  4. Các giao dịch có thể xảy ra thường xuyên trong tình huống xung đột.

  5. Tối ưu hóa tham số phụ thuộc vào dữ liệu lịch sử, trong đó có thể có quá trình tối ưu hóa.

Hướng tối ưu hóa

Chiến lược này có thể được tối ưu hóa bằng cách:

  1. Tối ưu hóa các tham số tính toán của DI, tìm kiếm sự kết hợp tham số tốt nhất.

  2. Thêm bộ lọc cho các chỉ số khác để tăng độ chính xác tín hiệu. Ví dụ như MACD, KDJ.

  3. Tối ưu hóa chiến lược dừng lỗ để thích ứng với nhiều điều kiện thị trường hơn. Có thể thay đổi để dừng lỗ di động hoặc dừng lệnh.

  4. Tiếp theo, các nhà đầu tư sẽ có thêm các bộ lọc thời gian giao dịch để tránh các sự kiện tin tức quan trọng.

  5. Kiểm tra sức mạnh của các tham số khác nhau của giống để cải thiện khả năng thích ứng.

  6. Thêm thành phần học máy, sử dụng mô hình phán đoán được đào tạo bằng dữ liệu lịch sử.

Tóm tắt

Chiến lược này nói chung là một chiến lược theo dõi xu hướng điển hình, sử dụng chỉ số DI để xác định hướng xu hướng, thiết lập dừng lỗ để khóa lợi nhuận, và tiếp tục lợi nhuận trong xu hướng. Ưu điểm của chiến lược này là tư duy chiến lược rõ ràng, dễ vận hành trong thực tế.

Mã nguồn chiến lược
/*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