Backtrader多时间框架策略重复下单问题:仅在日线触发交易
解决Backtrader双时间框架重复下单问题
问题根源
在Backtrader多时间框架策略中,next()方法会对每个加载的数据源(日线、周线)各执行一次,导致满足条件时重复生成订单。
解决方案
要实现仅在日线时间框架下,同时满足日线+周线条件时生成订单,需做以下修改:
限制下单逻辑仅在日线数据源触发时执行
在next()方法开头添加判断,只在处理第一个数据源(日线)时执行后续逻辑,跳过周线数据源的next()调用。完善双时间框架条件判断
恢复代码中被注释的周线条件,确保开仓/平仓同时满足日线和周线的SuperTrend交叉条件。修复代码语法错误
修正初始化方法名、缩进问题、导入语句缺失等语法错误,保证代码正常运行。
修改后的完整代码
from __future__ import (absolute_import, division, print_function, unicode_literals) import backtrader as bt import backtrader.indicators as btind import datetime import os.path import sys import pandas as pd from backtrader.indicators.supertrend import SuperTrend # 补全导入类名 class SuperTrendStrategy(bt.Strategy): params = dict( onlydaily = False ) def printdata(self, data): print(data) def log(self, txt, dt=None): ''' 日志记录函数 ''' dt = dt or self.datas[0].datetime.date(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): # 修正初始化方法名 # 日线数据引用 self.dataopen = self.datas[0].open self.datahigh = self.datas[0].high self.datalow = self.datas[0].low self.dataclose = self.datas[0].close # 周线数据引用 self.dataopen2 = self.datas[1].open self.datahigh2 = self.datas[1].high self.datalow2 = self.datas[1].low self.dataclose2 = self.datas[1].close # 初始化SuperTrend指标 self.supertrend = SuperTrend(self.data, period=10, multiplier=3) if not self.p.onlydaily: self.supertrend2 = SuperTrend(self.data1, period=10, multiplier=1) # 交叉信号 self.crossup = btind.CrossUp(self.dataclose, self.supertrend) self.crossdown = btind.CrossDown(self.dataclose, self.supertrend) # 跟踪未完成订单 self.order = None def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: # 订单已提交/接受,无需处理 return # 检查订单是否完成 if order.status in [order.Completed]: if order.isbuy(): self.log('BUY EXECUTED, %.2f' % order.executed.price) elif order.issell(): self.log('SELL EXECUTED, %.2f' % order.executed.price) self.bar_executed = len(self) elif order.status in [order.Canceled, order.Margin, order.Rejected]: self.log('Order Canceled/Margin/Rejected') # 重置未完成订单标记 self.order = None def next(self): # 仅在处理日线数据源时执行下单逻辑 if self._lastdataindex != 0: # _lastdataindex为当前处理的数据源索引,0对应日线 return # 如果有未完成订单,不生成新订单 if self.order: return # 开仓逻辑:无持仓,且日线向上交叉+周线收盘价在SuperTrend上方 if not self.position: if self.crossup[0] == 1 and self.dataclose2[0] > self.supertrend2[0]: self.log('Entry trade') self.buy() # 平仓逻辑:持有多单,且日线向下交叉+周线收盘价在SuperTrend下方 else: if self.position.size > 0: if self.crossdown[0] == 1 and self.dataclose2[0] < self.supertrend2[0]: self.log('Exit trade') self.sell()
关键修改说明
- 数据源判断:通过
self._lastdataindex != 0跳过周线数据源的next()执行,确保只有日线触发时才处理下单逻辑。 - 双条件判断:开仓时同时检查日线向上交叉信号和周线收盘价在SuperTrend上方;平仓时同时检查日线向下交叉信号和周线收盘价在SuperTrend下方。
- 语法修复:补全
SuperTrend类导入,修正初始化方法名__init__,统一代码缩进,修复notify_order方法的缩进错误。
修改后的预期效果
下单逻辑仅在日线bar更新时执行,且只有当日线和周线条件同时满足时才生成订单,不会再出现重复下单的情况。
内容的提问来源于stack exchange,提问作者user395882
相关产品推荐
相关产品推荐

