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.
Die Strategie beruht auf mehreren Grundsätzen:
Berechnen Sie DI+ und DI-. Erhalten Sie DI+ und DI- mit hohen, nahen und niedrigen Preisen.
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.
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.
DI+>DI- auf beiden Frames gibt ein langes Signal.
Verwenden Sie ATR zur Berechnung des dynamischen Stop-Loss für den Trend.
Ausgangsbedingungen: Ausgang, wenn der Stop-Loss erreicht wird oder der Preis umkehrt.
Die Strategie weist folgende Vorteile auf:
Durch doppelte Zeitrahmen filtert DI einige falsche Ausbrüche aus.
Der ATR-Stopp maximiert den Gewinnschutz und verhindert, dass die Stopps zu eng sind.
Eine rechtzeitige Stop-Loss-Regelung kontrolliert Verluste bei einzelnen Trades.
Der Handel mit dem Trend erlaubt kontinuierlich Trends zu erfassen.
Einfache und klare Regeln, einfach umzusetzen für den Live-Handel.
Es gibt auch mehrere Risiken:
DI hat einen Verzögerungseffekt, kann die Eintrittszeit verpassen, kann Parameter optimieren oder andere Indikatoren hinzufügen.
Bei Doppelzeiträumen kann es zu einer Divergenz zwischen größeren und kleineren TF kommen.
Ein zu aggressiver Stop-Loss kann zu einem Überhandel führen.
Whipsaw im seitlichen Markt kann häufige Trades verursachen.
Die Optimierung der Parameter beruht auf historischen Daten und kann überfordert sein.
Die Strategie kann in folgenden Bereichen verbessert werden:
Optimierung der DI-Berechnungsparameter für den besten Parametersatz.
Hinzufügen anderer Indikatorfilter zur Verbesserung der Signalgenauigkeit, z.B. MACD, KDJ usw.
Verbesserung der Stop-Loss-Strategie, um mehr Marktbedingungen anzupassen, z. B. einen Trailing-Stop oder ausstehende Aufträge.
Fügen Sie Filter für Handelssitzungen hinzu, um wichtige Nachrichten zu vermeiden.
Versuche die Robustheit der Parameter auf verschiedenen Produkten, um die Anpassungsfähigkeit zu verbessern.
Einführung von maschinellem Lernen, um Modelle anhand historischer Daten auszubilden.
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