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',确保有足够数据计算指标。模块导入错误:
- 重复导入
backtrader属于冗余代码,可删除; - 尝试从外部
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
相关产品推荐
相关产品推荐

