How to implement RSI Divergence in Python
Asked Answered
D

4

10

I was wondering is there any Python library that covers RSI-Divergence (difference between a fast and a slow RSI) or any guidence about how can I implement its algorithm in Python.

Already asked question: Programmatically detect RSI divergence. One of the answer suggests quantconnect forum for the Python version but it does not cover anything.

I was not able to find its mathematical formula but I was able to find the RSI-Divergence in pine-script, as below, but I was not able to convert it into Python since its not possible to debug pine-script using tradingview.

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))
divergence = rsi_fast - rsi_slow
plotdiv = plot(divergence, color = divergence > 0 ? lime:red, linewidth = 2)
band = hline(0)
Dolly answered 11/1, 2021 at 12:25 Comment(0)
A
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
Amalberga answered 17/1, 2021 at 4:8 Comment(2)
Where can I download pandas OHLC Dataframe dataset? or is there any example dataset that I can use (ex: BTC:USDT)?Dolly
May be you can use PyPiMetaTrader5. In this another link you may find how to use it too.Amalberga
S
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
Sallysallyann answered 22/4, 2021 at 6:20 Comment(3)
While this code block may answer the question, it would be best if you could provide a little explanation for why it does so.Tartlet
What changes did you make? Was there a bug on the accepted answer's code?Dolly
just added Data.iloc[] everywhere where he called simply Data[]Sallysallyann
F
2

Here's a concise function I found in this post. There's code for each high/low combination, it just needs a change in the inequality and can easily be expanded based on how many consecutive peaks you want to spot a divergence.

def getHigherHighs(data: np.array, order=5, K=2):
  '''
  Finds consecutive higher highs in price pattern.
  Must not be exceeded within the number of periods indicated by the width 
  parameter for the value to be confirmed.
  K determines how many consecutive highs need to be higher.
  '''
  # Get highs
  high_idx = argrelextrema(data, np.greater, order=order)[0]
  highs = data[high_idx]
  # Ensure consecutive highs are higher than previous highs
  extrema = []
  ex_deque = deque(maxlen=K)
  for i, idx in enumerate(high_idx):
    if i == 0:
      ex_deque.append(idx)
      continue
    if highs[i] < highs[i-1]:
      ex_deque.clear()
 
    ex_deque.append(idx)
    if len(ex_deque) == K:
      extrema.append(ex_deque.copy())
   
  return extrema

This follow up post (same site) builds on it and builds an RSI divergence strategy and backtests it if you want to get into more details.

Forefather answered 26/7, 2021 at 18:14 Comment(0)
L
2

I think @kieran-mackle have nailed the logic to find the divergence between price and any indicator. Kindly refer the below file for further.

https://github.com/kieran-mackle/AutoTrader/blob/main/autotrader/indicators.py

Lole answered 30/3, 2023 at 16:31 Comment(1)
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From ReviewCostotomy

© 2022 - 2024 — McMap. All rights reserved.