Adaptive Bollinger-Trendverfolgungsstrategie

Schriftsteller:ChaoZhang, Datum: 2023-11-16 16:35:01
Tags:

img

Übersicht

Diese Strategie basiert auf dem Bollinger Bands-Indikator, kombiniert mit einem anpassungsfähigen gleitenden Durchschnitt, um Trends genau zu beurteilen und zu verfolgen.

Strategie Logik

Die Strategie besteht aus folgenden Hauptteilen:

  1. Berechnen Sie den adaptiven gleitenden Durchschnitt. Verwenden Sie den linearen Regressionsindikator, um die lineare Regressionskurve über einen bestimmten Zeitraum als gleitenden Durchschnitt zu berechnen.

  2. Berechnen Sie Bollinger-Bänder. Verwenden Sie den adaptiven ATR-Indikator zur Berechnung von Bands, kombiniert mit dem vom Benutzer angegebenen Parameter ratio2, um obere und untere Bands zu erhalten.

  3. Bestimmung von Ein- und Ausstiegen. Beurteilen Sie die Trendrichtung und die Ein- und Ausstiege anhand des Preisbruchs durch Bollinger-Bänder. Durchbrechen der oberen Bandsignale verkaufen den Einstieg und durchbrechen der unteren Bandsignale den Kauf.

  4. Setzen Sie Stop Loss und nehmen Sie Gewinn. Verwenden Sie feste Stop Loss-Punkte, um Risiken zu kontrollieren, und Trailing Stop Profit, um den Trendgewinn zu maximieren.

  5. Kombinieren Sie mit Backtesting Zeitfenster für Strategieoptimierung und Verifizierung.

Vorteile

  1. Adaptive gleitende Durchschnitte und Banddesign passen sich den Marktveränderungen an.

  2. Bollinger-Band-Break-outs bieten deutliche Trendumkehrsignale.

  3. Eine feste Stop-Loss-Einstellung kontrolliert die Risiken, und eine nachträgliche Stop-Profit-Einstellung zielt darauf ab, den Trendgewinn zu maximieren.

  4. Das Backtesting-Fenster überprüft die Wirksamkeit der Strategie.

  5. Einfach zu verstehen und umzusetzen. Die Logik ist klar und der Code ist prägnant, um leicht zu verstehen.

Risiken

  1. Bollinger Bands benötigen Parameter-Tuning. Bandbreite und Periode können für verschiedene Produkte optimiert werden müssen. Falsche Parameter führen zu fehlenden Signalen oder falschen Auslösern.

  2. Begrenzte Backtestdauer: Der jüngste Backtest-Bereich ist möglicherweise nicht ausreichend, um die Stabilität umfassender historischer Daten vollständig zu überprüfen.

  3. Das Risiko einer Überanpassung: Aktuelle optimierte Parameter können sich in jüngeren spezifischen Marktbedingungen zu sehr anpassen.

  4. Der Stop-Loss-Level muss ausgewertet werden. Kleine Stop-Loss-Leistungen können zu empfindlich sein und durch kleine Schwankungen gestoppt werden. Geeignete Stop-Loss-Leistungen müssen bewertet werden.

  5. Mangelnde quantifizierbare Validierung: Derzeit wird nur für Handelssignale ohne quantifizierbare Metriken-Validierung ein grafischer Ausbruch verwendet.

Verbesserungsrichtlinien

  1. Einführung anpassungsfähigerer Indikatoren und Prüfung von Kombinationen verschiedener anpassungsfähiger gleitender Durchschnitte und Kanäle, um ein robustes Trendverfolgungssystem aufzubauen.

  2. Verwenden Sie systematischere Methoden wie genetische Algorithmen, um eine optimale Parameterkombination zu finden.

  3. Erweiterung der Backtest-Periode. Test auf breitere historische Daten zur Untersuchung der Parameterstabilität. Einbeziehung von Transaktionskosten für realistischere Backtest.

  4. Stellen Sie quantitative Filter ein, z. B. Volumen-Breakout, MACD-Histogramm-Lücke, um falsche Breakouts zu vermeiden.

  5. Optimieren Sie Stops. Beurteilen Sie verschiedene feste Stop-Loss-Level und Trailing-Stop-Methoden, um optimale Stops zu finden.

  6. Live-Validierung. Laufen Sie die optimierte Strategie live, um die Leistung für weitere Verbesserungen zu erfassen.

Schlussfolgerung

Die Strategie hat eine klare Logik, die Bollinger Bands verwendet, um die Trendrichtung zu bestimmen und Breakout-Signale zu erfassen, wobei der gleitende Durchschnitt den Gesamttrend definiert. Mit geeigneten Optimierungen kann es zu einem stabilen und zuverlässigen Trend nach der Strategie werden. Zu den wichtigsten Überlegungen gehören jedoch die Repräsentativität von Backtests, quantitative Filter und Stop-Loss-Tuning. Wenn diese Aspekte gut gehandhabt werden, kann die Strategie im Live-Handel stetige und beträchtliche Gewinne erzielen.


/*backtest
start: 2023-10-16 00:00:00
end: 2023-11-09 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy("Linear Regression (Backtest / Trailing Stop)",overlay=true)
close_price = close[0]

len = input(40)
linear_reg = linreg(close_price, len, 0)

calculationToPlotAverageMeanLine=linear_reg
useUpperDeviation = input(true, "Upper Deviation", bool)
useLowerDeviation = input(true, "Lower Deviation", bool)
ratio2=input(defval=2,title=" Ratio 2")
avg=atr(len)
r2=avg*ratio2
top=linear_reg+r2
bott=linear_reg-r2

calculationToPlotUpperLine=top
calculationToPlotLowerLine=bott

plotUpperDeviationLine = plot(not useUpperDeviation ? na : calculationToPlotUpperLine, color=color(blue,0))
plotAverageMeanLine = plot(calculationToPlotAverageMeanLine, color=color(olive,0))
plotLowererDeviationLine = plot(not useLowerDeviation ? na : calculationToPlotLowerLine, color=color(red,0))
fill(plotUpperDeviationLine, plotAverageMeanLine, color=color(blue,85))
fill(plotLowererDeviationLine, plotAverageMeanLine, color=color(red,85))


//
length = input(title="linear Length",  defval=40, minval=1)
multiplier = input(title="linear Deviation", type=float, defval=2, minval=1)
overbought = input(title="Overbought",  defval=1, minval=1)
oversold = input(title="Oversold",  defval=0, minval=1)
custom_timeframe = input(title="Use another Timeframe?", type=bool, defval=false)
highTimeFrame = input(title="Select The Timeframe",  defval="60")
res1 = custom_timeframe ? highTimeFrame : timeframe.period

fixedSL = input(title="SL Activation", defval=70)
trailSL = input(title="SL Trigger", defval=10)
fixedTP = input(title="TP Activation", defval=50)
trailTP = input(title="TP Trigger", defval=10)

// === INPUT BACKTEST RANGE ===
FromMonth = input(defval = 1, title = "From Month", minval = 1, maxval = 12)
FromDay   = input(defval = 1, title = "From Day", minval = 1, maxval = 31)
FromYear  = input(defval = 2019, title = "From Year", minval = 2015)
ToMonth   = input(defval = 1, title = "To Month", minval = 1, maxval = 12)
ToDay     = input(defval = 1, title = "To Day", minval = 1, maxval = 31)
ToYear    = input(defval = 9999, title = "To Year", minval = 2015)

start     = timestamp(FromYear, FromMonth, FromDay, 00, 00)  // backtest start window
finish    = timestamp(ToYear, ToMonth, ToDay, 23, 59)        // backtest finish window
window()  => time >= start and time <= finish ? true : false // create function "within window of time"

smabasis = linreg(close_price, length, 0)
stdev = stdev(close, length)
cierre = request.security(syminfo.tickerid, res1, close, false)
alta = request.security(syminfo.tickerid, res1, high, false)
baja = request.security(syminfo.tickerid, res1, low, false)
basis1 = request.security(syminfo.tickerid, res1, smabasis, false)
stdevb = request.security(syminfo.tickerid, res1, stdev, false)
dev = multiplier * stdevb // stdev(cierre, length)
upper = basis1 + dev
lower = basis1 - dev

bbr = (cierre - lower)/(upper - lower)

// plot(bbr)

// // MARCA LAS RESISTENCIAS
pintarojo = 0.0
pintarojo := nz(pintarojo[1])
pintarojo := bbr[1] > overbought and bbr < overbought ? alta[1] :  nz(pintarojo[1])
p = plot(pintarojo, color = red, style=circles, linewidth=2)

// // MARCA LOS SOPORTES
pintaverde = 0.0
pintaverde := nz(pintaverde[1])
pintaverde := bbr[1] < oversold and bbr > oversold ? baja[1] :  nz(pintaverde[1])
g = plot(pintaverde, color = black, style=circles, linewidth=2)
zz= crossover(pintaverde,pintaverde[1]) or crossunder(pintaverde,pintaverde[1])
kp= crossover(pintarojo,pintarojo[1]) or crossunder(pintarojo,pintarojo[1]) 
plotshape(zz,  title="buy", style=shape.triangleup,location=location.belowbar, color=green, transp=0, size=size.small)
plotshape(kp, title="sell", style=shape.triangledown,location=location.abovebar, color=red, transp=0, size=size.small)


strategy.entry("BUY", strategy.long, qty=10, oca_name="BUY",  when=zz and window())
strategy.exit("B.Exit", "BUY", qty_percent = 100, loss=fixedSL, trail_offset=trailTP, trail_points=fixedTP)

strategy.entry("SELL", strategy.short, qty=10, oca_name="SELL",  when=kp and window())
strategy.exit("S.Exit", "SELL", qty_percent = 100, loss=fixedSL, trail_offset=trailSL, trail_points=fixedTP)


Mehr