2
$\begingroup$

I've written python code that I believe computes RSI. I wrote the code based on what I saw in stockcharts.com found here

Here is the code:

def getRSI(close, n=14):
    """
    Computes the Relative Strength Index of a trend
    :param close: closing prices
    :param n: lookback period
    :return: a np array containing the RSI for all periods spanning 
closing price data
    """

# compute a vector for change between daily closing prices
change = np.zeros(len(close))
for i in range(1, len(close)):
    change[i] = close[i-1] - close[i]

# compute a vector of gains and losses
gain = np.zeros(len(close))
loss = np.zeros(len(close))

for i in range(1, len(close)):
    if change[i] >= 0:
        gain[i] = change[i]
    else:
        loss[i] = math.fabs(change[i])

avg_gain = np.zeros(len(close))
avg_loss = np.zeros(len(close))

avg_gain[n] = np.average(gain[0:n])
avg_loss[n] = np.average(loss[0:n])

for i in range(n, len(close)):
    avg_gain[i] = (avg_gain[i-1]*(n-1) + gain[i])/n
    avg_loss[i] = (avg_loss[i-1]*(n-1) + loss[i])/n

RS = np.zeros(len(close))
for i in range(n, len(close)):
    RS[i] = avg_gain[i]/avg_loss[i]

RSI = np.zeros(len(close))
for i in range(n, len(close)):
    RSI[i] = 100 - (100/(1+RS[i]))

return RSI

I tried to compute the RSI for COP for prices starting from 26th November 2006 to 26th November 2018. But the curve I get is completely different from what I see on Yahoo Finance or even StockCharts for that matter. What am I doing wrong?

$\endgroup$
  • $\begingroup$ Try to post this question in stackoverflow. $\endgroup$ – Newbie Nov 29 '18 at 15:54
4
$\begingroup$

I have corrected your code so that it works as it should. This code could be cleaned up a lot. I just adjusted your existing code so that you would be able to understand it. I added some comments preceded by ## on the lines that were changed. See below.

import numpy as np
from math import fabs

def getRSI(close, n=14):

    # compute a vector for change between daily closing prices
    change = np.zeros(len(close))
    for i in range(1, len(close)):        
        change[i] = close[i] - close[i-1] ##Reversed the order of these.

    # compute a vector of gains and losses
    gain = np.zeros(len(close))
    loss = np.zeros(len(close))

    for i in range(1, len(close)):
        if change[i] >= 0:
            gain[i] = change[i]
            loss[i] = 0.00 ##Each array element needs a value.
        else:
            gain[i] = 0.00 ##Each array element needs a value.
            loss[i] = fabs(change[i])

    avg_gain = np.zeros(len(close) - n) ##Array length was wrong.
    avg_loss = np.zeros(len(close) - n) ##Array length was wrong.

    avg_gain[0] = np.average(gain[1:n+1]) ##First array element has a different calculation.
    avg_loss[0] = np.average(loss[1:n+1]) ##First array element has a different calculation.

    for i in range(1, len(close) - n): ##Loop counter was wrong.
        avg_gain[i] = (avg_gain[i-1]*(n-1) + gain[i+n])/n ##Indexes were wrong.
        avg_loss[i] = (avg_loss[i-1]*(n-1) + loss[i+n])/n ##Indexes were wrong.

    RS = np.zeros(len(close) - n) ##Array length was wrong.
    for i in range(0, len(close) - n): ##Loop counter was wrong.
        RS[i] = avg_gain[i]/avg_loss[i]

    RSI = np.zeros(len(close) - n) ##Array length was wrong.
    for i in range(0, len(close) - n): ##Loop counter was wrong.
        if avg_loss[i] == 0: ##This was missing. Could throw an error without it.
            RSI[i] = 100
        else:
            RSI[i] = 100 - (100/(1+RS[i]))

    return RSI
| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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