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.
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.
Die Vorteile dieser Strategie sind:
Die Verwendung von Oszillatoren zur Identifizierung der Trendrichtung kann kurzfristige Umkehrchancen rechtzeitig erfassen.
Die Anwendung eines verzögerten Supertrend-Stop-Loss kann vor Verlustzuwächsen gestoppt werden, wodurch ein einziger Handelsverlust begrenzt wird.
Die Berechnung von Stop-Loss- und Gewinnzielen auf der Grundlage des dynamischen ATR hilft bei der Anpassung der Positionsgröße.
Die Filterung mit einem höheren Zeitrahmen des gleitenden Durchschnitts verhindert, in Konsolidierungen gefangen zu werden.
Eine teilweise Gewinnentnahme lässt den Gewinn laufen, während ein gewisser Gewinn eingeschlossen wird.
Die Logik ist einfach und leicht verständlich für Anfänger im Quant-Trading.
Zu den Risiken dieser Strategie gehören:
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.
Der Stop-Loss-Bereich kann erweitert werden oder dynamische Stops wie Chandelier verwendet werden können.
Die nach der Teilgewinnentnahme verbleibenden Positionen können eingestellt und die Teilgewinnquote gesenkt werden.
Die Strategie sollte auf verschiedenen Märkten validiert werden.
Ausfall des höheren Zeitrahmen gleitenden Durchschnittsfilters: Trendklassifikationsmethoden sollten zusammen verwendet werden.
Die Strategie kann in folgenden Aspekten optimiert werden:
Testen Sie verschiedene Kombinationen von Oszillatorparametern und finden Sie diejenigen, die Qualitätssignale liefern.
Versuchen Sie, die partielle Gewinnnahme durch einen auf ATR oder gleitenden Durchschnitten basierenden Profitstop zu ersetzen.
Hinzufügen von Algorithmen für maschinelles Lernen, um gleitende Durchschnitte für die Trendanalyse zu ersetzen und die Genauigkeit zu verbessern.
Um unnötige Umkehrungen zu vermeiden, werden als Filterbedingungen Volumenindikatoren hinzugefügt.
Zusammenstellung und Gewichtung von Optimierungsindicatoren, um die optimale Kombination für den Vermögenswert zu finden.
Hinzufügen von Modulen zur Steuerung von Maschinellen Lernrisiken zur dynamischen Optimierung von Stopps, Zielen und Positionsgrößen.
Einbeziehung von dreieckigen Arbitrage- oder Basishandelssignalen unter Verwendung von Kursspreads zwischen Futures und Spot.
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)