Doppelzeitrahmen-DI-Trend nach Strategie

Schriftsteller:ChaoZhang, Datum: 2023-11-07 16:31:07
Tags:

img

Übersicht

Diese Strategie verwendet den Durchschnittlichen Richtungsindex (DI +) und den Negativen Richtungsindex (DI-) auf zwei Zeitrahmen, um die Trendrichtung für lange und kurze Trades zu bestimmen. Wenn DI + sowohl in größeren als auch in kleineren Zeitrahmen höher ist als DI-, zeigt dies einen Aufwärtstrend an und ein langes Signal wird ausgelöst. Wenn DI- höher ist als DI+ in beiden Rahmen, zeigt es einen Abwärtstrend an und ein kurzes Signal wird ausgelöst.

Wie es funktioniert

Die Strategie beruht auf mehreren Grundsätzen:

  1. Berechnen Sie DI+ und DI-. Erhalten Sie DI+ und DI- mit hohen, nahen und niedrigen Preisen.

  2. DI+ und DI- auf zwei Zeitrahmen vergleichen. DI+ und DI- auf dem Hauptdiagramm-Zeitrahmen (z. B. 1 Stunde) bzw. einem größeren Zeitrahmen (z. B. täglich) berechnen.

  3. Bestimmt die Trendrichtung. Wenn DI+ in größeren und kleineren Zeitrahmen größer als DI- ist, zeigt dies einen Aufwärtstrend an. Wenn DI- in beiden Zeitrahmen größer als DI+ ist, zeigt dies einen Abwärtstrend an.

  4. DI+>DI- auf beiden Frames gibt ein langes Signal.

  5. Verwenden Sie ATR zur Berechnung des dynamischen Stop-Loss für den Trend.

  6. Ausgangsbedingungen: Ausgang, wenn der Stop-Loss erreicht wird oder der Preis umkehrt.

Vorteile

Die Strategie weist folgende Vorteile auf:

  1. Durch doppelte Zeitrahmen filtert DI einige falsche Ausbrüche aus.

  2. Der ATR-Stopp maximiert den Gewinnschutz und verhindert, dass die Stopps zu eng sind.

  3. Eine rechtzeitige Stop-Loss-Regelung kontrolliert Verluste bei einzelnen Trades.

  4. Der Handel mit dem Trend erlaubt kontinuierlich Trends zu erfassen.

  5. Einfache und klare Regeln, einfach umzusetzen für den Live-Handel.

Risiken und Lösungen

Es gibt auch mehrere Risiken:

  1. DI hat einen Verzögerungseffekt, kann die Eintrittszeit verpassen, kann Parameter optimieren oder andere Indikatoren hinzufügen.

  2. Bei Doppelzeiträumen kann es zu einer Divergenz zwischen größeren und kleineren TF kommen.

  3. Ein zu aggressiver Stop-Loss kann zu einem Überhandel führen.

  4. Whipsaw im seitlichen Markt kann häufige Trades verursachen.

  5. Die Optimierung der Parameter beruht auf historischen Daten und kann überfordert sein.

Optimierungsrichtlinien

Die Strategie kann in folgenden Bereichen verbessert werden:

  1. Optimierung der DI-Berechnungsparameter für den besten Parametersatz.

  2. Hinzufügen anderer Indikatorfilter zur Verbesserung der Signalgenauigkeit, z.B. MACD, KDJ usw.

  3. Verbesserung der Stop-Loss-Strategie, um mehr Marktbedingungen anzupassen, z. B. einen Trailing-Stop oder ausstehende Aufträge.

  4. Fügen Sie Filter für Handelssitzungen hinzu, um wichtige Nachrichten zu vermeiden.

  5. Versuche die Robustheit der Parameter auf verschiedenen Produkten, um die Anpassungsfähigkeit zu verbessern.

  6. Einführung von maschinellem Lernen, um Modelle anhand historischer Daten auszubilden.

Schlussfolgerung

Zusammenfassend ist dies eine typische Trendfolging-Strategie, die DI verwendet, um die Trendrichtung zu bestimmen und einen Stop-Loss festzulegen, um Gewinne entlang des Trends zu erzielen. Der Vorteil liegt in seiner klaren Logik und der Einfachheit der Implementierung für den Live-Handel. Es gibt auch Verbesserungsmöglichkeiten durch Parameteroptimierung, Hinzufügen von Filtern usw. Mit weiterer Optimierung und Robustheitstest kann es zu einer sehr praktischen Trendfolging-Strategie werden.


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


Mehr