点此获取扫地僧backtrader技术教程
===============
之前,我写了一篇文章“backtrader高级专题:策略绩效评价:用不了pyfolio?还有quantstats”,提到backtrader现在不能直接集成pyfolio,但是可以集成quantstats,进行策略绩效展示。
最近,我再次研究了pyfolio,发现现在已经可以集成到backtrader了。至少我自己测试通过了。注意,pyfolio只能用于notebook里,而quantstats可用于notebook和普通.py文件里,大家各取所需吧。
下面介绍如何在backtrader里使用pyfolio。
1 安装pyfolio
必须使用如下命令安装pyfolio,这样安装的是最新版:
pip install git+https://github.com/quantopian/pyfolio
不能使用pip install pyfolio来安装。很多人集成不了pyfolio,就是因为安装方式不对。
2 在backtrader中使用pyfolio
样本代码test.ipynb如下
from datetime import datetime
import backtrader as bt
# 导入pyfolio 包
import pyfolio as pf
# 创建策略类
class SmaCross(bt.Strategy):
# 定义参数
params = dict(period=5) # 移动平均期数
# 日志函数
def log(self, txt, dt=None):
'''日志函数'''
dt = dt or self.datas[0].datetime.date(0)
print('%s, %s' % (dt.isoformat(), txt))
def notify_order(self, order):
if order.status in [order.Submitted, order.Accepted]:
# 订单状态 submitted/accepted,无动作
return
# 订单完成
if order.status in [order.Completed]:
if order.isbuy():
self.log('买单执行, %.2f' % order.executed.price)
elif order.issell():
self.log('卖单执行, %.2f' % order.executed.price)
elif order.status in [order.Canceled, order.Margin, order.Rejected]:
self.log('订单 Canceled/Margin/Rejected')
# 记录交易收益情况(可省略,默认不输出结果)
def notify_trade(self, trade):
if trade.isclosed:
print('毛收益 %0.2f, 扣佣后收益 % 0.2f, 佣金 %.2f' %
(trade.pnl, trade.pnlcomm, trade.commission))
def __init__(self):
# 移动平均线指标
self.move_average = bt.ind.MovingAverageSimple(
self.data, period=self.params.period)
# 交叉信号指标
self.crossover = bt.ind.CrossOver(self.data, self.move_average)
def next(self):
if not self.position: # 还没有仓位
# 当日收盘价上穿5日均线,创建买单,买入100股
if self.crossover > 0:
self.log('创建买单')
self.buy(size=100)
# 有仓位,并且当日收盘价下破5日均线,创建卖单,卖出100股
elif self.crossover < 0:
self.log('创建卖单')
self.sell(size=100)
##########################
# 主程序开始
#########################
# 创建大脑引擎对象
cerebro = bt.Cerebro()
# 数据文件路径
datapath = './600000.csv'
# 创建行情数据对象,加载数据
data = bt.feeds.GenericCSVData(
dataname=datapath,
datetime=2, # 日期行所在列
open=3, # 开盘价所在列
high=4, # 最高价所在列
low=5, # 最低价所在列
close=6, # 收盘价价所在列
volume=10, # 成交量所在列
openinterest=-1, # 无未平仓量列
dtformat=('%Y%m%d'), # 日期格式
fromdate=datetime(2019, 1, 1), # 起始日
todate=datetime(2020, 7, 8)) # 结束日
cerebro.adddata(data) # 将行情数据对象注入引擎
cerebro.addstrategy(SmaCross) # 将策略注入引擎
cerebro.broker.setcash(10000.0) # 设置初始资金
# 加入pyfolio分析者
cerebro.addanalyzer(bt.analyzers.PyFolio, _name='pyfolio')
results=cerebro.run() # 运行
strat = results[0]
pyfoliozer = strat.analyzers.getbyname('pyfolio')
returns, positions, transactions, gross_lev = pyfoliozer.get_pf_items()
pf.create_full_tear_sheet(returns)
这里pf.create_full_tear_sheet(returns)中pyfolio需要的收益率returns是日收益率。
如果backtrader原始数据不是日线数据,我估计returns, positions, transactions, gross_lev = pyfoliozer.get_pf_items()中,backtrader返回的returns应该是已经转换成日收益率了,读者可以验证一下告诉我哈。