Handelsstrategie für Bollinger-Prozentsätze

Schriftsteller:ChaoZhang, Datum: 2023-12-11 11:14:53
Tags:

img

Übersicht

Diese Strategie basiert auf dem Bollinger Bands-Indikator, kombiniert mit gleitenden Durchschnitten und dem ATR-Technischen Indikator, um ein kurzfristiges Breakout-System zu implementieren.

Strategie Logik

  1. Berechnung des Bollinger-Bands-Kanals und der relativen Prozentsatzposition der Preise innerhalb des Kanals
  2. Berechnen Sie gleitende Durchschnitte für die Eröffnungs-, Schließ-, Höchst- und Tiefkurse separat
  3. Berechnung des ATR-Indikators und Festlegung von Stop-Loss-Linien in Kombination mit ATR
  4. Beurteilen Sie, ob die Preise in der Nähe neuer Höchstwerte oder neuer Tiefstände liegen
  5. Verknüpfen Sie jährliche Höchstwerte und Tiefstände, um größere zeitliche Trends zu beurteilen
  6. Erstellen von Handelssignalen basierend auf Veränderungen der Bollinger Bands und neuen Höchst-/Tiefwerten

Diese Strategie verwendet den Bollinger Bands-Kanal, um die Volatilität des Marktes zu beurteilen, wobei die Kanalbreite durch Standardabweichung bestimmt wird. Kaufsignale werden erzeugt, wenn die Preise unter das untere Band fallen und Verkaufssignale, wenn die Preise über das obere Band fallen. Bewegliche Durchschnitte können Bollinger-Schwankungen glätten und falsche Ausbrüche reduzieren.

Vorteile

  1. Strenge Bollinger-Band-Breakout-Filter helfen, falsche Signale zu reduzieren
  2. Gleitende Durchschnitte sorgen für einen reibungslosen Preisverlauf und erkennen die wahren Trends
  3. Der ATR-Indikator verfolgt dynamisch Stop-Loss und begrenzt Einzelhandelsverluste
  4. Neue Höchstwerte und jährliche Höchstwerte machen die Signale verlässlicher
  5. Eine effektive Kombination mehrerer Indikatoren verbessert die Effizienz

Risiken und Lösungen

  1. Bei falschen Bollinger-Band-Parametern kann es zu übermäßigen falschen Ausbrüchen kommen. Für optimale Ergebnisse sollten verschiedene Parameterkombinationen getestet werden
  2. Der Referenzpreis für den Schlusskurs kann zu Ziehungen führen, die den für ATR festgelegten Stop-Loss-Bereich übersteigen; für die Prozentsatzberechnung sollten volatilere Hoch-/Niedrigpreise verwendet werden.
  3. Eine strenge Bollinger-Filterung kann einige längerfristige Trendchancen verpassen, Filter und Haltezeit entsprechend lockern
  4. Der ATR-Indikator verfolgt große Preisschwankungen langsam, betrachten Sie höhere Frequenzvolatilitätsmaßnahmen wie den wahren Bereich
  5. Neue Höchst-/Tiefstbrüche werden leicht durch kurzfristiges Rauschen gestört, statistische Signifikanz und Trendnachhaltigkeit bewertet

Optimierungsrichtlinien

  1. Versuche verschiedene Parameterkombinationen zur Bestimmung optimaler Bollingerparameter und gleitender Durchschnittslängen
  2. Verwenden Sie Modellkombinationen, die verschiedene Bollinger-Parameter oder gleitende Durchschnitte enthalten
  3. Robustheit über verschiedene Zeitrahmen und Produkte hinweg testen, Anpassungsfähigkeit verbessern
  4. Einbeziehen Sie höhere Zeitrahmensignale wie tägliche Bollinger-Signale oder saisonale Faktoren
  5. Bewertung der Chancen, die sich aus dem Trend ergeben, um die Strategie abdecken und die Rentabilität zu erweitern

Schlussfolgerung

Diese Strategie kombiniert effektiv Bollinger-Prozentsatzbänder, gleitende Durchschnitte, den ATR-Indikator, neue Höchststände/Tiefstände und jährliche Höchststände/Tiefstände, um ein relativ strenges und effizientes kurzfristiges Breakout-Handelssystem zu konstruieren. Sein herausragender Vorteil liegt darin, verschiedene Tools zu verwenden, um Lärm zu reduzieren und wahre Trendsignale zu identifizieren. Natürlich ist die Strategie auch mit einigen Parameter-Tuning-Schwierigkeiten und verpassten Möglichkeiten unter strengen Bedingungen konfrontiert. Insgesamt stellt sie einen einzigartigen Handelsstil und eine hocheffiziente Bollinger-Breakout-Strategie dar, die weitere Forschung und Validierung auf realen Handelsdaten rechtfertigt.


/*backtest
start: 2022-12-04 00:00:00
end: 2023-12-10 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/
// © HeWhoMustNotBeNamed

//@version=4
strategy("Bollinger %B Candles Strategy", overlay=false, initial_capital = 1000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, pyramiding = 1, commission_value = 0.01, calc_on_order_fills = true)

BBLength = input(100, minval=1, step=1)
StdDev = 10
useMovingAverage = input(true)
MAType = input(title="Moving Average Type", defval="rma", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
lookbackPeriod = input(22, minval=10, step=10)
colorByPreviousClose = input(true)

AtrMAType = input(title="Moving Average Type", defval="hma", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
AtrLength = input(10)
AtrMult = input(4)
wicks = input(false)

considerYearlyHighLow = input(false)
considerNewLongTermHighLows = input(false)
shortHighLowPeriod = 100
longHighLowPeriod = 200
tradeDirection = input(title="Trade Direction", defval=strategy.direction.all, options=[strategy.direction.all, strategy.direction.long, strategy.direction.short])

backtestYears = input(10, minval=1, step=1)


//////////////////////////////////// Calculate new high low condition //////////////////////////////////////////////////
f_calculateNewHighLows(shortHighLowPeriod, longHighLowPeriod, considerNewLongTermHighLows)=>
    newHigh = highest(shortHighLowPeriod) == highest(longHighLowPeriod) or not considerNewLongTermHighLows
    newLow = lowest(shortHighLowPeriod) == lowest(longHighLowPeriod) or not considerNewLongTermHighLows
    [newHigh,newLow]

//////////////////////////////////// Calculate Yearly High Low //////////////////////////////////////////////////
f_getYearlyHighLowCondition(considerYearlyHighLow)=>
    yhigh = security(syminfo.tickerid, '12M', high[1]) 
    ylow = security(syminfo.tickerid, '12M', low[1]) 
    yhighlast = yhigh[365]
    ylowlast = ylow[365]
    yhighllast = yhigh[2 * 365]
    ylowllast = ylow[2 * 365]
    
    yearlyTrendUp = na(yhigh)? true : na(yhighlast)? close > yhigh : na(yhighllast)? close > max(yhigh,yhighlast) : close > max(yhigh, min(yhighlast, yhighllast))
    yearlyHighCondition = (  (na(yhigh) or na(yhighlast) ? true : (yhigh > yhighlast) ) and ( na(yhigh) or na(yhighllast) ? true : (yhigh > yhighllast))) or yearlyTrendUp or not considerYearlyHighLow
    yearlyTrendDown = na(ylow)? true : na(ylowlast)? close < ylow : na(ylowllast)? close < min(ylow,ylowlast) : close < min(ylow, max(ylowlast, ylowllast))
    yearlyLowCondition = (  (na(ylow) or na(ylowlast) ? true : (ylow < ylowlast) ) and ( na(ylow) or na(ylowllast) ? true : (ylow < ylowllast))) or yearlyTrendDown or not considerYearlyHighLow
    
    label_x = time+(60*60*24*1000*1)
    [yearlyHighCondition,yearlyLowCondition]

f_getMovingAverage(source, MAType, length)=>
    ma = sma(source, length)
    if(MAType == "ema")
        ma := ema(source,length)
    if(MAType == "hma")
        ma := hma(source,length)
    if(MAType == "rma")
        ma := rma(source,length)
    if(MAType == "vwma")
        ma := vwma(source,length)
    if(MAType == "wma")
        ma := wma(source,length)
    ma

inDateRange = true
[yearlyHighCondition,yearlyLowCondition] = f_getYearlyHighLowCondition(considerYearlyHighLow)
[newHighS,newLowS] = f_calculateNewHighLows(shortHighLowPeriod, longHighLowPeriod, considerNewLongTermHighLows)
[middleclose, upperclose, lowerclose] = bb(close, BBLength, StdDev)
[middleopen, upperopen, loweropen] = bb(open, BBLength, StdDev)
[middlehigh, upperhigh, lowerhigh] = bb(high, BBLength, StdDev)
[middlelow, upperlow, lowerlow] = bb(low, BBLength, StdDev)

percentBClose = (close - lowerclose)*100/(upperclose-lowerclose)
percentBOpen = (open - loweropen)*100/(upperopen-loweropen)
percentBHigh = (high - lowerhigh)*100/(upperhigh-lowerhigh)
percentBLow = (low - lowerlow)*100/(upperlow-lowerlow)

percentBMAClose = f_getMovingAverage(percentBClose, MAType, lookbackPeriod)
percentBMAOpen = f_getMovingAverage(percentBOpen, MAType, lookbackPeriod)
percentBMAHigh = f_getMovingAverage(percentBHigh, MAType, lookbackPeriod)
percentBMALow = f_getMovingAverage(percentBLow, MAType, lookbackPeriod)

newOpen = useMovingAverage? percentBMAOpen : percentBOpen
newClose = useMovingAverage? percentBMAClose : percentBClose
newHigh = useMovingAverage? percentBMAHigh : percentBHigh
newLow = useMovingAverage? percentBMALow : percentBLow

truerange = max(newHigh, newClose[1]) - min(newLow, newClose[1])

averagetruerange = f_getMovingAverage(truerange, AtrMAType, AtrLength)
atr = averagetruerange * AtrMult

longStop = newClose - atr
longStopPrev = nz(longStop[1], longStop)
longStop := (wicks ? newLow[1] : newClose[1]) > longStopPrev ? max(longStop, longStopPrev) : longStop

shortStop = newClose + atr
shortStopPrev = nz(shortStop[1], shortStop)
shortStop := (wicks ? newHigh[1] : newClose[1]) < shortStopPrev ? min(shortStop, shortStopPrev) : shortStop

dir = 1
dir := nz(dir[1], dir)
dir := dir == -1 and (wicks ? newHigh : newClose) > shortStopPrev ? 1 : dir == 1 and (wicks ? newLow : newClose) < longStopPrev ? -1 : dir

trailingStop = dir == 1? longStop : shortStop

candleColor = colorByPreviousClose ?
                 (newClose[1] < newClose ? color.green : newClose[1] > newClose ? color.red : color.silver) : 
                 (newOpen < newClose ? color.green : newOpen > newClose ? color.red : color.silver)
plotcandle(newOpen, newHigh, newLow, newClose, title='PercentBCandle', color = candleColor, wickcolor=candleColor)
plot(trailingStop, title="TrailingStop", style=plot.style_linebr, linewidth=1, color= dir == 1 ? color.green : color.red)

buyCondition = dir==1 and yearlyHighCondition and newHighS
exitBuyCondition = dir == -1
sellCondition = dir == -1 and yearlyLowCondition and newLowS
exitSellCondition = dir == 1
strategy.risk.allow_entry_in(tradeDirection)

barcolor(buyCondition? color.lime : sellCondition ? color.orange : color.silver)
strategy.entry("Buy", strategy.long, when=buyCondition and inDateRange, oca_name="oca_buy")
strategy.close("Buy", when=exitBuyCondition)

strategy.entry("Sell", strategy.short, when=sellCondition and inDateRange, oca_name="oca_sell")
strategy.close("Sell", when=exitSellCondition)

Mehr