I'm working on a Python project using the Backtrader library to calculate the Relative Strength Index (RSI) for a financial dataset. However, I'm encountering an "array index out of range" error when trying to access the RSI values from the bt.indicators.RSI indicator.
For instance, I have used static values in my code for demonstration purposes.
code:
def relative_strength_index(self, asset: str, days: int) -> float:
try:
# data = self.strategy.getdatabyname(asset)
data = pd.DataFrame({
'datetime': pd.date_range(start='2022-12-19', periods=20, freq='D'),
'open': [100, 102, 105, 103, 107, 110, 108, 106, 109, 112, 115, 118, 120, 122, 119, 116, 113, 111, 108, 106],
'high': [102, 105, 108, 106, 110, 112, 110, 108, 112, 114, 117, 120, 124, 126, 121, 118, 116, 114, 112, 110],
'low': [98, 100, 103, 101, 104, 108, 106, 104, 107, 110, 113, 116, 118, 120, 117, 114, 112, 110, 108, 106],
'close': [101, 104, 107, 105, 109, 111, 109, 107, 110, 113, 116, 119, 121, 124, 120, 117, 114, 112, 110, 108],
'volume': [1000, 1200, 1300, 1100, 1500, 1600, 1400, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 1800, 1700, 1600, 1500, 1400, 1300]
})
# Create a Backtrader data feed from the DataFrame
data_feed = bt.feeds.PandasData(dataname=data, datetime='datetime')
# Define the RSI period
days = 14
# Create an RSI indicator with the specified period
rsi = bt.indicators.RSI(data_feed.close, period=days)
# Print the RSI values
for i, rsi_value in enumerate(rsi):
print(f'Day {i + 1}: RSI = {rsi_value[0]:.2f}')
return rsi[0]
except Exception as e:
raise e
Despite using static values, the RSI indicator returns backtrader.indicators.rsi.RSI object with an empty array. Can anyone explain why this is happening and how I can resolve it to calculate RSI correctly ?
you can try this :
import backtrader as bt
import pandas as pd
class MyStrategy(bt.Strategy):
params = (('rsi_period', 14),)
def __init__(self):
self.rsi = bt.indicators.RSI(self.data.close, period=self.params.rsi_period)
def next(self):
print(f'Date: {self.data.datetime.date()}, RSI: {self.rsi[0]:.2f}')
def run_backtest():
cerebro = bt.Cerebro()
data = pd.DataFrame({
# ... [as in your original code]
})
data_feed = bt.feeds.PandasData(dataname=data, datetime='datetime')
cerebro.adddata(data_feed)
cerebro.addstrategy(MyStrategy, rsi_period=14)
cerebro.run()
if __name__ == "__main__":
run_backtest()