RSI 지표에 기반한 역전 전략

저자:차오장, 날짜: 2024-01-08 16:47:07
태그:

img

전반적인 설명

이 전략은 RSI 지표에 기초하여 과반 구매 또는 과반 판매 상황 후 반전 기회를 식별합니다. RSI가 과반 구매 또는 과반 판매 구역에 진입 한 후 가격과 RSI 사이의 차이를 모니터링하여 잠재적 인 미래의 반전 기회를 결정합니다.

전략 논리

이 전략은 RSI 지표를 사용하여 시장에서 과잉 구매 및 과잉 판매 상황을 결정합니다. RSI가 미리 설정된 과잉 구매 또는 과잉 판매 구역에 진입하면 반전 오차를 모니터링하기 시작합니다.

특히, RSI가 과잉 매입 구역에 진입하면, RSI가 낮은 하락점을 형성하는 동안 가격이 계속 상승 (더 높은 하락점을 형성) 하는지를 모니터링합니다. 또는 가격이 낮은 하락점을 형성하고 RSI가 더 높은 하락점을 형성합니다. 두 가지 상황 모두 잠재적인 하락 전환을 알립니다.

마찬가지로, RSI가 과잉 판매 구역에 진입하면, RSI가 더 높은 최고치를 형성하는 동안 가격이 계속 떨어지는지 (하층 최고치를 형성하는) 또는 가격이 더 높은 최고치를 형성하고 RSI가 더 낮은 최고치를 형성하는지 (숨겨진 하위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위 위

위의 반전 신호가 감지되면 구성된 매개 변수에 따라 긴 또는 짧은 지위가 취해질 것입니다.

장점

이 전략의 가장 큰 장점은 역전 가능성이 높고 역전 거래의 이익 마진이 큰 극단적인 시장 상황을 식별 할 수 있다는 것입니다. 간단한 트렌드 추종 전략에 비해, 이와 같은 역 트렌드 전략은 더 높은 승률과 수익성을 가지고 있습니다.

또한, 전략은 규칙적인 차이와 숨겨진 차이에 대한 모니터링을 포함하여 더 많은 역행 기회를 식별 할 수 있으며 일회성 상황으로 인해 좋은 기회를 놓치지 않도록합니다.

위험성

이 전략에 직면 한 가장 큰 위험은 더욱 극단적인 과잉 구매 또는 과잉 판매 상황, 이른바 "직선 상승, 90도 하락"입니다. 이러한 경우 긴 또는 짧은 거래를 계속하는 것이 더 가능성이 높으며, 역행 조치를 취하면 손해를 멈추게 될 수 있습니다.

게다가, 매개 변수들이 제대로 설정되지 않고 과잉 구매와 과잉 판매 상황을 판단하는 데 오류가 있을 경우, 오류가 쉽게 발생할 수 있습니다.

이 문제를 해결하는 방법은 지나치게 극단적인 상황을 피하기 위해 과반 구매 및 과반 판매 구역의 상위 및 하위 한도를 합리적으로 설정하는 것입니다. 또한 단일 스톱 손실의 금액을 제어하기 위해 라이브 거래에서 포지션 크기를 축소합니다.

최적화 방향

이 전략은 다음과 같은 측면에서 최적화 될 수 있습니다.

  1. RSI에만 의존하는 것을 피하기 위해 과반 구매 및 과반 판매 조건을 결정하기 위해 다른 지표를 포함하십시오.

  2. 역전 확률이 높을 때 브레이크오웃 전에 통합을 식별하기 위해 논리를 추가합니다.

  3. 더 과학적인 위치 크기를 가능하게 하기 위해 반전 후 수익 목표 설정 최적화

  4. 자동으로 매개 변수를 최적화하기 위해 최근 년의 역사적 데이터에 기계 학습 방법을 사용

  5. 스톱 로스 로직 최적화를 개선합니다. 예를 들어, 적시에 수익을 취하고, 스톱 로스를 단계적으로, 트래일링 스톱 로스를 취합니다.

결론

결론적으로, 이것은 전형적인 통계적 중재 전략이다. 시장이 극단적인 상황에서 균형을 되찾을 때 기회를 잡으려고 노력한다. 트렌드 추종 전략에 비해 더 높은 승률과 수익성이 있지만 더 큰 위험에 직면한다. 매개 변수 최적화와 위험 통제로 이러한 유형의 전략은 꾸준히 이익을 얻을 수 있다.


/*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)




더 많은