Dynamische ATR-Strategie für die Zentrallinie mit Stop-Loss

Schriftsteller:ChaoZhang, Datum: 16.10.2023
Tags:

img

Übersicht

Diese Strategie verwendet eine lineare Regressionsfunktion und die Mindestquadrate-Methode, um einen Preiskanal zu berechnen, der aus zwei grünen und roten Linien besteht.

Strategie Logik

Die Strategie berechnet die Mittellinie xLG mit linearer Regression mit Länge 25 und Verschiebung 5. Dann wird 6% über und unter der Mittellinie als Kanalbereich, mit xLG1r als obere Linie und xLG1s als untere Linie.

Wenn der Preis über xLG1r liegt, geht er lang. Wenn der Preis unter xLG1s liegt, geht er kurz. Es zeichnet die letzte lange und kurze Zeit auf. Ein langes Signal wird erzeugt, wenn die letzte lange Zeit größer ist als die letzte kurze Zeit. Ein kurzes Signal wird erzeugt, wenn die letzte kurze Zeit größer ist als die letzte lange Zeit.

Der dynamische ATR-Stop-Loss verwendet eine ATR-Periode von 1 und einen Multiplikator von 2. Für lange Trades ist der Stop-Loss der Schlusskurs minus ATR-Wert-Multiplizier. Für kurze Trades ist der Stop-Loss der Schlusskurs plus ATR-Wert-Multiplizer.

Analyse der Vorteile

  • Benutzt einen linearen Regressionskanal, um langfristige Trends zu verfolgen
  • ATR-basierte Stoppverluste werden dynamisch angepasst, damit die Stopps nicht zu breit oder zu eng sind
  • Preisschlagsignale helfen, falsche Signale zu vermeiden

Risiken und Verbesserungen

  • Regressionskanalparameter müssen optimiert werden, der Strombereich ist möglicherweise zu eng
  • Der ATR-Multiplikator muss auch getestet werden, um den optimalen Parameter zu finden
  • Überlegen Sie, eine Bestätigung zum Ausbruch hinzuzufügen, um falsche Ausbrüche zu vermeiden

Optimierungsrichtlinien

  • Verschiedene Regressionszeiten testen, um bessere Parameter zu finden
  • Versuche verschiedene ATR-Perioden und Stop-Loss-Multiplikatoren
  • Hinzufügen zusätzlicher Bestätigung auf Ausbruchsignale, wie Volumen Ausbruch

Schlussfolgerung

Diese Strategie kombiniert mehrere Techniken wie Trendfolgen, dynamische Stopps und Breakout-Signale, um ein anpassungsfähiges Trendverfolgungssystem zu schaffen.


/*backtest
start: 2023-01-01 00:00:00
end: 2023-06-24 00:00:00
period: 4h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
// Thanks to HPotter for the original code for Center of Gravity Backtest
strategy("Center of Gravity BF 🚀", overlay=true, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.15)

/////////////// Time Frame ///////////////
testStartYear = input(2017, "Backtest Start Year") 
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay, 0, 0)

testStopYear = input(2019, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(31, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay, 0, 0)

testPeriod() => true

///////////// Center of Gravity /////////////
Length = input(25, minval=1)
m = input(5, minval=0)
Percent = input(6, minval=0, title="COG %")

xLG = linreg(close, Length, m)
xLG1r = xLG + ((close * Percent) / 100)
xLG1s = xLG - ((close * Percent) / 100)

pos = 0.0
pos := iff(close > xLG1r, 1, iff(close < xLG1s, -1, nz(pos[1], 0))) 
possig = iff(pos == 1, 1, iff(pos == -1, -1, pos))

/////////////// Srategy ///////////////
long = possig == 1 
short = possig == -1 

last_long = 0.0
last_short = 0.0
last_long := long ? time : nz(last_long[1])
last_short := short ? time : nz(last_short[1])

long_signal = crossover(last_long, last_short)
short_signal = crossover(last_short, last_long)

last_open_long_signal = 0.0
last_open_short_signal = 0.0
last_open_long_signal := long_signal ? open : nz(last_open_long_signal[1])
last_open_short_signal := short_signal ? open : nz(last_open_short_signal[1])

last_long_signal = 0.0
last_short_signal = 0.0
last_long_signal := long_signal ? time : nz(last_long_signal[1])
last_short_signal := short_signal ? time : nz(last_short_signal[1])

in_long_signal = last_long_signal > last_short_signal
in_short_signal = last_short_signal > last_long_signal

last_high = 0.0
last_low = 0.0
last_high := not in_long_signal ? na : in_long_signal and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1])
last_low := not in_short_signal ? na : in_short_signal and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1])

since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1]) 
since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[1]) 

/////////////// Dynamic ATR Stop Losses ///////////////
atrLkb = input(1, minval=1, title='ATR Stop Period')
atrMult = input(2, step=0.25, title='ATR Stop Multiplier') 
atr1 = atr(atrLkb)

longStop = 0.0
longStop :=  short_signal ? na : long_signal ? close - (atr1 * atrMult) : longStop[1]
shortStop = 0.0
shortStop := long_signal ? na : short_signal ? close + (atr1 * atrMult) : shortStop[1]

/////////////// Execution ///////////////
if testPeriod()
    strategy.entry("Long",  strategy.long, when=long)
    strategy.entry("Short", strategy.short, when=short)
    strategy.exit("Long SL", "Long", stop=longStop, when=since_longEntry > 0)
    strategy.exit("Short SL", "Short", stop=shortStop, when=since_shortEntry > 0)

/////////////// Plotting ///////////////
plot(xLG1r, color=color.lime, title="LG1r")
plot(xLG1s, color=color.red, title="LG1s")
plot(strategy.position_size <= 0 ? na : longStop, title="Long Stop Loss", color=color.yellow, style=plot.style_circles, linewidth=1)
plot(strategy.position_size >= 0 ? na : shortStop, title="Short Stop Loss", color=color.orange, style=plot.style_circles, linewidth=1)
bgcolor(strategy.position_size > 0 ? color.lime : strategy.position_size < 0 ? color.red : color.white, transp=90)
bgcolor(long_signal ? color.lime : short_signal ? color.red : na, transp=60)

Mehr