import sys
sys.path.insert(0,"/home/william/Financial/financial_calcs/")
import trading_calcs.standard as std_calcs
import numpy as np
import pandas as pd
import pandas_datareader as pdr
import matplotlib.pyplot as plt
%matplotlib inline
df1 = pd.read_excel('./financial_calcs/cs-rsi.xls',index_col=0,header=1,usecols="C:K",nrows=33)
df1.columns = ['Close','Change','Gain','Loss','Avg Gain','Avg Loss', 'RS', 'RSI']
df1.head(15)
gldf = std_calcs.gain_loss_calc(df1['Close'])
df1.to_pickle('./financial_calcs/rsi_data.pkl')
# TODO: compare the results of the two data frames could use assert_frame_equal
from pandas.testing import assert_frame_equal
ref_gldf = df1[['Gain','Loss']]
ref_gldf = ref_gldf.fillna(0)
ref_gldf = ref_gldf.round(4)
gldf = gldf.round(4)
result = assert_frame_equal(ref_gldf, gldf)
pd.concat([gldf, ref_gldf], axis=1)
def gain_loss_calc(price):
"""
Returns a DataFrame containing the Gain and Loss from a price time series.
Usually price is closing price.
"""
if not isinstance(price, pd.Series):
raise TypeError()
chg = price.diff()
gain = np.where(chg > 0, chg, 0)
gain = np.abs(gain)
gain = pd.Series(gain,index=price.index)
loss = np.where(chg < 0, chg, 0)
loss = np.abs(loss)
loss = pd.Series(loss,index=price.index)
df1 = pd.DataFrame(data={'Gain':gain,'Loss':loss})
return df1
gldf1 = gain_loss_calc(df1['Close'])
gldf2 = pd.concat([gldf1,ref_gldf],axis=1)
gldf2.head(20)
#now it looks like gain and loss are the same based on difference vs percent change
#TODO: Calculate avg gain and avg loss and compare
https://school.stockcharts.com/doku.php?id=technical_indicators:relative_strength_index_rsi
The very first calculations for average gain and average loss are simple 14-period averages:
The second, and subsequent, calculations are based on the prior averages and the current gain loss:
# try to just add the first few examples and see what happens
g1 = gldf1['Gain'].iloc[0:15].sum()/14
g1
g2 = (g1*13)/14
g2
g3 = (g2*13 + 0.03)/14
g3
gldf1['Gain'].iloc[1:16].sum()/14
gldf1['Gain'].shape
first_avg_gain = gldf1['Gain'].iloc[0:15].sum()/14
print("First Average Gain =",first_avg_gain)
avg_gain_arry = np.zeros(gldf1['Gain'].shape)
for i in range(14,len(avg_gain_arry)):
if i == 14:
avg_gain_arry[i] = first_avg_gain
else:
avg_gain_arry[i] = (avg_gain_arry[i-1]*13+gldf1['Gain'].iloc[i])/14
avg_gain = pd.Series(avg_gain_arry,name='Avg Gain',index=gldf1.index)
gldf3 = pd.concat([avg_gain,df1[['Avg Gain','Gain']]],axis=1)
gldf3.head(20)
first_avg_loss = gldf1['Loss'].iloc[0:15].sum()/14
print("First Average Loss =",first_avg_loss)
avg_loss_arry = np.zeros(gldf1['Loss'].shape)
for i in range(14,len(avg_loss_arry)):
if i == 14:
avg_loss_arry[i] = first_avg_loss
else:
avg_loss_arry[i] = (avg_loss_arry[i-1]*13+gldf1['Loss'].iloc[i])/14
avg_loss = pd.Series(avg_loss_arry,name='Avg Loss',index=gldf1.index)
gldf3 = pd.concat([avg_loss,df1[['Avg Loss','Loss']]],axis=1)
gldf3.head(20)
# Now to calculate relative strength
RS = avg_gain/avg_loss
RS.name = "RS"
rsdf = pd.concat([RS,df1['RS']],axis=1)
rsdf.head(20)
# Now to calculate RSI
RSI = 100-(100/(1+RS))
RSI.name = "RSI"
rsidf = pd.concat([RSI,df1['RSI']],axis=1)
rsidf.tail(15)
RSI.dtype
rsi1 = df1['RSI']
rsi2 = rsi1.iloc[14:-1]
rsi2.astype('float64')
gldf_1 = std_calcs.gain_loss_calc(df1['Close'])
gldf_compare = pd.concat([gldf_1,df1['Gain'],df1['Loss']],axis=1)
gldf_compare.head(5)
rsi_1 = std_calcs.rsi_calc(gldf_1['Gain'],gldf_1['Loss'],14)
rsi_compare = pd.concat([rsi_1,df1['RSI']],axis=1)
rsi_compare.head(20)