Backtrader导入CSV数据报ValueError: year x is out of range如何解决
问题解决方案
错误原因
你遇到的ValueError: year x is out of range错误由毫秒级Unix时间戳格式不匹配导致:
- 你的CSV文件第一列为13位毫秒级Unix时间戳
- Backtrader中
dtformat=2配置仅支持10位秒级Unix时间戳,直接传入13位数值会被解析为远超出合理范围的年份,触发报错
解决方案
有两种可选用的解决方式,推荐优先使用第一种,无需修改原始CSV文件:
方式1:自定义时间解析函数(推荐)
在你的代码中新增时间戳转换函数,同时补充数据源列的映射配置即可,修改后的完整代码如下:
import backtrader as bt import matplotlib # 新增毫秒时间戳转datetime对象的函数 def millisec_parser(timestamp_str): return bt.num2date(int(timestamp_str) / 1000) class RSIStrategy(bt.Strategy): def __init__(self): self.rsi = bt.talib.RSI(self.data, period=14) def next(self): if self.rsi < 30 and not self.position: self.buy(size=1) if self.rsi > 70 and self.position: self.close() cerebro = bt.Cerebro() # 修改数据源配置,传入自定义解析函数,补充列映射 data = bt.feeds.GenericCSVData( dataname='daily_2021.csv', dtformat=millisec_parser, open=1, high=2, low=3, close=4, volume=5, openinterest=-1 # 无持仓量数据,设为-1忽略该字段 ) cerebro.adddata(data) cerebro.addstrategy(RSIStrategy) cerebro.run() # 若绘图报错可添加iplot=False参数,或把matplotlib降级到3.2.2版本 cerebro.plot(iplot=False)
方式2:预处理CSV文件转换时间戳
如果不想修改原有导入逻辑,可以先把CSV的时间戳转换为秒级,运行如下预处理脚本生成新的CSV文件:
import pandas as pd # 读取原始CSV df = pd.read_csv('daily_2021.csv', header=None) # 第一列毫秒时间戳转秒级 df[0] = df[0] // 1000 # 保存新文件 df.to_csv('daily_2021_seconds.csv', index=False, header=False)
之后把原有代码中数据源的文件名替换为新生成的daily_2021_seconds.csv即可,不需要修改其他配置。
内容的提问来源于stack exchange,提问作者Swashbuckler75
相关产品推荐
相关产品推荐

