You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 18:47:30