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
🌐
Medium
medium.com › the-investors-handbook › the-hidden-divergence-trading-method-in-python-f747363723e2
The Hidden Divergence Trading Method in Python. | by Sofien Kaabar, CFA | Investor’s Handbook | Medium
August 13, 2021 - The Hidden Divergence Trading Method in Python. Creating & Applying the Hidden Divergence Trend-Following Technique. Divergences are known to be counter trend signals that show an exhaustion in the …
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 › 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!

🌐
Substack
abouttrading.substack.com › p › the-hidden-divergence-trading-method
The Hidden Divergence Trading Method in Python.
September 14, 2021 - Divergences are known to be counter trend signals that show an exhaustion in the current trend. There exists a type of divergences that actually signal a trend continuation. The idea of this article is to shine some light on them and try to code them in Python.
🌐
Medium
kaabar-sofien.medium.com › hidden-divergence-trading-in-python-4642c09a92ae
Hidden Divergence Trading in Python | by Sofien Kaabar, CFA | Medium
August 31, 2022 - Divergences are known to be counter trend signals that show an exhaustion in the current trend. There exists a type of divergences that actually signal a trend continuation. The idea of this article is to shine some light on them and try to code them in Python.
Find elsewhere
🌐
Medium
kaabar-sofien.medium.com › the-hidden-divergence-trading-method-in-python-b77641144193
The Hidden Divergence Trading Method in Python | by Sofien Kaabar, CFA | Medium
October 3, 2022 - Divergences are known to be counter trend signals that show an exhaustion in the current trend. There exists a type of divergences that actually signal a trend continuation. The idea of this article is to shine some light on them and try to code them in Python.
🌐
YouTube
youtube.com › watch
Build a Python Trading Bot (2025) | Coding RSI Hidden Divergence Detection – Ep. 5 - YouTube
👋 Welcome to Episode 5 of my 2025 Python Algo Trading series!In this episode, we break down the full logic and flow of the system, focusing on how to code H...
Published   August 21, 2025
🌐
GitHub
github.com › markpichler › rsi-divergence-detector
GitHub - markpichler/rsi-divergence-detector: A web app I'm developing that aims to assist cryptocurrency traders by detecting RSI divergence on multiple time frames across multiple trading pairs on various exchanges.
A web app I'm developing that aims to assist cryptocurrency traders by detecting RSI divergence on multiple time frames across multiple trading pairs on various exchanges. There was an error while loading. Please reload this page. Activity · 9 stars · 1 watching · 9 forks · Report repository · No releases published · No packages published · There was an error while loading. Please reload this page. Python 100.0% You can’t perform that action at this time.
Starred by 9 users
Forked by 9 users
Languages   Python 100.0% | Python 100.0%
🌐
Babypips
babypips.com › school of pipsology › high school › trading divergences › hidden divergence
Hidden Divergence - Babypips.com
5 days ago - Learn what hidden bullish and bearish divergences are, how they differ from regular divergences, and how traders use them to spot trend continuation signals in forex.
🌐
GitHub
github.com › xoopsi › macd-divergence-detector
GitHub - xoopsi/macd-divergence-detector: This repository contains Python code for detecting MACD (Moving Average Convergence Divergence) divergences in financial time series data. The code provides functions to calculate MACD ranges, identify local peaks and troughs, and detect both regular and hidden bullish and bearish divergences.
This repository contains Python code for detecting MACD (Moving Average Convergence Divergence) divergences in financial time series data. The code provides functions to calculate MACD ranges, identify local peaks and troughs, and detect both regular and hidden bullish and bearish divergences.
Author   xoopsi
🌐
PyPI
pypi.org › project › rsi-divergence-detector
rsi-divergence-detector · PyPI
August 11, 2025 - Lightweight, tested Python library & CLI for detecting RSI divergences (regular & hidden) on time‑series price data.
      » pip install rsi-divergence-detector
    
Published   Aug 11, 2025
Version   0.1.0
🌐
QuantConnect
quantconnect.com › forum › discussion › 12411 › hidden-divergence
Hidden Divergence by Dario de Gennaro
October 3, 2021 - User seeks help coding Hidden Divergence strategy in Python for QuantConnect.
🌐
QuantInsti
blog.quantinsti.com › divergence-trading
Divergence in Trading: Types, Indicators, Strategies, and a Step-by-Step Guide
December 7, 2023 - You'll receive a step-by-step guide ... on hidden divergence opportunities. By the end of this guide, you'll have a comprehensive understanding of divergence in trading and the tools to elevate your trading skills to the next level. Some of the concepts in this blog have been taken from Technical Indicators Strategies in Python...
🌐
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 - Parameters: - df: DataFrame with 'close' prices. - indicator_values: Series with indicator values (e.g., RSI). - order: controls local extrema sensitivity. - lookback: how many bars back to compare for divergence. Returns: - df with divergence columns.
🌐
Trading Markets
tradingmarkets.com › home › articles › finding hidden setups using advanced divergence strategies
Finding Hidden Setups Using Advanced Divergence Strategies - Trading Markets
December 30, 2009 - For the first type of divergences, I look for stocks that are weaker or stronger than the general market and/or their respective sector indices. The strongest stocks are the ones that go up while the market is going down.