Strategie für den Trend der ATR bei mittlerer Umkehrung

Schriftsteller:ChaoZhang, Datum: 2023-09-21 11:42:06
Tags:

Übersicht

Diese Strategie nutzt die Höhen und Tiefen der Preisvolatilität, um den Zeitpunkt der Ein- und Ausstiege von Positionen zu bestimmen.

Strategie Logik

  1. Verwenden Sie den ATR-Indikator, um die Preisvolatilität zu messen. Berechnen Sie den ATR über die letzten 20 Perioden und erhalten Sie den gleitenden Durchschnitt und die Standardabweichung. Wenn der aktuelle ATR-Wert den Durchschnitt plus eine Standardabweichung übersteigt, gilt die Preisvolatilität als hoch.

  2. Verwenden Sie die logarithmische Preisänderungsrate erster Ordnung, um den Preistrend zu bestimmen. Berechnen Sie die logarithmische Preisänderungsrate in den letzten 20 Perioden, erhalten Sie den gleitenden Durchschnitt. Wenn die aktuelle Kursänderung den Durchschnitt für 3 aufeinanderfolgende Tage übersteigt und positiv ist, wird der Preis als Aufwärtstrend betrachtet.

  3. Wenn die Preisvolatilität hoch ist und der Preis einen Aufwärtstrend zeigt, gehen Sie lang. Wenn der Preis zurückzieht und der Stop-Loss ausgelöst wird, schließt die Position. Der Stop-Loss-Preis wird dynamisch angepasst, um unter dem niedrigsten Preis minus 2 mal ATR zu bleiben.

Analyse der Vorteile

  1. Nutzen Sie Preisschwankungen und -trends, um die lang-/kurzfristige Abweichung zu bestimmen, und vermeiden Sie Überhandelungen in verschiedenen Märkten.

  2. Dynamische Stoppverluste vermeiden einen übermäßigen Verlust bei zu breiten Stopps.

  3. Der Rücktest zeigt eine jährliche Rendite von 159% während 2015-2021 und übersteigt damit bei weitem 120% der Buy & Hold-Anleihen.

Risikoanalyse

  1. Zu aggressive ATR-Parameter können zu wenigen Einstiegsmöglichkeiten führen.

  2. Der Trendindikator kann falsche Signale erzeugen, die dem tatsächlichen Trend widersprechen.

  3. Wir brauchen eine größere Stichprobe und eine Robustheitskontrolle, um eine Überanpassung zu vermeiden.

  4. Nicht in der Lage, die Leistung unter extremen Bedingungen wie Flash-Abstürzen zu beurteilen.

Optimierungsrichtlinien

  1. Hinzufügen von mehr Trendbestätigungsindikatoren wie MACD, KDJ, um die Trendgenauigkeit zu verbessern.

  2. Die ATR-Parameter anpassungsfähig anhand verschiedener Produkte und Marktregime anpassen, um den Volatilitätsindikator zu optimieren.

  3. Fügen Sie Breakout-Logik und Trendbeschleunigungsfaktoren hinzu, um Breakouts zu ermitteln.

  4. Testen Sie verschiedene Stop-Loss-Typen wie Prozentsatz, Volatilitäts-Stop auf die Performance.

  5. Beurteilen Sie auf Metriken wie Handelsfrequenz, Kurvenstabilität, maximale Auslastung, um die Robustheit zu gewährleisten.

Zusammenfassung

Diese Strategie kombiniert die Vorteile der Messung von Volatilität und Trend, um mögliche Umkehrpunkte bei verstärkter Volatilität zu bestimmen, und verwendet dynamische Stopps, um das Risiko zu kontrollieren. Der Backtest zeigt anständige Alpha-Generationen. Aber die 6-Jahres-Stichprobe ist begrenzt, die wichtigsten Parameter müssen marktspezifisch abgestimmt werden und mehr Bestätigungsfaktoren sind erforderlich, um falsche Signale zu reduzieren. Eine umfassende Robustheitsprüfung ist auch erforderlich, bevor sie für den Live-Handel angewendet wird. Insgesamt bietet dies eine Vorstellung von einer mittleren Umkehrung der Volatilität, benötigt jedoch noch Verfeinerung und strenge Überprüfung, um zu einer robusten Quantitären Strategie zu werden.


/*backtest
start: 2022-09-14 00:00:00
end: 2023-09-20 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 (kevinhhl)

//@version=4
strategy("Mean Reversion (ATR) Strategy [KL]",overlay=true,pyramiding=1)
ENUM_LONG = "Long"

// Timeframe {
backtest_timeframe_start = input(defval = timestamp("01 Apr 2000 13:30 +0000"), title = "Backtest Start Time", type = input.time)
USE_ENDTIME = input(false,title="Define backtest end-time (If false, will test up to most recent candle)")
backtest_timeframe_end = input(defval = timestamp("01 May 2021 19:30 +0000"), title = "Backtest End Time (if checked above)", type = input.time)
within_timeframe = true
// }

// Trailing stop loss {
ATR_X2_TSL = atr(input(14,title="Length of ATR for trailing stop loss")) * input(2.0,title="ATR Multiplier for trailing stop loss",type=input.float)
TSL_source = low
var stop_loss_price = float(0)
TSL_line_color = color.green, TSL_transp = 100
if strategy.position_size == 0 or not within_timeframe
    TSL_line_color := color.black
    stop_loss_price := TSL_source - ATR_X2_TSL 
else if strategy.position_size > 0
    stop_loss_price := max(stop_loss_price, TSL_source - ATR_X2_TSL)
    TSL_transp := 0
plot(stop_loss_price, color=color.new(TSL_line_color, TSL_transp))
// }

// Variables for confirmations of entry {
_len_volat = input(20,title="Length of ATR to determine volatility")
_ATR_volat = atr(_len_volat)
_avg_atr = sma(_ATR_volat, _len_volat)
_std_volat = stdev(_ATR_volat,_len_volat)
signal_diverted_ATR = _ATR_volat > (_avg_atr + _std_volat) or _ATR_volat < (_avg_atr - _std_volat)

_len_drift = input(20,title="Length of Drift")//default set to const: _len_vol's default value
_prcntge_chng = log(close/close[1])
_drift = sma(_prcntge_chng, _len_drift) - pow(stdev(_prcntge_chng, _len_drift),2)*0.5
_chg_drift = _drift/_drift[1]-1
signal_uptrend = (_drift > _drift[1] and _drift > _drift[2]) or _drift > 0

entry_signal_all = signal_diverted_ATR and signal_uptrend
// }

alert_per_bar(msg)=>
    prefix = "[" + syminfo.root + "] "
    suffix = "(P=" + tostring(close) + "; atr=" + tostring(_ATR_volat) + ")"
    alert(tostring(prefix) + tostring(msg) + tostring(suffix), alert.freq_once_per_bar)

// MAIN {
if within_timeframe

    if strategy.position_size > 0 and strategy.position_size[1] > 0 and (stop_loss_price/stop_loss_price[1]-1) > 0.005
        alert_per_bar("TSL raised to " + tostring(stop_loss_price))

    // EXIT:
	if strategy.position_size > 0 and TSL_source <= stop_loss_price
	    exit_msg = close <= strategy.position_avg_price ? "stop loss" : "take profit"
        strategy.close(ENUM_LONG, comment=exit_msg)
    // ENTRY:
    else if entry_signal_all and (strategy.position_size == 0 or (strategy.position_size > 0 and close > stop_loss_price))
		entry_msg = strategy.position_size > 0 ? "adding" : "initial"
		strategy.entry(ENUM_LONG, strategy.long, comment=entry_msg)

if strategy.position_size == 0
    stop_loss_price := float(0)
// }


Mehr