0

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)

0 Answers0