# Programmatically detect RSI divergence

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.

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.

• 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. – Casey Jones Aug 20 '18 at 2:13
• 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. – Casey Jones Aug 20 '18 at 6:08
• 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. – hkml Mar 12 '19 at 2:57
• 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? – Casey Jones Mar 18 '19 at 2:48
• 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. – Chris Conlan Jul 25 '20 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.

• 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 – Dr. Andrew Burnett-Thompson Jul 2 '20 at 17:15
• quantconnect forum does not have any Python version – alper Jan 11 at 11:49
• What about this. Press code > main.py. Also i have done it in c# quantconnect.com/terminal/… – valentasm Jan 12 at 6:44

Pine script that could be applied on tradingview, reference:

study(title="RSI Divergence", shorttitle="RSI Divergence_alper")
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)

// => 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)
divlong = divergence >=0
divshort = divergence <=0