当前位置: 代码迷 >> 综合 >> backtrader:终于可以集成pyfolio了
  详细解决方案

backtrader:终于可以集成pyfolio了

热度:56   发布时间:2023-12-08 09:29:36.0

点此获取扫地僧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日均线,创建买单,买入100if 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应该是已经转换成日收益率了,读者可以验证一下告诉我哈。