AlgoTrading: An intro to back-testing with RSI and Python.

ByJames Burnett

The following code implements an very basic buy signal idea using a the relative strength index (RSI) and a counter to determine if a stock has dipped. This code will back-test the idea using the 60 minute time frame with 1000 hours of historical data.

Once you feel that your trading strategy works you could then use the same code to implement an automated or algo trading bot.

In order to use this code you will need a free API key from alphavantage.co. You will also need install the MatPlotLib Python module (pip install matplotlib) and the Pandas python module (pip install pandas).

Copy the contents into a file called “rsi-test.py” and run the program like this.

$ python ./rsi-test.py AMD

The Code.

import sys
import matplotlib.pyplot as plt
import pandas as pd
import mykeys


def RSI(prices, n=14):
    deltas = (prices-prices.shift(1)).fillna(0)
    avg_of_gains = deltas[1:n+1][deltas > 0].sum() / n
    avg_of_losses = -deltas[1:n+1][deltas < 0].sum() / n rsi_series = pd.Series(0.0, deltas.index) up = lambda x: x if x > 0 else 0
    down = lambda x: -x if x < 0 else 0
    i = n+1
    for d in deltas[n+1:]:
        avg_of_gains = ((avg_of_gains * (n-1)) + up(d)) / n
        avg_of_losses = ((avg_of_losses * (n-1)) + down(d)) / n
        if avg_of_losses != 0:
            rs = avg_of_gains / avg_of_losses
            rsi_series[i] = 100 - (100 / (1 + rs))
        else:
            rsi_series[i] = 100
        i += 1
    return rsi_series


api_key = 

ticker = sys.argv[1] 

rsi_length = 12

timeseries = "60min"

api_url = 'https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=' + ticker + '&interval=' + timeseries + '&apikey=' + api_key + '&datatype=csv&outputsize=full'

data = pd.read_csv(api_url)

stock_data = pd.DataFrame(index=range(0,len(data)),columns=['timestamp', 'open','high','low','close','volume'])

stock_data = stock_data.reindex(index=stock_data.index[::-1])

rsi_fairval = []



for i in range(0,len(data)):
    stock_data['timestamp'][i] = data['timestamp'][i]
    stock_data['close'][i] = float(data['close'][i])
    stock_data['high'][i] = float(data['high'][i])
    stock_data['low'][i] = float(data['low'][i])
    stock_data['open'][i] = float(data['open'][i])
    stock_data['volume'][i] = int(data['volume'][i])
    rsi_fairval.append(50)
 
 


stock_data.index = stock_data.timestamp

stock_data = stock_data.dropna()

timestamp = stock_data['timestamp']

close = stock_data['close']

high = stock_data['high']

low = stock_data['low']

open = stock_data['open']

volume = stock_data['volume']

rsi = RSI(close,rsi_length)

rsi_counter = 0

for now in range(0,len(close)):
    if now > rsi_length:
        if rsi[now] < 33:
            if rsi_counter < 2: print("OVER_SOLD",rsi_counter,timestamp[now], close[now], rsi[now]) if rsi_counter >= 2:
                print("      BUY", rsi_counter, close[now])

            rsi_counter = rsi_counter + 1

        if rsi[now] >= 50 and rsi_counter > 0:
            rsi_counter = 0
            print("RECOVERED",rsi_counter,timestamp[now], close[now], rsi[now])
        if rsi_counter < 0:
            rsi_counter = 0
       


plt.rcParams.update({
    "lines.color": "white",
    "patch.edgecolor": "white",
    "text.color": "white",
    "axes.facecolor": "black",
    "axes.edgecolor": "lightgray",
    "axes.labelcolor": "white",
    "xtick.color": "white",
    "ytick.color": "white",
    "grid.color": "lightgray",
    "figure.facecolor": "black",
    "figure.edgecolor": "black",
    "savefig.facecolor": "black",
    "savefig.edgecolor": "black"})

#Define our chart with 2 subcharts and a size of 1200x1200.
fig, axs = plt.subplots(2, 1,figsize=(18,9))



####Sub Graph 1

axs[0].set_title('Stock Chart For: ' + ticker,color='black')
axs[0].set_facecolor('#000000')
axs[0].plot(timestamp,close)
axs[0].set_xticks([0,len(close)-1], minor=False)
axs[0].set_ylabel(ticker + ' CLOSE',fontsize=18,color='white')
axs[0].tick_params(axis='x', colors='red')
axs[0].tick_params(axis='y', colors='green')
axs[0].grid(True,color='#292b2e')


fig.tight_layout()


####Sub Graph 2

axs[1].set_title('Relative Strength Index',color='black')
axs[1].set_facecolor('#000000')
axs[1].plot(timestamp,rsi)
axs[1].plot(timestamp,rsi_fairval,color='yellow')

axs[1].set_xticks([0, len(close)-1], minor=False)
axs[1].set_yticks([0, 30,50, 70, 100], minor=False)
axs[1].tick_params(axis='x', colors='red')
axs[1].tick_params(axis='y', colors='green')
axs[1].grid(True,color='#292b2e')
axs[1].set_ylabel('RSI',fontsize=18,color='white')
print("Done.")
plt.show()



%d bloggers like this: