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

Backtrader策略代码运行异常:预期图表无法显示求助

问题排查:Backtrader策略仅输出初始价值无后续反馈及图表显示

问题描述

编写的Backtrader量化策略Python代码运行后仅输出组合初始价值(100000.00),无后续执行信息,且预期的策略可视化图表无法显示。

策略代码

import backtrader as bt

class TestStrategy(bt.Strategy):

    def log(self, txt, dt=None):
        ''' Logging function fot this strategy'''
        dt = dt or self.datas[0].datetime.date(0)
        print('%s, %s' % (dt.isoformat(), txt))

    def __init__(self):
        self.dataclose = self.datas[0].close
        self.sma50 = bt.indicators.SimpleMovingAverage(self.datas[0], period=50)
        self.sma200 = bt.indicators.SimpleMovingAverage(self.datas[0], period=200)
        self.macd = bt.indicators.MACD(self.data[0])
        self.bb = bt.indicators.BollingerBands(self.data[0])
        self.tema = bt.indicators.TripleExponentialMovingAverage(self.datas[0], period = 9)
        self.adx = bt.indicators.AverageDirectionalMovementIndex(self.datas[0])
        self.order = None

    def notify_order(self, order):
        if order.status in [order.Submitted, order.Accepted]:
            # Buy/Sell order submitted/accepted to/by broker - Nothing to do
            return

        # Check if an order has been completed
        # Attention: broker could reject order if not enough cash
        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')

        # Write down: no pending order
        self.order = None

    def next(self):
        if self.order:  # Check for open order
            return

        if not self.position:  # Check for existing position
            if  self.adx[0] > 30 and  self.tema[0] > self.tema[-1] and self.sma200[0] > self.dataclose[0]:
                self.order = self.buy()
                self.curratr = self.atr

        else:
            # Already in the market... we might sell
            if self.adx[0] > 70  and self.tema[0] < self.tema[-1]:
                # Keep track of the created order to avoid a 2nd order
                self.order = self.sell()

import backtrader as bt
import matplotlib
import datetime
from stradegy import TestStrategy
import pandas as pd

cerebro = bt.Cerebro()                                                    
cerebro.broker.set_cash(100000)
df = pd.read_csv("nifty50.csv")
df['date'] = df['date'].str[:10]
df['date'] = pd.to_datetime(df['date'], format='%Y-%m-%d')

start_date = '2022-10-21'
end_date = '2022-10-21'
filtered_df = df[(df['date'] >= start_date) & (df['date'] <= end_date)]

# Convert the filtered DataFrame to a PandasData feed
data = bt.feeds.PandasData(
    dataname=filtered_df,
    datetime='date'
)
cerebro.adddata(data)
cerebro.addstrategy(TestStrategy)

print('starting value of the portfolio is %.2f' % cerebro.broker.getvalue())
cerebro.run()
print('final portfolio value is as follows: %.2f'%cerebro.broker.getvalue())
cerebro.plot()

运行输出

chaitanyasachdeva@chaitanyas-MacBook-Air-2 japenese candle stick % /Users/chaitanyasachdeva/opt/anaconda3/bin/python "/Users/chaitanyasachdeva/Desktop/japenese candle stick/Test_momenyum.py" starting value of the portfolio is 100000.00

问题排查及修复方案

  • 数据时间范围过窄:代码仅筛选了单日数据,而策略中使用的SMA200、ADX等指标需要大量历史K线才能完成计算,单根K线无法触发next()逻辑,导致程序直接终止。
    修复:扩大数据时间范围,例如将start_date改为'2021-01-01',确保有足够数据计算指标。

  • 模块导入错误:

    1. 重复导入backtrader属于冗余代码,可删除;
    2. 尝试从外部stradegy模块导入TestStrategy,但该类是当前脚本内定义的,这会触发导入错误,直接中断程序。
      修复:删除重复的import backtrader as bt语句,以及错误的from stradegy import TestStrategy导入。
  • 未定义变量引用:next()中尝试赋值self.curratr = self.atr,但__init__中未初始化ATR指标,会触发AttributeError中断程序。
    修复:若需要ATR,在__init__中添加self.atr = bt.indicators.AverageTrueRange(self.datas[0]);若不需要则删除该赋值语句。

  • PandasData列映射缺失:Backtrader默认要求PandasData包含open、high、low、close等核心列,若CSV文件有这些列但未指定映射,会导致数据加载异常。
    修复:明确指定列映射,示例:

    data = bt.feeds.PandasData(
        dataname=filtered_df,
        datetime='date',
        open='open',
        high='high',
        low='low',
        close='close',
        volume='volume',
        openinterest=None
    )
    
  • matplotlib后端问题:终端环境运行时可能无法自动弹出图表,需指定后端。
    修复:在导入matplotlib后添加matplotlib.use('TkAgg')(根据操作系统调整,如Mac可用'Qt5Agg')。


内容的提问来源于stack exchange,提问作者chaitanya sachdeva

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 13:43:12