How can I programmatically detect bullish and bearish RSI divergences?

A bullish divergence occurs when the underlying security makes a lower low and RSI forms a higher low. RSI does not confirm the lower low and this shows strengthening momentum.

A bearish divergence forms when the security records a higher high and RSI forms a lower high. RSI does not confirm the new high and this shows weakening momentum.

enter image description here


3 Answers 3


I was searching for answers to the same question and came across your question.

After some thought and research, here is the plan I have developed. I will be working in Python.

  1. Calculate relative maxima and minima with SciPy.
  2. Calculate RSI at those points using lib-ta.
  3. For each pair of lows and highs, compare the change in price with the difference in RSI.

I'm completely new to technical analysis, so in case I have made any oversights, feedback would be greatly appreciated. I wanted to ask about your programming language and data format, but don't have enough reputation to comment.

  • 1
    $\begingroup$ Cool, thanks. If my answer was helpful for you, I'd appreciate an upvote and/or accept. IMHO my answer is more specific and complete than any of the answers on Reddit so far. $\endgroup$ Aug 20, 2018 at 2:13
  • $\begingroup$ Awesome, thanks. :) I actually just started developing my own bot a couple of days ago. So far it just does trailing stop losses for the sell strategy. I'm planning to use RSI divergences at first for the buy strategy, so I'll be curious to compare my algorithm with yours later. $\endgroup$ Aug 20, 2018 at 6:08
  • $\begingroup$ I am attempting to do the same thing with finding divergences and was able to complete steps 1 and 2 before hitting a roadblock and stumbling upon this. Could you explain how you computed step 3? I have the index points of these highs and lows and all the RSI/close info. Just trying to figure out a way to automate the checking, using those specific index points. $\endgroup$
    – hkml
    Mar 12, 2019 at 2:57
  • $\begingroup$ I'm not sure if I understand your question. As explained in the original question: "A bullish divergence occurs when the underlying security makes a lower low and RSI forms a higher low... A bearish divergence forms when the security records a higher high and RSI forms a lower high." If you have identified a pair of lower lows in price (priceA and price B), then priceA - priceB should be positive, right? If RSIa - RSIb (RSI at the same times) is then negative, that means the RSI has risen, which signals a bullish divergence. Does that help? $\endgroup$ Mar 18, 2019 at 2:48
  • $\begingroup$ scipy.argrelmin is dangerous in quant trading because it has a forward-looking component. In other words, the relative maxima at time t depends on data from time t+i for positive i, which invalidates your simulation. $\endgroup$ Jul 25, 2020 at 23:27

I want to implement exactly same principle in C# and realized that i should start opposite. Start from finding Higher High or Lower Low and then checking RSI. After finding HH or LL checking RSI is trivial task. To find HH or LL you could use ZigZag indicator. At investopedia you could find how to calculate it in more details. Also you could check Python version of it in quantconnect forum. Also, you could find more versions on internet.

  • $\begingroup$ The problem with ZigZag indicator is it draws peaks when they are quite in the past (it retrospectively updates itself). A way to detect turning points as they happen is quite difficult $\endgroup$ Jul 2, 2020 at 17:15
  • $\begingroup$ quantconnect forum does not have any Python version $\endgroup$
    – alper
    Jan 11, 2021 at 11:49
  • $\begingroup$ What about this. Press code > main.py. Also i have done it in c# quantconnect.com/terminal/… $\endgroup$
    – valentasm
    Jan 12, 2021 at 6:44
  • $\begingroup$ I've looked at Zig Zag too and am worried it will miss obvious HH/LL due to its use of a % change threshold. I'm also looking at Williams Fractal to identify points. I'm also stuck on next steps, but might try a custom rolling point identification, similar to Fractal. The problem with all of these is you'll never know you've hit a HH/LL point until several bars later, so it will never give you real-time signals (only retro). $\endgroup$ May 30, 2021 at 19:00

Pine-script that could be applied on tradingview, Shizaru 's reference:

// => normal RSI: check double or triple top/bottom on a chart meanwhile RSI is descending/ascending (check the example on chart)
// => signal line: when RSI Divergence cross zero line from bottom to top you get a buy signal (the line become green), 
//    vice versa when the RSI Divergence cross zero line in the opposite way you get a sell signal (the line become red)

study(title="RSI Divergence", shorttitle="RSI Divergence")
src_fast = close, len_fast = input(5, minval=1, title="Length Fast RSI")
src_slow = close, len_slow = input(14,minval=1, title="Length Slow RSI")
up_fast = rma(max(change(src_fast), 0), len_fast)
down_fast = rma(-min(change(src_fast), 0), len_fast)
rsi_fast = down_fast == 0 ? 100 : up_fast == 0 ? 0 : 100 - (100 / (1 + up_fast / down_fast))
up_slow = rma(max(change(src_slow), 0), len_slow)
down_slow = rma(-min(change(src_slow), 0), len_slow)
rsi_slow = down_slow == 0 ? 100 : up_slow == 0 ? 0 : 100 - (100 / (1 + up_slow / down_slow))
//plotfast = plot(rsi_fast, color=blue)
//plotslow = plot(rsi_slow, color=orange)
divergence = rsi_fast - rsi_slow
plotdiv = plot(divergence, color = divergence > 0 ? lime:red, linewidth = 2)
//band1 = hline(70,color=green)
//band0 = hline(30,color=red)
band = hline(0)

divlong = divergence >=0
divshort = divergence <=0

alertcondition(divlong, title='Div Long', message='Div Long')
alertcondition(divshort, title='Div Short', message='Div Short')

data1 = divlong
data2 = divshort
plotshape(data1, style=shape.triangleup,location=location.bottom, color=green , title="DivUp")
plotshape(data2, style=shape.triangledown, location=location.top, color=red,title="DivDown")
  • $\begingroup$ This only depicts divergence between two differently configured RSI lines. I think the more popular definition of divergence is between higher high and lower low Price and RSI trends, usually in the overbought/oversold RSI zones. $\endgroup$ May 16, 2021 at 3:19
  • $\begingroup$ @DaveSkender Could WaveTrend Oscillator be an example for what you are defining related to overbought/oversold zones? Please see tradingview.com/script/… $\endgroup$
    – alper
    May 16, 2021 at 11:36
  • $\begingroup$ I'm trying to do some research for my .NET indicator library as well. So far, here's the most general description I can find online: Divergence @ Investopedia $\endgroup$ May 30, 2021 at 18:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.