Backtrader是一款纯Python的回测+实盘框架。从软件工程的角度,这个项目非常值得学习。这个框架的代码风格非常Pythonic,也值得借鉴和学习。作者是一个很严谨的德国人,从他的代码审查和社区管理可见一斑。
backtrader允许您专注于编写可重复使用的交易策略,指标和分析器,而不必花时间构建基础架构。
 
backtrader的思路是通过历史回顾每个bar来进行回测追溯,可能会更简单理解一点。
论坛有采生之前写过的帖子,大家也可以去学习一波,我是学习完之后,总结了一下这篇笔记。
最终会生成图表,有助于我们进行分析,可以清晰的看到开关仓点位,以及盈利情况等。
基本概念 在学习backtrader之前需要大概先了解他的几个核心组件,如果你不想了解也没事,直接看代码就好啦。看到不懂的回来参考一下即可。
Cerebro:BackTrader的基石,所有的操作都是基于Cerebro的。 
Feed:将运行策略所需的基础数据加载到Cerebro中,一般为K线数据。 
Indicator:BackTader自带的指标,并集成了talib中的指标。我们也可以选择继承一个Indicator实现自己的指标。 
Strategy:交易策略。这里是整个过程中最复杂的部分,需要我们计算买入/卖出信号。 
Analyzer:分析器,以图形和风险收益等指标对交易策略的回测结果进行分析评价。 
Order:订单,记录了与当前订单相关的所有数据。 
Trader:交易,记录了与当前交易相关的所有数据。 
Position:持仓,记录了与当前持仓相关的所有数据。 
Broker:可以理解成经纪人,整个策略的初始资金、交易费率、滑点等参数需要通过Broker进行设置。 
Observer:观察者,对数据进行监控观察,比如资金曲线等等。 
Plotting:可视化组件 
 
每个组件在程序运行中对应的功能 
框架思路 
我们先获得数据源,backtrader有很多种方式获得数据源,但是数据源要遵循一般的结构模式,最少要包含以下字段:Open(开盘价),High(最高价),Low(最低价),Close(收盘价),Volume(成交量)–>ohlcv 
数据加载(Data Feed)将历史数据加载到回测框架中 
 
交易策略(Strategy):该模块是编程过程中最复杂的部分,需要设计交易决策,得出买入/卖出信号。   
回测框架设置(Cerebro):需要设置   
初始资金   
交易佣金   
数据反馈   
交易策略   
运行回测:运行Cerebro回测并打印出所有已执行的交易。   
评估性能(Analyzers):以图形和风险收益等指标对交易策略的回测结果进行评价。 
 
具体的实现可以看我画的这个流程图,可以让你更好的理解运行的过程。
实战编写代码 安装backtrader 1 2 3 pip install backtrader # matplotibli 需要安装3.2.2 最新班班的3.4.2我使用有问题 pip install matplotlib==3.2.2 
引入backtrader 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import backtrader as bt if __name__ == '__main__':     cerebro = bt.Cerebro()     print("starting portfolio value: %.2f" % cerebro.broker.getvalue())     cerebro.run()     print("final portfolio value: %.2f" % cerebro.broker.getvalue()) """ starting portfolio value: 10000.00 final portfolio value: 10000.00 """ 
实现简单的策略 
加载外部feather数据到cerebro 
实现订单监听方法:notify_order 
实现策略类 
上涨突破20日均线执行买入 
下跌突破20日均线执行卖出 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 import backtrader as bt import pandas as pd import matplotlib.pyplot as plt class MyStrategy(bt.Strategy):     params = (         ('m', 20),     )     def log(self, txt, dt=None):         df = self.datas[0].datetime.date(0)         print('%s, %s' % (df.isoformat(), txt))     def __init__(self):         self.dataclose = self.datas[0].close         self.sma = bt.indicators.SMA(self.datas[0], period=self.params.m)         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)             print('=======order',self.bar_executed)         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:             self.log("==is order: %s" % self.order)             return         # 检查是否持仓         if not self.position:             # 上涨突破20日均线执行买入             if self.dataclose[0] > self.sma[0]:                 self.log('BUY CREATE, %.2f' % self.dataclose[0])                 self.order = self.buy()         else:             # 下跌突破20日均线执行卖出             if self.dataclose[0] < self.sma[0]:                 self.log('SELL CREATE, %.2f' % self.dataclose[0])                 self.order = self.sell() if __name__ == '__main__':     cerebro = bt.Cerebro()     cerebro.addstrategy(MyStrategy)      # 读取数据     df = pd.read_feather('./BTCUSDT_1d.feather')     df.candle_begin_time = pd.to_datetime(df.candle_begin_time)     df.set_index('candle_begin_time', inplace=True)     # 给cerebro添加数据     data = bt.feeds.PandasData(dataname=df)     cerebro.adddata(data)     # 设置初始化资金     cerebro.broker.setcash(10000.0)         cerebro.broker.setcommission(commission=0.002)  # 手续费     cerebro.run()     cerebro.plot() 
最终出来的图表如下,可以清晰的看到开仓和平仓的点位
至此就完成了第一个backtrader的回测。
参考 backtrader官网 
【Backtrader教程01】Python Backtrader量化回测框架 
Backtrader框架系列视频量化交易策略实战回测 量化交易金融投资Python量化 
使用BackTrader进行回测01:BackTrader是什么 
量化回测框架的对比 https://zhuanlan.zhihu.com/p/81007132