As I was running my RSI crossover back-testing script on Jupyter, I encountered an unexpected error message. Upon closer examination, I discovered that the issue stemmed from a KeyError with the "rsi21" column. This came as a surprise to me, as I had previously defined the "rsi21" column in my code and it had been functioning without issue up until this point. I have tried to troubleshoot the problem by carefully reviewing my code for any typos or syntax errors, but to no avail. It is frustrating to encounter this issue and I am eager to find a solution. Can anyone provide any insight or assistance in resolving this KeyError with the "rsi21" column?
KeyError Traceback (most recent call last)
File ~\.julia\conda\3\lib\site-packages\pandas\core\indexes\base.py:3803, in Index.get_loc(self, key, method, tolerance)
3802 try:
-> 3803 return self._engine.get_loc(casted_key)
3804 except KeyError as err:
File ~\.julia\conda\3\lib\site-packages\pandas\_libs\index.pyx:138, in pandas._libs.index.IndexEngine.get_loc()
File ~\.julia\conda\3\lib\site-packages\pandas\_libs\index.pyx:165, in pandas._libs.index.IndexEngine.get_loc()
File pandas\_libs\hashtable_class_helper.pxi:5745, in pandas._libs.hashtable.PyObjectHashTable.get_item()
File pandas\_libs\hashtable_class_helper.pxi:5753, in pandas._libs.hashtable.PyObjectHashTable.get_item()
KeyError: 'rsi21'
The above exception was the direct cause of the following exception:
KeyError Traceback (most recent call last)
Cell In [31], line 28
26 df_temp = df_5min[df_5min.index.date == index.date()]
27 # if the RSI21 is above the RSI55 and RSI100 and the RSI is above 30 in the 5 minute interval data, place a buy order
---> 28 if (row['rsi21'] > row['rsi55']) and (row['rsi21'] > row['rsi100']) and (df_temp['rsi21'].values[-1] > 30):
29 # place buy order
30 num_trades += 1
31 # calculate profit/loss based on the current price and the buy price
File ~\.julia\conda\3\lib\site-packages\pandas\core\frame.py:3805, in DataFrame.__getitem__(self, key)
3803 if self.columns.nlevels > 1:
3804 return self._getitem_multilevel(key)
-> 3805 indexer = self.columns.get_loc(key)
3806 if is_integer(indexer):
3807 indexer = [indexer]
File ~\.julia\conda\3\lib\site-packages\pandas\core\indexes\base.py:3805, in Index.get_loc(self, key, method, tolerance)
3803 return self._engine.get_loc(casted_key)
3804 except KeyError as err:
-> 3805 raise KeyError(key) from err
3806 except TypeError:
3807 # If we have a listlike key, _check_indexing_error will raise
3808 # InvalidIndexError. Otherwise we fall through and re-raise
3809 # the TypeError.
3810 self._check_indexing_error(key)
KeyError: 'rsi21'
In an effort to resolve the KeyError with the "rsi21" column, I tried several different approaches. First, I checked my code for any typos or syntax errors that could be causing the issue. I also tried re-running the script to see if the error was a temporary glitch. However, neither of these approaches yielded any results. I was expecting the script to run smoothly and for the "rsi21" column to be recognized without issue. However, instead, I received the KeyError message and the script halted. This discrepancy between my expectations and the actual result has been frustrating and I am seeking a solution to resolve the issue.
import yfinance as yf
start_date = "2020-01-01"
end_date = "2022-12-31"
stock = yf.Ticker("SPY")
df = stock.history(start=start_date, end=end_date)
def moving_average(df, window):
return df['Close'].rolling(window=window).mean()
df_5min = stock.history(interval='5m')
def rsi(df, window):
# create a new column for the difference between the current and previous close
df['diff'] = df['Close'].diff()
# create new columns for the gain and loss
df['gain'] = df['diff'].apply(lambda x: x if x > 0 else 0)
df['loss'] = df['diff'].apply(lambda x: abs(x) if x < 0 else 0)
# calculate the average gain and loss over the specified window
avg_gain = df['gain'].rolling(window=window).mean()
avg_loss = df['loss'].rolling(window=window).mean()
# calculate the relative strength
df['rs'] = avg_gain / avg_loss
# return the relative strength index
return 100 - (100 / (1 + df['rs']))
df['rsi21'] = rsi(df, 21)
df['rsi55'] = rsi(df, 55)
df['rsi100'] = rsi(df, 100)
num_trades = 0
total_profit = 0
for index, row in df.iterrows():
# get the 5-minute interval data for the current date
df_temp = df_5min[df_5min.index.date == index.date()]
# if the RSI21 is above the RSI55 and RSI100 and the RSI is above 30 in the 5 minute interval data, place a buy order
if (row['rsi21'] > row['rsi55']) and (row['rsi21'] > row['rsi100']) and (df_temp['rsi21'].values[-1] > 30):
# place buy order
num_trades += 1
# calculate profit/loss based on the current price and the buy price
profit = row['Close'] - df_temp['Open'].values[-1]
total_profit += profit
# if the RSI21 is below the RSI55 and RSI100 and the RSI is below 70 in the 5 minute interval data, place a sell order
elif (row['rsi21'] < row['rsi55']) and (row['rsi21'] < row['rsi100']) and (df_temp['rsi21'].values[-1] < 70):
# place sell order
num_trades += 1
# calculate profit/loss based on the current price and the sell price
profit = df_temp['Open'].values[-1] - row['Close']
total_profit += profit
#print the total number of trades and total profit/loss
print("Total number of trades:", num_trades)
print("Total profit/loss:", total_profit)