Diese Strategie verwendet Hypothesenprüfung, um festzustellen, ob ATR von seinem Durchschnittswert abweicht. Kombiniert mit der Vorhersage des Preistrends implementiert sie eine durchschnittliche Umkehrstrategie, die auf ATR basiert. Eine signifikante Abweichung von ATR zeigt eine mögliche abnorme Volatilität auf dem Markt an. Wenn der Preistrend bullisch prognostiziert wird, kann eine Long-Position eingerichtet werden.
Hypothesenprüfung
T-Test mit zwei Stichproben zwischen schneller ATR-Periode (atr_fast) und langsamer ATR-Periode (atr_slow) durchführen. Nullhypothese H0 ist, dass zwischen den beiden Stichprobenmittelwerten kein signifikanter Unterschied besteht.
Überschreitet die Prüfstatistik den Schwellenwert (Vertrauensintervall, der durch den Reliability_factor angegeben wird), so wird die Nullhypothese abgelehnt, d. h. die schnelle ATR wird als deutlich von der langsamen ATR abweichend angesehen.
Prognose der Preisentwicklung
Der gleitende Durchschnitt der logarithmischen Renditen wird als erwartete Driftrate (Drift) berechnet.
Wenn die Drift zunimmt, wird der aktuelle Trend als bullisch beurteilt.
Eintritt und Stop-Loss-Ausgang
Es ist nicht möglich, die Verteilung der Zinssätze zu erleichtern, da die Zinssätze in der Regel nicht in der Zinsspanne liegen.
Sie müssen die Position, wenn der Preis unter den Stop-Loss-Wert fällt, fortlaufend anpassen.
Die Verwendung von Hypothesenprüfungen zur Bestimmung der ATR-Abweichung ist wissenschaftlicher und anpassungsfähiger.
Die Kombination mit der Prognose der Preisentwicklung verhindert falsche Geschäfte, die ausschließlich auf der ATR-Abweichung basieren.
Durch die Anpassung des Stop-Loss wird das Abwärtsrisiko kontinuierlich gesteuert.
Unfähig, Verluste zu stoppen, wenn der Preis abstürzt.
Eine falsche Trendvorhersage kann dazu führen, dass man an der Spitze kauft.
Bei falschen Parameter-Einstellungen kann die richtige Eingabe fehlen oder unnötige Trades hinzugefügt werden.
Um Fehler zu vermeiden, sollten weitere Indikatoren für die mehrfache Bestätigung hinzugefügt werden.
Versuche verschiedene Kombinationen von ATR-Parametern, um stabilere Werte zu finden.
Hinzufügen von Kriterien für den Durchbruch der zentralen Preisniveaus, um einen falschen Ausbruch zu vermeiden.
Die allgemeine Logik dieser Strategie ist klar. Die Verwendung von Hypothesenprüfung zur Erkennung von abnormaler Volatilität ist vernünftig. Allerdings ist die ATR-Abweichung allein nicht ausreichend, um den Trend zu bestimmen. Mehr Bestätigungsfaktoren sind erforderlich, um die Genauigkeit zu verbessern. Die Stop-Loss-Regeln sind zuverlässig, aber unwirksam gegen Klippen-Crashs. Zukünftige Verbesserungen können in Bereichen wie Einstiegskriterien, Parameterwahl, Stop-Loss-Optimierung vorgenommen werden.
/*backtest start: 2022-10-16 00:00:00 end: 2023-10-16 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("Mean Reversion (ATR) Strategy v2 [KL] ", overlay=true, pyramiding=1) var string ENUM_LONG = "Long" var string GROUP_TEST = "Hypothesis testing" var string GROUP_TSL = "Stop loss" var string GROUP_TREND = "Trend prediction" backtest_timeframe_start = input(defval=timestamp("01 Apr 2000 13:30 +0000"), title="Backtest Start Time") within_timeframe = true // TSL: calculate the stop loss price. { ATR_TSL = ta.atr(input(14, title="Length of ATR for trailing stop loss", group=GROUP_TSL)) * input(2.0, title="ATR Multiplier for trailing stop loss", group=GROUP_TSL) TSL_source = low TSL_line_color = color.green TSL_transp = 100 var stop_loss_price = float(0) if strategy.position_size == 0 or not within_timeframe TSL_line_color := color.black stop_loss_price := TSL_source - ATR_TSL else if strategy.position_size > 0 stop_loss_price := math.max(stop_loss_price, TSL_source - ATR_TSL) TSL_transp := 0 plot(stop_loss_price, color=color.new(TSL_line_color, TSL_transp)) // } end of "TSL" block // Entry variables { // ATR diversion test via Hypothesis testing (2-tailed): // H0 : atr_fast equals atr_slow // Ha : reject H0 if z_stat is above critical value, say reliability factor of 1.96 for a 95% confidence interval len_fast = input(14,title="Length of ATR (fast) for diversion test", group=GROUP_TEST) atr_fast = ta.atr(len_fast) std_error = ta.stdev(ta.tr, len_fast) / math.pow(len_fast, 0.5) // Standard Error (SE) = std / sq root(sample size) atr_slow = ta.atr(input(28,title="Length of ATR (slow) for diversion test", group=GROUP_TEST)) test_stat = (atr_fast - atr_slow) / std_error reject_H0 = math.abs(test_stat) > input.float(1.645,title="Reliability factor", tooltip="Strategy uses 2-tailed test; Confidence Interval = Point Estimate (avg ATR) +/- Reliability Factor x Standard Error; i.e use 1.645 for a 90% confidence interval", group=GROUP_TEST) // main entry signal, subject to confirmation(s), gets passed onto the next bar var _signal_diverted_ATR = false if not _signal_diverted_ATR _signal_diverted_ATR := reject_H0 // confirmation: trend prediction; based on expected lognormal returns _prcntge_chng = math.log(close / close[1]) // Expected return (drift) = average percentage change + half variance over the lookback period len_drift = input(14, title="Length of drift", group=GROUP_TREND) _drift = ta.sma(_prcntge_chng, len_drift) - math.pow(ta.stdev(_prcntge_chng, len_drift), 2) * 0.5 _signal_uptrend = _drift > _drift[1] entry_signal_all = _signal_diverted_ATR and _signal_uptrend // main signal + confirmations // } end of "Entry variables" block // MAIN { // Update the stop limit if strategy holds a position if strategy.position_size > 0 and ta.change(stop_loss_price) strategy.exit(ENUM_LONG, comment="sl", stop=stop_loss_price) // Entry if within_timeframe and entry_signal_all strategy.entry(ENUM_LONG, strategy.long, comment=strategy.position_size > 0 ? "adding" : "initial") // Alerts _atr = ta.atr(14) alert_helper(msg) => prefix = "[" + syminfo.root + "] " suffix = "(P=" + str.tostring(close, "#.##") + "; atr=" + str.tostring(_atr, "#.##") + ")" alert(str.tostring(prefix) + str.tostring(msg) + str.tostring(suffix), alert.freq_once_per_bar) if strategy.position_size > 0 and ta.change(strategy.position_size) if strategy.position_size > strategy.position_size[1] alert_helper("BUY") else if strategy.position_size < strategy.position_size[1] alert_helper("SELL") // Clean up - set the variables back to default values once no longer in use if strategy.position_size == 0 stop_loss_price := float(0) if ta.change(strategy.position_size) _signal_diverted_ATR := false // } end of MAIN block