backtrader中notify_timer未被调用问题求助:每月初定时器无触发
Backtrader每月第一天定时器未触发的问题排查
核心问题分析及解决方法:
数据时间索引错误
你调用reset_index()后,yfinance返回的DatetimeIndex被转换成了普通列,backtrader的PandasData默认依赖索引识别时间戳,导致定时器无法正确判断日期。
修正方式二选一:# 方式1:保留原DatetimeIndex(推荐) data = yf.Ticker("SPY").history(period="5y") cerebro.adddata(bt.feeds.PandasData(dataname=data)) # 方式2:指定datetime列(如果必须reset_index) data = yf.Ticker("SPY").history(period="5y").reset_index() cerebro.adddata(bt.feeds.PandasData(dataname=data, datetime='Date'))定时器触发时机不匹配
bt.timer.SESSION_END是在交易日结束时检查触发条件,若希望在每月第一个交易日开始时执行操作,建议改用bt.timer.SESSION_START,更贴合策略执行逻辑:self.add_timer(bt.timer.SESSION_START, monthdays=[1], monthcarry=True)验证数据覆盖范围
确认你的数据包含每月第一个交易日(或因monthcarry=True顺延的交易日),可以先打印数据的日期列,检查是否存在符合条件的日期点。
修正后的完整代码示例:
import backtrader as bt import yfinance as yf class MyStrategy(bt.Strategy): def __init__(self): self.add_timer(bt.timer.SESSION_START, monthdays=[1], monthcarry=True) def notify_timer(self, timer, *args, **kwargs): print(f"Timer triggered on {self.datas[0].datetime.date(0)}: 可执行买卖操作") cerebro = bt.Cerebro() cerebro.addstrategy(MyStrategy) # 正确加载数据,保留时间索引 data = yf.Ticker("SPY").history(period="5y") cerebro.adddata(bt.feeds.PandasData(dataname=data)) cerebro.broker.setcash(1000.0) print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) cerebro.run() print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
内容的提问来源于stack exchange,提问作者dnn-6
相关产品推荐
相关产品推荐

