I found this on the next link: Back Testing RSI Divergence Strategy on FX

The author of the post used the exponential moving average for RSI calculation, using this piece of code:

'''
Assuming you have a pandas OHLC Dataframe downloaded from Metatrader 5 historical data. 
'''
# Get the difference in price from previous step
Data = pd.DataFrame(Data)
delta = Data.iloc[:, 3].diff()
delta = delta[1:]

# Make the positive gains (up) and negative gains (down) Series
up, down = delta.copy(), delta.copy()
up[up < 0] = 0
down[down > 0] = 0
roll_up = pd.stats.moments.ewma(up, lookback)
roll_down = pd.stats.moments.ewma(down.abs(), lookback)

# Calculate the SMA
roll_up = roll_up[lookback:]
roll_down = roll_down[lookback:]
Data = Data.iloc[lookback + 1:,].values

# Calculate the RSI based on SMA
RS = roll_up / roll_down
RSI = (100.0 - (100.0 / (1.0 + RS)))
RSI = np.array(RSI)
RSI = np.reshape(RSI, (-1, 1))

Data = np.concatenate((Data, RSI), axis = 1)

At this point we have an array with OHLC data and a fifth column that has the RSI in it. Then added the next two columns:

  1. Column 6: Data[:, 5] will be for the bullish divergences and will have values of 0 or 1 (initiate buy).
  2. Column 7: Data[:, 6] will be for the bearish divergences and will have values of 0 or -1 (initiate short).

using this variables:

lower_barrier = 30
upper_barrier = 70
width = 10

Here is the code:

# Bullish Divergence
for i in range(len(Data)):
   try:
       if Data[i, 4] < lower_barrier:
           for a in range(i + 1, i + width):
               if Data[a, 4] > lower_barrier:
                    for r in range(a + 1, a + width):
                       if Data[r, 4] < lower_barrier and \
                        Data[r, 4] > Data[i, 4] and Data[r, 3] < Data[i, 3]:
                            for s in range(r + 1, r + width): 
                                if Data[s, 4] > lower_barrier:
                                    Data[s + 1, 5] = 1
                                    break
                                else:
                                    continue
                        else:
                            continue
                    else:
                        continue
                else:
                    continue
  except IndexError:
        pass

# Bearish Divergence
for i in range(len(Data)):
   try:
       if Data[i, 4] > upper_barrier:
           for a in range(i + 1, i + width): 
               if Data[a, 4] < upper_barrier:
                   for r in range(a + 1, a + width):
                       if Data[r, 4] > upper_barrier and \
                       Data[r, 4] < Data[i, 4] and Data[r, 3] > Data[i, 3]:
                           for s in range(r + 1, r + width):
                               if Data[s, 4] < upper_barrier:
                                   Data[s + 1, 6] = -1
                                   break
                               else:
                                   continue
                       else:
                           continue
                   else:
                       continue
               else:
                   continue
   except IndexError:
       pass
Answer from robbinc91 on Stack Overflow
Top answer
1 of 4
3

I found this on the next link: Back Testing RSI Divergence Strategy on FX

The author of the post used the exponential moving average for RSI calculation, using this piece of code:

'''
Assuming you have a pandas OHLC Dataframe downloaded from Metatrader 5 historical data. 
'''
# Get the difference in price from previous step
Data = pd.DataFrame(Data)
delta = Data.iloc[:, 3].diff()
delta = delta[1:]

# Make the positive gains (up) and negative gains (down) Series
up, down = delta.copy(), delta.copy()
up[up < 0] = 0
down[down > 0] = 0
roll_up = pd.stats.moments.ewma(up, lookback)
roll_down = pd.stats.moments.ewma(down.abs(), lookback)

# Calculate the SMA
roll_up = roll_up[lookback:]
roll_down = roll_down[lookback:]
Data = Data.iloc[lookback + 1:,].values

# Calculate the RSI based on SMA
RS = roll_up / roll_down
RSI = (100.0 - (100.0 / (1.0 + RS)))
RSI = np.array(RSI)
RSI = np.reshape(RSI, (-1, 1))

Data = np.concatenate((Data, RSI), axis = 1)

At this point we have an array with OHLC data and a fifth column that has the RSI in it. Then added the next two columns:

  1. Column 6: Data[:, 5] will be for the bullish divergences and will have values of 0 or 1 (initiate buy).
  2. Column 7: Data[:, 6] will be for the bearish divergences and will have values of 0 or -1 (initiate short).

using this variables:

lower_barrier = 30
upper_barrier = 70
width = 10

Here is the code:

# Bullish Divergence
for i in range(len(Data)):
   try:
       if Data[i, 4] < lower_barrier:
           for a in range(i + 1, i + width):
               if Data[a, 4] > lower_barrier:
                    for r in range(a + 1, a + width):
                       if Data[r, 4] < lower_barrier and \
                        Data[r, 4] > Data[i, 4] and Data[r, 3] < Data[i, 3]:
                            for s in range(r + 1, r + width): 
                                if Data[s, 4] > lower_barrier:
                                    Data[s + 1, 5] = 1
                                    break
                                else:
                                    continue
                        else:
                            continue
                    else:
                        continue
                else:
                    continue
  except IndexError:
        pass

# Bearish Divergence
for i in range(len(Data)):
   try:
       if Data[i, 4] > upper_barrier:
           for a in range(i + 1, i + width): 
               if Data[a, 4] < upper_barrier:
                   for r in range(a + 1, a + width):
                       if Data[r, 4] > upper_barrier and \
                       Data[r, 4] < Data[i, 4] and Data[r, 3] > Data[i, 3]:
                           for s in range(r + 1, r + width):
                               if Data[s, 4] < upper_barrier:
                                   Data[s + 1, 6] = -1
                                   break
                               else:
                                   continue
                       else:
                           continue
                   else:
                       continue
               else:
                   continue
   except IndexError:
       pass
2 of 4
3

I changed above code a bit hope this helps:

lower_barrier = 30
upper_barrier = 70
width = 5
#Bullish Divergence
for i in range(len(Data)):

   try:
     if Data.iloc[i, 4] < lower_barrier:
         for a in range(i + 1, i + width):
             if Data.iloc[a, 4] > lower_barrier:
                  for r in range(a + 1, a + width):
                     if Data.iloc[r, 4] < lower_barrier and Data.iloc[r, 4] > Data.iloc[i, 4] and Data.iloc[r, 3] < Data.iloc[i, 3]:
                         for s in range(r + 1, r + width): 
                            if Data.iloc[s, 4] > lower_barrier:
                                print('Bullish above',Data.iloc[s+1,1])
                                Data.iloc[s + 1, 5] = 1
                                break
                            else:
                                continue
                    else:
                        continue
            else:
                continue
    else:
        continue
except IndexError:
    pass
#Bearish Divergence
for i in range(len(Data)):
try:
    if Data.iloc[i, 4] > upper_barrier:
        for a in range(i + 1, i + width): 
            if Data.iloc[a, 4] < upper_barrier:
                for r in range(a + 1, a + width):
                    if Data.iloc[r, 4] > upper_barrier and Data.iloc[r, 4] < Data.iloc[i, 4] and Data.iloc[r, 3] > Data.iloc[i, 3]:
                        for s in range(r + 1, r + width):
                            if Data.iloc[s, 4] < upper_barrier:
                                print('Bearish below',Data.iloc[s+1,2])
                                Data.iloc[s + 1, 6] = -1
                                break
                            else:
                                continue
                    else:
                        continue
                else:
                    continue
            else:
                continue
except IndexError:
    pass
🌐
GitHub
github.com › AmirRezaFarokhy › RSI-Divergence
GitHub - AmirRezaFarokhy/RSI-Divergence
Finding the divergence of the gold market(XAUUSD) based on the RSI indicator. It is one of the trading strategies. Tested and obtained percentage: 75% winning rate. ... # install numpy pip install numpy # install matplotlib pip install matplotlib ...
Starred by 16 users
Forked by 9 users
Languages   Jupyter Notebook 98.3% | Python 1.7% | Jupyter Notebook 98.3% | Python 1.7%
Discussions

I created a divergence indicator (Python)
man this is so clean, you did a great job thanks for sharing More on reddit.com
🌐 r/algotrading
23
54
November 12, 2021
programming - Programmatically detect RSI divergence - Quantitative Finance Stack Exchange
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 More on quant.stackexchange.com
🌐 quant.stackexchange.com
Coding price-RSI divergence?
That might help with the extrema. https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.argrelextrema.html - The idea could look good in backtesting (depending on the quality of the backtest), but the relative maxima and minima will be lagging behind. In other words you will never know if the current bar is a extrema instantly. Depending on your settings it takes X bars more, before its recognisable as extrema. So you probably always miss the (perfect) entry / exit. If you trade crypto, checkout jesse: https://docs.jesse-ai.com/docs/indicators/reference.html#minmax - it offers the detection of extrema already and is a good backtesting framework. More on reddit.com
🌐 r/algotrading
3
7
June 7, 2020
Thinking of automating a trading strat involving ADX, MACD and RSI, what do yall think of strat involving these indicators?
Good luck man. Even doing a general optimisation will overfit these. More on reddit.com
🌐 r/algotrading
104
45
October 6, 2023
🌐
GitHub
github.com › SpiralDevelopment › RSI-divergence-detector
GitHub - SpiralDevelopment/RSI-divergence-detector: RSI divergence detector finds regular and hidden bullish and bearish divergences
March 22, 2022 - sample_tg_poster.py - Gets the ohlc data from local database and checks if the last candle has RSI divergence
Starred by 110 users
Forked by 39 users
Languages   Python 100.0% | Python 100.0%
🌐
Reddit
reddit.com › r/algotrading › i created a divergence indicator (python)
r/algotrading on Reddit: I created a divergence indicator (Python)
November 12, 2021 -

TLDR: I developed a divergence indicator in Python. Source code on my GitHub here.

Hi, I thought I would share a divergence indicator I have developed in Python. It can be used to detect divergence between any two datasets, whether that be price and an indicator, or two indicators.

I started by looking at indicators available on TradingView for inspiration and found their built-in divergence indicator, which uses pivot points to locate local turning points in price/indicators. My idea was to use a different method for this, which has turned out to be more responsive and hence less lagging. To do so, I apply a 2-period EMA to hl2 data and detected a new price level when the gradient of the ema changes. The chart below illustrates this idea. The same concept can be applied to indicators.

Dashed lines appear when a new 'support' or 'resistance' level is detected. The sensitivity of this indicator can be controlled by the period of the EMA.

Since this method will sometimes detect new levels due to noise, I filter for 'strong' levels by only accepting levels which last greater than (for example) 2 candles. Now it is possible to detect higher-highs, lower-lows, lower-highs and higher-lows. An example of this is shown in the chart below, where lower-lows in price are detected.

Detection of lower-lows using price levels.

Now the same process can be applied to indicators instead of price data: instead of taking the EMA of price, passing the indicator data straight in is sufficient. This will work for RSI, Stochastics, MACD, or any other data source.

As an example, I have applied it the RSI. As per the definition, regular bullish divergence occurs when price makes a lower-low at the same time an indicator makes a higher-low. By comparing the levels detected in price to the levels detected in the indicator, divergence between them can be detected. The chart below shows an example of regular bullish divergence being detected.

An example of regular bullish divergence being detected.

For comparison, the screenshot below shows TradingView's divergence indicator on the same instrument (EUR/USD on D) at the same time. Although the bullish tag appears earlier on the chart, the signal will not actually appear until the candle I have highlighted with a vertical line (try using the replay function to see this for yourself - it is a bit misleading when the signal would be received live). In this (admittedly cherry-picked) example, the indicator I have developed picks up the signal 3 candles before the TradingView indicator, which equals approximately 100 pips.

TradingView's divergence indicator.

The source code for the indicator can be found on my GitHub (link at the top of this post). The module containing the code is actually a part of my entire trading project, but using the indicators from that module is easy enough.

Note that I have split the processes above into three indicators. There are some parameters which can be used to tune the sensitivity of each, but I will just give a brief overview of how to use them to reproduce the results above. They are also commented in the code itself. The indicators are:

  • find_swings(): to detect the reversal levels. This function accepts OHLC data and indicator data sources. If you pass in the data from an indicator (ie. a 1D array), use the data_type='other' input parameter to specify that it is not OHLC data. This function will return a DataFrame with columns Highs, Lows, Last and Trend. The first three contain the values of the data source at high swings, low swings and the most recent swing, respectively. The Trend column contains 1 when there is an implied uptrend, and -1 when there is an implied downtrend.

  • classify_swings(): to classify the swing levels as higher-highs, lower-lows, lower-highs and higher-lows. The main input to this function is the DataFrame output of find_swings(). The output is another DataFrame with columns "HH", "LL", "LH" and "HL".

  • detect_divergence(): to compare the classified swings of two data sources (for example, price data and RSI). This function requires two "classified swings" DataFrames as inputs, as outputted from the classify_swings() function. It will then return a DataFrame with True/False columns titled 'regularBull', 'regularBear', 'hiddenBull', and 'hiddenBear', corresponding to the regular and hidden divergences detected.

I have also wrapped all of the indicators above into a single indicator, autodetect_divergence. The inputs to this functions are the OHLC data and the indicator data. It will return the same thing as detect_divergence, described above.

Hopefully this post was interesting and maybe gave someone some ideas. Please let me know if you have any suggestions or questions. Thanks for reading!

🌐
YouTube
youtube.com › watch
RSI Divergence Automated In Python | Algorithmic Trading - YouTube
The RSI Divergence Detection is programmed in python as an automated indicator for algorithmic trading, the Jupyter notebook file is available from the link:...
Published   November 12, 2021
🌐
Raposa
raposa.trade › blog › test-and-trade-rsi-divergence-in-python
Test and Trade RSI Divergence in Python — Raposa
July 26, 2021 - Divergent strategies can be powerful to add to your bot trading arsenal. We show you how to trade this with the RSI and provide code for you to backtest it yourself.
Find elsewhere
🌐
QuantInsti
blog.quantinsti.com › rsi-indicator
RSI Indicator Formula and Calculation: Trading Strategies and Python Implementation
March 5, 2025 - Learn how the RSI indicator works, from its formula and calculation to trading strategies and backtesting. Explore Python implementation with real-world examples and visualizations.
🌐
Kaggle
kaggle.com › code › chandrimad31 › forex-trading-momentum-analysis-rsi-divergence
Forex Trading Momentum Analysis: RSI Divergence | Kaggle
May 29, 2022 - Explore and run machine learning code with Kaggle Notebooks | Using data from EUR/USD Forex Trading Data 4 Hrs Gap (2003-2021)
🌐
Medium
medium.com › raposa-technologies › test-and-trade-rsi-divergence-in-python-34a11c1c4142
Test and Trade RSI Divergence in Python | by Raposa.Trade | Raposa Technologies | Medium
February 2, 2022 - Divergences occur when price and your indicator move in opposite directions. For example, you’re trading with the RSI and it last had a peak at 80, now it peaks at 70. The underlying security you’re…
🌐
PyPI
pypi.org › project › rsi-divergence-detector
rsi-divergence-detector · PyPI
The detector returns a pd.DataFrame ... of the price pivots (first → second) ... Regular bullish: price makes lower low (LL), RSI makes higher low (HL) → potential reversal up....
      » pip install rsi-divergence-detector
    
Published   Aug 11, 2025
Version   0.1.0
🌐
YouTube
youtube.com › watch
CODING RSI DIVERGENCES - YouTube
In this video, I will teach you how to code the RSI divergence in Python.Here is the link to the code:https://www.technicallysorted.com/products/Coding-an-RS...
Published   June 28, 2023
🌐
Medium
medium.com › @trading.dude › spotting-market-turning-points-how-to-detect-bullish-and-bearish-divergence-with-python-b0c44df25461
Spotting Market Turning Points: How to Detect Bullish and Bearish Divergence with Python | by Trading Dude | Medium
May 12, 2025 - For example: A bullish divergence at a support level strengthens the case for a long trade. A bearish divergence near resistance might reinforce your decision to exit or go short.
🌐
Insider Finance
wire.insiderfinance.io › rsi-divergence-trading-strategy-e2e16788324a
RSI divergence trading strategy
InsiderFinance news wire — Top articles on data-driven trading, investing, analyses, tools, and strategies to achieve financial freedom
🌐
YouTube
youtube.com › watch
Python Trading Strategy: RSI Divergence Backtest
Enjoy the videos and music you love, upload original content, and share it all with friends, family, and the world on YouTube.
🌐
Quantified Strategies
quantifiedstrategies.com › python-and-rsi-trading-strategy
Python and RSI Trading Strategy (Backtest, Rules, Code, Setup) - QuantifiedStrategies.com
October 20, 2024 - In this article, we will learn how to download historical stock data from Yahoo Finance, calculate the RSI indicator, generate trading signals, and plot the returns of the strategy, all using Python. ... yfinance allows us to download historical data from Yahoo Finance for free and also includes fundamental data such as income statements, trading multiples, and dividends, among many others. We are going to create a Python notebook to run our code. A Python notebook is a web-based environment to create and edit Python scripts (for example, Jupyter notebook or Google Colaboratory).
🌐
alpharithms
alpharithms.com › home › articles › trading › calculating the rsi in python: 3 ways to predict market status & price movement
Calculating the RSI in Python: 3 Ways to Predict Market Status & Price Movement - αlphαrithms
April 10, 2023 - The example worksheet by Wilder illustrating the intermediate values for RSI calculation across a 38-period trading window. (Click to Enlarge) The thought of having to make these calculations for any reasonable number of assets seems excruciating. Keep in mind this was long before intraday trading was available and daily (and often weekly) price action was the primary focus of technical analysis. Still, it highlights the advantages afforded to modern traders by tools like Python.
🌐
AlphaSquawk
alphasquawk.com › alphasquawk | knowledge for traders › strategy › relative strength index: trading strategies, rsi divergence and python
Relative Strength Index: Trading Strategies, RSI Divergence and Python
February 25, 2025 - The RSI python created (blue line) on a Meta Platforms stock candlestick chart with volume for 2022-2023. You could expand this code to develop an RSI indicator screener. Note to the right of the chart bearish RSI divergence from price as it ...