Diese Strategie identifiziert Umkehrchancen nach Überkauf- oder Überverkaufssituationen anhand des RSI-Indikators. Sie wird die Divergenz zwischen Preis und RSI überwachen, nachdem RSI in Überkauf- oder Überkaufzonen eingetreten ist, um mögliche zukünftige Umkehrchancen zu ermitteln.
Diese Strategie verwendet den RSI-Indikator, um die überkauften und überverkauften Situationen auf dem Markt zu bestimmen.
Wenn der RSI in die Überkaufzone eintritt, überwacht er insbesondere, ob der Preis weiter steigt (und höhere Tiefststände bildet), während der RSI niedrigere Tiefstände bildet - eine regelmäßige bullische Divergenz; oder ob der Preis niedrigere Tiefstände bildet und der RSI höhere Tiefstände
In ähnlicher Weise wird der RSI, wenn er in die Überverkaufszone eintritt, beobachten, ob der Preis weiter sinkt (niedrigere Höchststände bildet), während der RSI höhere Höchststände
Sobald die oben genannten Umkehrsignale erkannt werden, werden nach den konfigurierten Parametern Long- oder Short-Positionen eingesetzt.
Der größte Vorteil dieser Strategie besteht darin, extreme Marktsituationen zu identifizieren, in denen die Umkehrwahrscheinlichkeit hoch ist und die Gewinnmarge für Umkehroperationen groß ist.
Darüber hinaus umfasst die Strategie die Überwachung sowohl regelmäßiger als auch versteckter Abweichungen, damit mehr Möglichkeiten zur Umkehrung erkannt werden können und gute Chancen aufgrund einmaliger Situationen nicht verpasst werden.
Das größte Risiko, dem diese Strategie gegenübersteht, sind noch extremere Überkauf- oder Überverkaufssituationen, die sogenannten "straight up, 90 degrees down". In solchen Fällen ist es wahrscheinlicher, mit langen oder kurzen Operationen fortzufahren, und die Durchführung von Umkehrmaßnahmen kann leicht zu einem Stop-Loss führen.
Außerdem können Fehler leicht entstehen, wenn die Parameter nicht ordnungsgemäß festgelegt werden und bei der Beurteilung von Überkauf- und Überverkaufssituationen Fehler auftreten.
Der Weg, dies zu bewältigen, besteht darin, die oberen und unteren Grenzen für überkaufte und überverkaufte Zonen vernünftigerweise festzulegen, um zu extreme Situationen zu vermeiden.
Die Strategie kann in folgenden Aspekten optimiert werden:
Einbeziehung anderer Indikatoren zur Ermittlung von Überkauf- und Überverkaufsbedingungen, um nicht ausschließlich auf den RSI zu setzen
Hinzufügen von Logik zur Identifizierung der Konsolidierung vor Ausbrüchen, wenn die Umkehrwahrscheinlichkeit höher ist
Optimierung der Gewinnziele nach Umkehrungen, um eine wissenschaftlichere Positionsgröße zu ermöglichen
Verwenden Sie maschinelle Lernmethoden auf historischen Daten der letzten Jahre zur automatischen Optimierung von Parametern
Verbessern Sie die Optimierung der Stop-Loss-Logik, z. B. rechtzeitige Gewinnentnahme, abgestuften Stop-Loss, Trailing-Stop-Loss usw.
Zusammenfassend ist dies eine typische statistische Arbitrage-Strategie. Sie versucht, Chancen zu erfassen, wenn sich der Markt aus extremen Situationen wieder ins Gleichgewicht zurückkehrt. Im Vergleich zu Trend-folgende Strategien hat sie höhere Gewinnraten und Rentabilität, aber auch größere Risiken. Mit Parameteroptimierung und Risikokontrolle können diese Art von Strategien stetig profitieren.
/*backtest start: 2023-01-01 00:00:00 end: 2024-01-07 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/ // made by Imal_Max // thanks to neo the crypto trader's idea // // thanks to JayTradingCharts RSI Divergence /w Alerts indicator for the base code. // we modified this to detect the divergence only if price was oversold or overbought recently and a few more settings // also now you can backtest the settings easy //@version=5 // 🔥 comment out the line below to disable the alerts and enable the backtester //indicator(title="RSI Divergence Indicator with Alerts Overbought Oversold", shorttitle="RSI OB/OS Divergence", format=format.price, timeframe="") // 🔥 uncomment the line below to enable the backtester + uncomment the lines slightly below and at the bottom of the script strategy(title="RSI Divergence Indicator with Alerts Overbought Oversold", shorttitle="RSI OB/OS Divergence", overlay=true) len = input.int(title='RSI Period', minval=1, defval=14, group='regular RSI settings') src = input.source(title='RSI Source', defval=close, group='regular RSI settings') lbR = input.int(title='Pivot Lookback Right', defval=5, group='regular RSI settings') lbL = input.int(title='Pivot Lookback Left', defval=5, group='regular RSI settings') rangeUpper = input.int(title='Max of Lookback Range', defval=60, group='regular RSI settings') rangeLower = input.int(title='Min of Lookback Range', defval=5, group='regular RSI settings') plotBull = input.bool(title='Plot Bullish', defval=true, group='regular RSI settings') plotHiddenBull = input.bool(title='Plot Hidden Bullish', defval=true, group='regular RSI settings') plotBear = input.bool(title='Plot Bearish', defval=true, group='regular RSI settings') plotHiddenBear = input.bool(title='Plot Hidden Bearish', defval=true, group='regular RSI settings') // ob/os divergence settings obvalue = input.int(title='OB RSI Value', defval=70, group='look for RSI divergence after OverBought/OverSold', inline='Input 0', tooltip="min RSI Level needed within lookback period to look for bullish divergences") oblookback = input.int(title='OB lookback period', defval=30, group='look for RSI divergence after OverBought/OverSold', inline='Input 0') osvalue = input.int(title='OS RSI Value', defval=35, group='look for RSI divergence after OverBought/OverSold', inline='Input 1', tooltip="max RSI Level needed within lookback period to look for bearish divergences") oslookback = input.int(title='OS lookback period', defval=30, group='look for RSI divergence after OverBought/OverSold', inline='Input 1') minBearRSI = input.int(title='min RSI for bear Alerts', defval=60, group='look for RSI divergence after OverBought/OverSold', tooltip="min RSI needed at the time where bearish divergence gets detected") maxBullRSI = input.int(title='max RSI for Bull Alerts', defval=50, group='look for RSI divergence after OverBought/OverSold', tooltip="max RSI needed at the time where bullish divergence gets detected") // Backtesteer Info enableBacktesterInfo = input(true, title="to enable the Backtester, uncomment/comment the 🔥 lines in the source code", group='enable Backtester') // Backtester input stuff // long settings - 🔥 uncomment the 3 lines below to disable the alerts and enable the backtester longTrading = input(true, title="enable Long Backtester (to disable uncheck 'plot Bullish' and 'plot hidden Bullish as well')", group='Long Backtester') longStopLoss = input.float(0.5, title='Stop Loss %', group='Long Backtester') / 100 longTakeProfit = input.float(2.0, title='Take Profit %', group='Long Backtester') / 100 // short settings - 🔥 uncomment the 3 lines below to disable the alerts and enable the backtester shortTrading = input(true, title="enable Short Backtester (to disable uncheck 'plot Bearish' and 'plot hidden Bearish as well'", group='Short Backtester') shortStopLoss = input.float(0.5, title='Stop Loss %', group='Short Backtester') / 100 shortTakeProfit = input.float(2.0, title='Take Profit %', group='Short Backtester') / 100 // Backtesting Range settings - 🔥 uncomment the 6 lines below to disable the alerts and enable the backtester startDate = input.int(title='Start Date', defval=1, minval=1, maxval=31, group='Backtesting range') startMonth = input.int(title='Start Month', defval=1, minval=1, maxval=12, group='Backtesting range') startYear = input.int(title='Start Year', defval=2016, minval=1800, maxval=2100, group='Backtesting range') endDate = input.int(title='End Date', defval=1, minval=1, maxval=31, group='Backtesting range') endMonth = input.int(title='End Month', defval=1, minval=1, maxval=12, group='Backtesting range') endYear = input.int(title='End Year', defval=2040, minval=1800, maxval=2100, group='Backtesting range') bearColor = color.red bullColor = color.green hiddenBullColor = color.new(color.green, 80) hiddenBearColor = color.new(color.red, 80) textColor = color.white noneColor = color.new(color.white, 100) osc = ta.rsi(src, len) plot(osc, title='RSI', linewidth=2, color=color.new(#00bcd4, 0)) obLevel = hline(obvalue, title='Overbought', linestyle=hline.style_dotted) osLevel = hline(osvalue, title='Oversold', linestyle=hline.style_dotted) minRSIline = hline(minBearRSI, title='max RSI for Bull divergence', linestyle=hline.style_dotted) maxRSIline = hline(maxBullRSI, title='max RSI for Bull divergence', linestyle=hline.style_dotted) fill(obLevel, minRSIline, title='Bear Zone Background', color=color.new(#f44336, 90)) fill(osLevel, maxRSIline, title='Bull Zone Background', color=color.new(#4caf50, 90)) RSI0line = hline(0, title='RSI 0 Line', linestyle=hline.style_dotted) RSI100line = hline(100, title='RSI 100 Line', linestyle=hline.style_dotted) fill(obLevel, RSI100line, title='Overbought Zone Background', color=color.new(#e91e63, 75)) fill(osLevel, RSI0line, title='Oversold Zone Background', color=color.new(#4caf50, 75)) plFound = na(ta.pivotlow(osc, lbL, lbR)) ? false : true phFound = na(ta.pivothigh(osc, lbL, lbR)) ? false : true _inRange(cond) => bars = ta.barssince(cond == true) rangeLower <= bars and bars <= rangeUpper // check if RSI was OS or OB recently obHighestRsi = ta.highest(osc, oblookback) osLowestRsi = ta.lowest(osc, oslookback) //------------------------------------------------------------------------------ // Regular Bullish // Osc: Higher Low oscHL = osc[lbR] > ta.valuewhen(plFound, osc[lbR], 1) and _inRange(plFound[1]) // Price: Lower Low priceLL = low[lbR] < ta.valuewhen(plFound, low[lbR], 1) bullCond = plotBull and priceLL and oscHL and plFound and osLowestRsi < osvalue and osc < maxBullRSI plot(plFound ? osc[lbR] : na, offset=-lbR, title='Regular Bullish', linewidth=2, color=bullCond ? bullColor : noneColor, transp=0) plotshape(bullCond ? osc[lbR] : na, offset=-lbR, title='Regular Bullish Label', text=' Bull ', style=shape.labelup, location=location.absolute, color=bullColor, textcolor=textColor, transp=0) //------------------------------------------------------------------------------ // Hidden Bullish // Osc: Lower Low oscLL = osc[lbR] < ta.valuewhen(plFound, osc[lbR], 1) and _inRange(plFound[1]) // Price: Higher Low priceHL = low[lbR] > ta.valuewhen(plFound, low[lbR], 1) hiddenBullCond = plotHiddenBull and priceHL and oscLL and plFound and osLowestRsi < osvalue and osc < maxBullRSI plot(plFound ? osc[lbR] : na, offset=-lbR, title='Hidden Bullish', linewidth=2, color=hiddenBullCond ? hiddenBullColor : noneColor, transp=0) plotshape(hiddenBullCond ? osc[lbR] : na, offset=-lbR, title='Hidden Bullish Label', text=' H Bull ', style=shape.labelup, location=location.absolute, color=bullColor, textcolor=textColor, transp=0) //------------------------------------------------------------------------------ // Regular Bearish // Osc: Lower High oscLH = osc[lbR] < ta.valuewhen(phFound, osc[lbR], 1) and _inRange(phFound[1]) // Price: Higher High priceHH = high[lbR] > ta.valuewhen(phFound, high[lbR], 1) bearCond = plotBear and priceHH and oscLH and phFound and obHighestRsi > obvalue and osc > minBearRSI plot(phFound ? osc[lbR] : na, offset=-lbR, title='Regular Bearish', linewidth=2, color=bearCond ? bearColor : noneColor, transp=0) plotshape(bearCond ? osc[lbR] : na, offset=-lbR, title='Regular Bearish Label', text=' Bear ', style=shape.labeldown, location=location.absolute, color=bearColor, textcolor=textColor, transp=0) //------------------------------------------------------------------------------ // Hidden Bearish // Osc: Higher High oscHH = osc[lbR] > ta.valuewhen(phFound, osc[lbR], 1) and _inRange(phFound[1]) // Price: Lower High priceLH = high[lbR] < ta.valuewhen(phFound, high[lbR], 1) hiddenBearCond = plotHiddenBear and priceLH and oscHH and phFound and obHighestRsi > obvalue and osc > minBearRSI plot(phFound ? osc[lbR] : na, offset=-lbR, title='Hidden Bearish', linewidth=2, color=hiddenBearCond ? hiddenBearColor : noneColor, transp=0) plotshape(hiddenBearCond ? osc[lbR] : na, offset=-lbR, title='Hidden Bearish Label', text=' H Bear ', style=shape.labeldown, location=location.absolute, color=bearColor, textcolor=textColor, transp=0) alertcondition(bullCond, title='Bullish divergence', message='Regular Bull Div {{ticker}} XXmin') alertcondition(bearCond, title='Bearish divergence', message='Regular Bear Div {{ticker}} XXmin') alertcondition(hiddenBullCond, title='Hidden Bullish divergence', message='Hidden Bull Div {{ticker}} XXmin') alertcondition(hiddenBearCond, title='Hidden Bearish divergence', message='Hidden Bear Div {{ticker}} XXmin') // 🔥 uncomment the all lines below for the backtester and revert for alerts longTP = strategy.position_size > 0 ? strategy.position_avg_price * (1 + longTakeProfit) : strategy.position_size < 0 ? strategy.position_avg_price * (1 - longTakeProfit) : na longSL = strategy.position_size > 0 ? strategy.position_avg_price * (1 - longStopLoss) : strategy.position_size < 0 ? strategy.position_avg_price * (1 + longStopLoss) : na shortTP = strategy.position_size > 0 ? strategy.position_avg_price * (1 + shortTakeProfit) : strategy.position_size < 0 ? strategy.position_avg_price * (1 - shortTakeProfit) : na shortSL = strategy.position_size > 0 ? strategy.position_avg_price * (1 - shortStopLoss) : strategy.position_size < 0 ? strategy.position_avg_price * (1 + shortStopLoss) : na strategy.risk.allow_entry_in(longTrading == true and shortTrading == true ? strategy.direction.all : longTrading == true ? strategy.direction.long : shortTrading == true ? strategy.direction.short : na) strategy.entry('Bull', strategy.long, comment='Long', when=bullCond) strategy.entry('Bull', strategy.long, comment='Long', when=hiddenBullCond) strategy.entry('Bear', strategy.short, comment='Short', when=bearCond) strategy.entry('Bear', strategy.short, comment='Short', when=hiddenBearCond) strategy.exit(id='longTP-SL', from_entry='Bull', limit=longTP, stop=longSL) strategy.exit(id='shortTP-SL', from_entry='Bear', limit=shortTP, stop=shortSL)