import backtrader as bt
import pandas as pd
# Load data
file_path = r'C:\forex\python\data\EURUSD1min-v2.xlsx'
data = pd.read_excel(file_path)
# Handle date and time in separate columns
data['Datetime'] = pd.to_datetime(data['Datetime'], format='%Y.%m.%d. %H:%M')
data.set_index('Datetime', inplace=True)
print("Data loaded, total entries:", len(data))
# Backtrader data format
class PandasData(bt.feeds.PandasData):
params = (
('datetime', None),
('open', '<OPEN>'),
('high', '<HIGH>'),
('low', '<LOW>'),
('close', '<CLOSE>'),
('volume', None),
('openinterest', None),
)
# RSI-based strategy
class RSIStrategy(bt.Strategy):
params = (
('rsi_period', 14),
('rsi_upper', 70),
('rsi_lower', 30),
)
def __init__(self):
self.rsi = bt.indicators.RSI_SMA(self.data.close, period=self.params.rsi_period)
print("RSI indicator initialized.")
def next(self):
if len(self.data.close) < self.params.rsi_period:
print("Not enough data for RSI calculation.")
return
current_rsi = self.rsi[0]
current_close = self.data.close[0]
if pd.isna(current_rsi) or current_rsi == 0:
print("Invalid or zero RSI:", current_rsi)
return
print(f"Close: {current_close}, RSI: {current_rsi}")
# Load data into Backtrader
data_feed = PandasData(dataname=data)
print("Data converted to Backtrader format.")
# Create Backtrader cerebro and add strategy
cerebro = bt.Cerebro()
cerebro.adddata(data_feed)
cerebro.addstrategy(RSIStrategy)
print("Strategy added to Cerebro.")
# Run the strategy
cerebro.run()
print("Execution finished.")
程序运行时(AT RSI 初始化)遇到错误消息 ZeroDivisionError: float 除以零
数据是正确的,从 RSI 开始。问题可能是什么?我尝试了很多东西,调试,日志。但是RSI内部的日志也不起作用,所以问题出在RSI的某个地方。
要调试此问题,请尝试验证列名称和数据格式。这可以确认 PandasData 类中指定的
print(data.head())
输出将是:
Open time Open High Low Close Volume Close time Quote asset volume Number of trades Taker buy base asset volume Taker buy quote asset volume Ignore
Datetime
2019-09-08 2019-09-08 10000.00 10412.65 10000.00 10391.63 3096.291 2019-09-08 23:59:59.999 3.209628e+07 3754 0.039 3.933563e+02 0
2019-09-09 2019-09-09 10316.62 10475.54 10077.22 10307.00 14824.373 2019-09-09 23:59:59.999 1.524472e+08 11296 5452.451 5.619740e+07 0
2019-09-10 2019-09-10 10307.00 10382.97 9940.87 10102.02 9068.955 2019-09-10 23:59:59.999 9.271765e+07 10089 6395.462 6.552636e+07 0
2019-09-11 2019-09-11 10094.27 10293.11 9884.31 10159.55 10897.922 2019-09-11 23:59:59.999 1.097862e+08 13811 7724.442 7.784116e+07 0
2019-09-12 2019-09-12 10163.06 10450.13 10042.12 10415.13 15609.634 2019-09-12 23:59:59.999 1.594942e+08 20060 10117.798 1.031607e+08 0
重命名 PandasData 中的列:更新 PandasData 类以匹配实际的列名称,因为像这样的占位符可能与 DataFrame 的结构不对齐。例如,如果您的 DataFrame 具有开盘价、最高价、最低价、收盘价等列,请使用:
class PandasData(bt.feeds.PandasData):
params = (
('datetime', None),
('open', 'Open'),
('high', 'High'),
('low', 'Low'),
('close', 'Close'),
('volume', 'Volume'),
('openinterest', None),
)