Backtrader回测程序未生成任何仓位问题求助
嘿,我帮你排查了下代码里的几个关键问题,这些应该就是你的程序没生成任何仓位的核心原因,咱们一个个来解决:
1. 初始化方法命名错误
你把策略的初始化方法写成了__init___(多了一个下划线),Backtrader根本识别不了这个方法,相当于你的策略逻辑完全没被初始化,这是最致命的问题!
修复:把方法名改成标准的def __init__(self):
2. 未正确引用DataFeed中的字段
在初始化方法里直接写self.signal、self.take_profit是错误的——Backtrader中必须通过self.data来访问CSV里的列数据。另外,temp变量要定义成实例变量(也就是self.temp),不然next方法根本访问不到它。
修复后的初始化方法应该是这样:
def __init__(self): # 正确引用datafeed里的自定义列 self.signal = self.data.signal self.tp = self.data.take_profit self.sl = self.data.stop_loss self.high = self.data.High self.low = self.data.Low # 初始化实例变量,记录当前持仓方向 self.temp = 0
另外,加载数据的时候,得告诉Backtrader你要加载这些自定义列,否则它只会解析默认的OHLCV字段:
# 加载数据时指定自定义列 data = bt.feeds.PandasData( dataname=df, # params里的键要和你CSV/DF里的列名对应,-1表示自动匹配列名 params=( ('signal', -1), ('take_profit', -1), ('stop_loss', -1), ('High', -1), ('Low', -1), ) )
3. Next方法中未获取当前Bar的实时数据
在next方法里直接用signal == 1是不对的,self.signal是Backtrader的Line对象,必须用[0]来获取当前Bar的数值,否则你拿的是整个序列,根本没法做判断。
修复后的next方法关键部分:
def next(self): # 获取当前Bar的所有数据 current_signal = self.signal[0] current_high = self.high[0] current_low = self.low[0] current_tp = self.tp[0] current_sl = self.sl[0] if not self.position: if current_signal == 1: # 触发做多信号 self.temp = 1 self.order = self.buy() elif current_signal == 2: # 触发做空信号 self.temp = 2 self.order = self.sell() else: # 持仓时判断止盈止损 if self.temp == 1 and (current_high >= current_tp or current_low <= current_sl ): self.order = self.close() elif self.temp == 2 and (current_low <= current_tp or current_high >= current_sl ): self.order = self.close()
这里提个小建议:做空的止盈止损逻辑你可以再核对下,通常做空的止盈是价格跌到目标位,止损是涨到止损位,你的判断逻辑如果符合自己的策略就没问题,要是不符合可以再调整。
4. 最后检查两个潜在问题
- 确保你的
df已经正确加载了CSV,而且列名和你代码里引用的完全一致(比如有没有把Signal写成signal这种大小写错误) - 检查你的
signal列里确实有1或2的值,如果全是0或者NaN,那自然不会触发任何交易
修复后的完整代码大概是这样:
import backtrader as bt import backtrader.analyzers as btay import matplotlib import backtrader.feeds as btf import pandas as pd # 别忘了导入pandas加载CSV # 假设你是这样加载CSV的 df = pd.read_csv('你的CSV文件名.csv') class Supertrend(bt.Strategy): def __init__(self): self.signal = self.data.signal self.tp = self.data.take_profit self.sl = self.data.stop_loss self.high = self.data.High self.low = self.data.Low self.temp = 0 def next(self): current_signal = self.signal[0] current_high = self.high[0] current_low = self.low[0] current_tp = self.tp[0] current_sl = self.sl[0] if not self.position: if current_signal == 1: #做多 self.temp = 1 self.order = self.buy() elif current_signal == 2: #做空 self.temp = 2 self.order = self.sell() else: if self.temp == 1 and (current_high >= current_tp or current_low <= current_sl ): self.order = self.close() elif self.temp == 2 and (current_low <= current_tp or current_high >= current_sl ): self.order = self.close() cerebro = bt.Cerebro() cerebro.addstrategy(Supertrend) data = bt.feeds.PandasData( dataname=df, params=( ('signal', -1), ('take_profit', -1), ('stop_loss', -1), ('High', -1), ('Low', -1), ) ) cerebro.adddata(data) cerebro.broker.set_cash(8700) cerebro.addsizer(bt.sizers.PercentSizer, percents = 50) cerebro.broker.setcommission(commission=0.002) print('Starting Portfolio Value : %0.2f' % cerebro.broker.getvalue()) cerebro.run() cerebro.plot() print('Final Portfolio Value : %0.2f' % cerebro.broker.getvalue())
内容的提问来源于stack exchange,提问作者IU iuuu
相关产品推荐
相关产品推荐

