이중 시간 프레임 DI 트렌드 전략에 따라

저자:차오장, 날짜: 2023-11-07 16:31:07
태그:

img

전반적인 설명

이 전략은 긴 및 짧은 거래의 트렌드 방향을 결정하기 위해 두 시간 프레임에서 평균 방향 지표 (DI +) 및 부정적인 방향 지표 (DI-) 를 사용합니다. DI +가 더 크고 작은 시간 프레임 모두에서 DI-보다 높을 때 상승 추세를 나타내고 긴 신호가 유발됩니다. DI-가 두 프레임 모두에서 DI +보다 높을 때 하락 추세를 나타내고 짧은 신호가 유발됩니다.

어떻게 작동 합니까?

이 전략은 몇 가지 원칙에 기초합니다.

  1. DI+와 DI를 계산합니다. DI+와 DI-를 얻으려면 높은 가격과 가까운 가격과 낮은 가격을 사용해야 합니다.

  2. DI+와 DI-를 두 시간 프레임에 비교합니다. 주요 차트 시간 프레임 (예를 들어 1 시간) 및 더 큰 시간 프레임 (예를 들어 매일) 에 따라 DI+와 DI-를 계산합니다. 두 시간 프레임 사이의 값을 비교하십시오.

  3. 트렌드 방향을 결정한다. DI+가 더 크고 작은 두 시간 프레임에서 DI-보다 크면 상승 추세를 나타낸다. DI-가 두 프레임에서 DI+보다 크면 하락 추세를 나타낸다.

  4. 트리거 트레이딩 신호 두 프레임의 DI+>DI-는 긴 신호를 주고 두 프레임의 DI->DI+는 짧은 신호를 주고

  5. 스톱 로스를 설정하세요. 트렌드를 따르는 동적 스톱 로스를 계산하기 위해 ATR를 사용하세요.

  6. 출구 조건. 정지 손실이 발생하거나 가격이 역전되면 출구.

장점

이 전략은 다음과 같은 장점을 가지고 있습니다.

  1. 이중 타임프레임 DI를 이용해서 가짜 유출을 필터링할 수 있어요

  2. ATR 후속 스톱은 수익 보호를 극대화하고 너무 긴 스톱을 피합니다.

  3. 적시에 스톱 로스는 단일 트레이드에서 손실을 조절합니다.

  4. 트렌드를 따라 거래하면 트렌드를 지속적으로 파악할 수 있습니다.

  5. 간단하고 명확한 규칙, 실시간 거래에 적용하기 쉽습니다.

위험 과 해결책

또한 몇 가지 위험이 있습니다.

  1. DI는 지연 효과를 가지고, 입력 시기를 놓칠 수 있습니다. 매개 변수를 최적화하거나 다른 지표를 추가 할 수 있습니다.

  2. 이중 시간 프레임은 더 큰 TF와 더 작은 TF 사이에 차이가 있을 수 있습니다. 더 많은 시간 프레임 검증을 추가합니다.

  3. 너무 공격적인 스톱 로즈는 거래가 지나치게 될 수 있습니다.

  4. 시장을 편향하면 빈번한 거래가 발생할 수 있습니다.

  5. 매개 변수 최적화는 역사적 데이터에 의존하며 과장 될 수 있습니다. 매개 변수 안정성을 신중하게 평가하십시오.

최적화 방향

이 전략은 다음과 같은 측면에서 개선될 수 있습니다.

  1. 가장 좋은 매개 변수 세트를 위해 DI 계산 매개 변수를 최적화합니다.

  2. 신호 정확성을 향상시키기 위해 다른 지표 필터를 추가하십시오. 예를 들어 MACD, KDJ 등.

  3. 트래일링 스톱 또는 대기 주문과 같은 더 많은 시장 조건을 조정하기 위해 스톱 손실 전략을 개선하십시오.

  4. 중요한 뉴스 이벤트를 피하기 위해 거래 세션 필터를 추가합니다.

  5. 적응력을 향상시키기 위해 다른 제품에서 매개 변수 견고성을 테스트합니다.

  6. 기계 학습을 도입하여 역사적인 데이터로 모델을 훈련시킵니다.

결론

요약하자면, 이것은 트렌드 방향을 결정하고 트렌드를 따라 이익을 잠금하기 위해 스톱 로스를 설정하는 DI를 사용하는 전형적인 트렌드 다음 전략입니다. 이점은 라이브 트레이딩에 대한 명확한 논리와 구현의 편리함에 있습니다. 또한 매개 변수 최적화, 필터 추가 등을 통해 개선 할 여지가 있습니다. 추가 최적화 및 견고성 테스트로 매우 실용적인 트렌드 다음 전략이 될 수 있습니다.


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


더 많은