Handelsstrategie für die Schwingungsschwingung

Schriftsteller:ChaoZhang, Datum: 26.09.2023
Tags:

Übersicht

Dies ist eine momentumbasierte Strategie, die Oszillatorenindikatoren wie RSI, Stoch, MACD verwendet, um Handelssignale zu generieren. Die Hauptidee ist es, die Trendrichtung zu identifizieren, wenn der Preis durch Indikatoren oszilliert und Trades basierend auf Indikatorsignalen eingeht. Die Strategie verwendet auch verzögerten Supertrend für Stop Loss.

Strategie Logik

Die Strategie ruft zunächst die benutzerdefinierte Funktion f_getOscilatorValues auf, um Werte verschiedener Oszillatorindikatoren zu erhalten, einschließlich RSI, Stoch, MACD usw. Dann berechnet sie mit f_getSupertrend verzögerte Supertrend-Werte, um den Stop-Loss zu verfolgen.

Nach der Berechnung der Indikatoren ruft die Strategie f_getBuySellStops auf, um Entry Stops und Gewinnziele basierend auf Indikatorwerten zu berechnen. Insbesondere berechnet sie ATR und verwendet ATR multipliziert mit einem Stop-Loss-Koeffizienten als Entry Stop und ATR multipliziert mit einem Take-Profit-Koeffizient als Gewinnziel. Die Stops und Ziele werden angepasst, wenn sich der Trend umkehrt.

Als nächstes bestimmt die Strategie die Kerzenrichtung. Die Aufwärtstrendkerzen sind grün und die Abwärtstrendkerzen rot gefärbt. Nach der Erstellung von Kerzen und Indikatoren überprüft die Strategie, ob die Einstiegsbedingungen erfüllt sind. Die Einstiegsbedingungen sind Kauf, wenn der Indikator überkauft zeigt und der Preis über dem oberen Band bricht, und Verkauf, wenn der Indikator überverkauft zeigt und der Preis unter dem unteren Band bricht.

Nach dem Eintritt wird der Stop-Loss durch das obere/untere Band gefolgt, je nachdem, welches näher ist. Wenn der Stop-Loss ausgelöst wird, wird die Position geschlossen. Wenn der Preis das Gewinnziel erreicht, wird ein Teilgewinn erzielt.

Analyse der Vorteile

Die Vorteile dieser Strategie sind:

  1. Die Verwendung von Oszillatoren zur Identifizierung der Trendrichtung kann kurzfristige Umkehrchancen rechtzeitig erfassen.

  2. Die Anwendung eines verzögerten Supertrend-Stop-Loss kann vor Verlustzuwächsen gestoppt werden, wodurch ein einziger Handelsverlust begrenzt wird.

  3. Die Berechnung von Stop-Loss- und Gewinnzielen auf der Grundlage des dynamischen ATR hilft bei der Anpassung der Positionsgröße.

  4. Die Filterung mit einem höheren Zeitrahmen des gleitenden Durchschnitts verhindert, in Konsolidierungen gefangen zu werden.

  5. Eine teilweise Gewinnentnahme lässt den Gewinn laufen, während ein gewisser Gewinn eingeschlossen wird.

  6. Die Logik ist einfach und leicht verständlich für Anfänger im Quant-Trading.

Risikoanalyse

Zu den Risiken dieser Strategie gehören:

  1. Oszillatoren können Verzögerungsprobleme haben, was zu verzögerten Ein- und vorzeitigen Ausstiegssignalen führt. Dies kann durch Optimierung von Parametern oder durch Hinzufügen von Trendindikatoren verbessert werden.

  2. Der Stop-Loss-Bereich kann erweitert werden oder dynamische Stops wie Chandelier verwendet werden können.

  3. Die nach der Teilgewinnentnahme verbleibenden Positionen können eingestellt und die Teilgewinnquote gesenkt werden.

  4. Die Strategie sollte auf verschiedenen Märkten validiert werden.

  5. Ausfall des höheren Zeitrahmen gleitenden Durchschnittsfilters: Trendklassifikationsmethoden sollten zusammen verwendet werden.

Anweisungen zur Verbesserung

Die Strategie kann in folgenden Aspekten optimiert werden:

  1. Testen Sie verschiedene Kombinationen von Oszillatorparametern und finden Sie diejenigen, die Qualitätssignale liefern.

  2. Versuchen Sie, die partielle Gewinnnahme durch einen auf ATR oder gleitenden Durchschnitten basierenden Profitstop zu ersetzen.

  3. Hinzufügen von Algorithmen für maschinelles Lernen, um gleitende Durchschnitte für die Trendanalyse zu ersetzen und die Genauigkeit zu verbessern.

  4. Um unnötige Umkehrungen zu vermeiden, werden als Filterbedingungen Volumenindikatoren hinzugefügt.

  5. Zusammenstellung und Gewichtung von Optimierungsindicatoren, um die optimale Kombination für den Vermögenswert zu finden.

  6. Hinzufügen von Modulen zur Steuerung von Maschinellen Lernrisiken zur dynamischen Optimierung von Stopps, Zielen und Positionsgrößen.

  7. Einbeziehung von dreieckigen Arbitrage- oder Basishandelssignalen unter Verwendung von Kursspreads zwischen Futures und Spot.

Schlussfolgerung

Insgesamt ist dies eine großartige Strategie für Quant-Trading-Anfänger mit einer klaren Logik, die sich auf Indikatoren und Risikomanagement konzentriert. Für den Live-Handel sind jedoch noch Parameteroptimierung und Risikominderung erforderlich. Es kann auch in Aspekten wie Trendanalyse, Stop-Loss-Optimierung, Ensemble-Modelle usw. verbessert werden, um die Robustheit zu verbessern. Als Handelsstrategievorlage bietet es eine wertvolle Referenz.


/*backtest
start: 2023-08-26 00:00:00
end: 2023-09-25 00:00:00
period: 1h
basePeriod: 15m
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("Oscilator 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)

oscilatorType = input(title="Oscliator Type", defval="stoch", options=["rsi", "stoch", "cog", "macd", "tsi", "cci", "cmo", "mfi"])
length = input(3)
shortlength = input(3)
longlength = input(9)

showSupertrend = input(true)
AtrMAType = input(title="Moving Average Type", defval="rma", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
AtrLength = input(30, step=10)
stopMultiplier  = input(4)
targetMultiplier  = input(3)
wicks = input(true)
considerWicksForDelayByStep = input(false)
colorByPreviousClose = input(true)

useHTFPivot = input(false)
resolution = input("12M", type=input.resolution)
HTFMultiplier = input(4, title="Higher Timeframe multiplier (Used when resolution is set to Same as Symbol)", minval=2, step=1)
PivotLength = input(2, step=1)

tradeDirection = input(title="Trade Direction", defval=strategy.direction.long, options=[strategy.direction.all, strategy.direction.long, strategy.direction.short])
i_startTime = input(defval = timestamp("01 Jan 2010 00:00 +0000"), title = "Backtest Start Time", type = input.time)
i_endTime = input(defval = timestamp("01 Jan 2099 00:00 +0000"), title = "Backtest End Time", type = input.time)
inDateRange = true

f_getOscilatorValues(oscilatorType, length, shortlength, longlength)=>
    oOpen = rsi(open, length)
    oClose = rsi(close, length)
    oHigh = rsi(high, length)
    oLow = rsi(low, length)
    if(oscilatorType == "tsi")
        oOpen := tsi(open, shortlength, longlength)
        oClose := tsi(close, shortlength, longlength)
        oHigh := tsi(high, shortlength, longlength)
        oLow := tsi(low, shortlength, longlength)
    if(oscilatorType == "stoch")
        oOpen := stoch(open, longlength, shortlength, length)
        oClose := stoch(close, longlength, shortlength, length)
        oHigh := stoch(high, longlength, shortlength, length)
        oLow := stoch(low, longlength, shortlength, length)
    if(oscilatorType == "cci")
        oOpen := cci(open, length)
        oClose := cci(close, length)
        oHigh := cci(high, length)
        oLow := cci(low, length)
    if(oscilatorType == "cog")
        oOpen := cog(open, length)
        oClose := cog(close, length)
        oHigh := cog(high, length)
        oLow := cog(low, length)
    if(oscilatorType == "cmo")
        oOpen := cmo(open, length)
        oClose := cmo(close, length)
        oHigh := cmo(high, length)
        oLow := cmo(low, length)
    if(oscilatorType == "mfi")
        oOpen := mfi(open, length)
        oClose := mfi(close, length)
        oHigh := mfi(high, length)
        oLow := mfi(low, length)
    if(oscilatorType == "macd")
        [macdLineOpen, signalLineOpen, histLineOpen] = macd(open, shortlength, longlength, length)
        [macdLineClose, signalLineClose, histLineClose] = macd(close, shortlength, longlength, length)
        [macdLineHigh, signalLineHigh, histLineHigh] = macd(high, shortlength, longlength, length)
        [macdLineLow, signalLineLow, histLineLow] = macd(low, shortlength, longlength, length)
        oOpen := macdLineOpen
        oClose := macdLineClose
        oHigh := macdLineHigh
        oLow := macdLineLow
    [oOpen, oClose, oHigh, oLow]

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

f_getSupertrend(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, stopMultiplier, wicks)=>
    truerange = max(oHigh, oClose[1]) - min(oLow, oClose[1])
    
    averagetruerange = f_getMovingAverage(truerange, AtrMAType, AtrLength)
    atr = averagetruerange * stopMultiplier

    longStop = oClose - atr
    longStopPrev = nz(longStop[1], longStop)
    longStop := (wicks ? oLow[1] : oClose[1]) > longStopPrev ? max(longStop, longStopPrev) : longStop
    
    shortStop = oClose + atr
    shortStopPrev = nz(shortStop[1], shortStop)
    shortStop := (wicks ? oHigh[1] : oClose[1]) < shortStopPrev ? min(shortStop, shortStopPrev) : shortStop
    
    dir = 1
    dir := nz(dir[1], dir)
    dir := dir == -1 and (wicks ? oHigh : oClose) > shortStopPrev ? 1 : dir == 1 and (wicks ? oLow : oClose) < longStopPrev ? -1 : dir
    
    trailingStop = dir == 1? longStop : shortStop
    
    [dir, trailingStop]


f_getBuySellStops(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, considerWicks, considerWicksForDelayByStep, stopMultiplier, targetMultiplier)=>
    barState = 0
    source = oClose
    
    truerange = max(oHigh, oClose[1]) - min(oLow, oClose[1])
    
    atr = f_getMovingAverage(truerange, AtrMAType, AtrLength)

    buyStop = source - atr * stopMultiplier
    sellStop = source + atr * stopMultiplier
    buyStopDerived = buyStop
    sellStopDerived = sellStop
    highTarget = considerWicks ? oHigh : source
    lowTarget = considerWicks ? oLow : source
    
    highTargetDelayByStep = considerWicksForDelayByStep ? oHigh : source
    lowTargetDelayByStep = considerWicksForDelayByStep ? oLow : source
    
    barState := highTarget > sellStopDerived[1] ? 1 : lowTarget < buyStopDerived[1] ? -1 : nz(barState[1],0)
    
    buyMultiplier = (barState == 1)? stopMultiplier : targetMultiplier
    sellMultiplier = (barState == -1)? stopMultiplier : targetMultiplier
    buyStop := source - atr * buyMultiplier
    sellStop := source + atr * sellMultiplier
    buyStop := barState == 1? max(buyStop, buyStop[1]) : barState == -1? min(buyStop, buyStop[1]) : buyStop
    sellStop := barState == 1? max(sellStop, sellStop[1]) : barState == -1? min(sellStop, sellStop[1]) : sellStop
    
    buyStopDerived := buyStop
    sellStopDerived := sellStop
    
    buyStopDerived := highTargetDelayByStep < sellStopDerived[1] and lowTargetDelayByStep > buyStopDerived[1] ? buyStopDerived[1] : buyStopDerived
    sellStopDerived := highTargetDelayByStep < sellStopDerived[1] and lowTargetDelayByStep > buyStopDerived[1] ? sellStopDerived[1] : sellStopDerived

    [buyStopDerived, sellStopDerived, barState]


f_secureSecurity(_symbol, _res, _src) => security(_symbol, _res, _src[1], lookahead = barmerge.lookahead_on, gaps=barmerge.gaps_off)

f_multiple_resolution(HTFMultiplier) => 
    target_Res_In_Min = timeframe.multiplier * HTFMultiplier * (
      timeframe.isseconds   ? 1. / 60. :
      timeframe.isminutes   ? 1. :
      timeframe.isdaily     ? 1440. :
      timeframe.isweekly    ? 7. * 24. * 60. :
      timeframe.ismonthly   ? 30.417 * 24. * 60. : na)

    target_Res_In_Min     <= 0.0417       ? "1S"  :
      target_Res_In_Min   <= 0.167        ? "5S"  :
      target_Res_In_Min   <= 0.376        ? "15S" :
      target_Res_In_Min   <= 0.751        ? "30S" :
      target_Res_In_Min   <= 1440         ? tostring(round(target_Res_In_Min)) :
      tostring(round(min(target_Res_In_Min / 1440, 365))) + "D"
    
f_getPivotHighLow(oOpen, oClose, oHigh, oLow, HTFMultiplier, resolution, PivotLength)=>
    derivedResolution = resolution == ""? f_multiple_resolution(HTFMultiplier) : resolution
    HTFHigh = f_secureSecurity(syminfo.tickerid, derivedResolution, oHigh)
    HTFLow = f_secureSecurity(syminfo.tickerid, derivedResolution, oLow)
    CLOSEprev = f_secureSecurity(syminfo.tickerid, derivedResolution, oClose)
    pivothi = pivothigh(HTFHigh, PivotLength, PivotLength)
    pivotlo = pivotlow(HTFLow, PivotLength, PivotLength)
    pivothi := na(pivothi)? nz(pivothi[1]) : pivothi
    pivotlo := na(pivotlo)? nz(pivotlo[1]) : pivotlo
    [pivothi, pivotlo]
    
[oOpen, oClose, oHigh, oLow] = f_getOscilatorValues(oscilatorType, length, shortlength, longlength)
[dir, trailingStop] = f_getSupertrend(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, stopMultiplier, wicks)

candleColor = colorByPreviousClose ?
                 (oClose[1] < oClose ? color.green : oClose[1] > oClose ? color.red : color.silver) : 
                 (oOpen < oClose ? color.green : oOpen > oClose ? color.red : color.silver)
plotcandle(oOpen, oHigh, oLow, oClose, 'Oscilator Candles', color = candleColor)

[buyStopDerived, sellStopDerived, barState] = f_getBuySellStops(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, wicks, considerWicksForDelayByStep, stopMultiplier, targetMultiplier)

trailingStopDerived = barState == 1? buyStopDerived : sellStopDerived

plot(showSupertrend?trailingStopDerived:na, title="TrailingStop", style=plot.style_linebr, linewidth=1, color= barState == 1 ? color.green : color.red)

[pivotHigh, pivotLow] = f_getPivotHighLow(open, close, high, low, HTFMultiplier, resolution, PivotLength)

buyCondition = (barState == 1) and (close > pivotHigh or not useHTFPivot)
exitBuyConditin = (barState == -1)
sellCondition = (barState == -1) and (close < pivotLow or not useHTFPivot)
exitSellCondition = (barState == 1)

// strategy.risk.allow_entry_in(tradeDirection)
strategy.entry("Buy", strategy.long, when=buyCondition and inDateRange, oca_name="oca")
strategy.entry("Sell", strategy.short, when=sellCondition and inDateRange, oca_name="oca")
strategy.close("Buy", when = exitBuyConditin)
strategy.close( "Sell", when = exitSellCondition)

Mehr