backtrader的回测结果之Bokel quantstats backtrader_plotting btplotting

backtrader 量化回测模块中 cerebro.plot()图像不是很方便使用,所以测试了很多作图相关的模块;
总结:
1.backtrader_bokeh这个应该是一种付费的模块,所以本人没有钱
2. quantstats quantstats
这个模块最关键的是要做索引设置returns.index = returns.index.tz_convert(None)

cerebro.addanalyzer(bt.analyzers.PyFolio, _name='pyfolio')
back  = cerebro.run(maxcpus=12,exactbars=True,stdstats=False)

strat = back[0]
portfolio_stats = strat.analyzers.getbyname('pyfolio')
returns, positions, transactions, gross_lev = portfolio_stats.get_pf_items()
returns.index = returns.index.tz_convert(None)

3.backtrader_plotting 是Bokeh专门针对backtrader开发的模块port端口没有办法改变,不方便做成相关服务被flask app调用,只能单独使用https://github.com/verybadsoldier/backtrader_plotting

4.btplotting 这个模块是在backtrader_plotting模块下改进的,可以改变相关端口port,构建单独的新服务被flask app 进行整合,但是不能够适应复杂策略需求,同时在backtrader Bokeh模块下有个小bug需要在处理

5.backtrader_plotly这个模块没有进行相关测试,感觉不太被维护 https://github.com/lamkashingpaul/backtrader_plotly

6.Bokeh这个是backtrader自带的作图模块,上面这些都是基于此模型改进开发的

7.如果想要一个适合自己喜欢那就动手造吧!知乎上的大神做了
Dash plotly https://zhuanlan.zhihu.com/p/98775974

8.折腾案例学习和借鉴,量化大道溜达走起
BTR-E2020 https://github.com/klein203/BTR-E2020

learn_backtrader
https://github.com/jrothschild33/learn_backtrader

from btplotting import BacktraderPlotting, BacktraderPlottingOptBrowser
from btplotting.schemes import Tradimo

def btplotting_results():
    result = cerebro.run(optreturn=False)
    strat = result[0]
    btp = BacktraderPlotting(style='bar', multiple_tabs=True)
    browser = BacktraderPlottingOptBrowser(btp, strat,port=9000)
    browser.start()
    return
from __future__ import (absolute_import, division, print_function,unicode_literals)

import datetime  # 用于datetime对象操作
import os.path  # 用于管理路径
import sys  # 用于在argvTo[0]中找到脚本名称
import backtrader as bt # 引入backtrader框架
import backtrader.feeds as btfeeds
import pandas as pd

import quantstats
import warnings
warnings.filterwarnings('ignore')

import math
# 创建策略
class SmaCross(bt.Strategy):
    # 可配置策略参数
    params = dict(
        pfast=10,  # 短期均线周期
        pslow=30,  # 长期均线周期
        poneplot=False,  # 是否打印到同一张图
        # pstake = 1000 # 单笔交易股票数目
    )

    def __init__(self):
        # self.log_file = open('position_log.txt', 'w') # 用于输出仓位信息
        self.inds = dict()
        for i, d in enumerate(self.datas):
            self.inds[d] = dict()
            self.inds[d]['dataclose'] = d.close
            self.inds[d]['sma1'] = bt.ind.SMA(d.close, period=self.p.pfast)  # 短期均线
            self.inds[d]['sma2'] = bt.ind.SMA(d.close, period=self.p.pslow)  # 长期均线
            self.inds[d]['cross'] = bt.ind.CrossOver(self.inds[d]['sma1'], self.inds[d]['sma2'], plot=False)  # 交叉信号
            # 跳过第一只股票data,第一只股票data作为主图数据
            if i > 0:
                if self.p.poneplot:
                    d.plotinfo.plotmaster = self.datas[0]

    def next(self):
        for i, d in enumerate(self.datas):
            dt, dn = self.datetime.date(), d._name  # 获取时间及股票代码
            pos = self.getposition(d)

            # 买入策略
            if not len(pos):  # 不在场内,则可以买入
                if self.inds[d]['cross'] > 0:  # 如果金叉
                    # self.buy(data = d, size = self.p.pstake) # 买买买
                    self.buy(data=d)  # 买买买

            # 止损策略
            elif self.inds[d]['cross'] < 0:  # 在场内,且死叉
                self.close(data=d)  # 卖卖卖


            elif ((pos.price - pos.adjbase) > 0.3) or ((pos.adjbase - pos.price) > 0.4):
                #                 print("code: {},pos_price:{},today_close:{},value_size{}".format(
                #                     d._name, pos.price, pos.adjbase,pos.size))
                self.close(data=d)  # 卖卖卖

cerebro = bt.Cerebro()
import tushare as ts

# 初始化pro接口,写自己的免费token
pro = ts.pro_api('******************************')
data = pro.query('stock_basic', exchange='', list_status='L', fields='ts_code')
stk_pools = data.ts_code[:5]

def quantstats_cerebro_plot():
    results = cerebro.run(stdstats=False, tradehistory=True)  # execute
    strat = results[0]

    pyfoliozer = strat.analyzers.getbyname('pyfolio')

    returns, positions, transactions, gross_lev = pyfoliozer.get_pf_items()
    returns.index = returns.index.tz_convert(None)
    quantstats.reports.html(returns,output='fstatss.html',download_filename='fstatss.html', title='Returns Sentiment')

    return
def bokeh_cerebro_plot():
    from backtrader_plotting import Bokeh, OptBrowser
    from backtrader_plotting.schemes import Tradimo
    from bokeh.io import show, save, output_file

    cerebro.run(optreturn=False, tradehistory=True)

    fnames = "bt_bokeh_plot.html"
    b = Bokeh(style='bar', tabs='multi', filename=fnames)  # 黑底,多页

    # b=Bokeh(style='bar',scheme=Tradimo()) # 传统白底,单页
    # b=Bokeh(style='bar',tabs='multi',scheme=Tradimo()) #传统白底,多页
    output_file(fnames, mode='cdn', title='海龟交易策略')
    cerebro.plot(b)
    return

if __name__ == '__main__':
    # 获取数据
    for stk_code in stk_pools:
        # 拉取数据
        df = pro.daily(**{
            "ts_code": stk_code,
            "trade_date": "",
            "start_date": "20180101",
            "end_date": "20211231",
            "offset": "",
            "limit": ""
        }, fields=[
            "ts_code",
            "trade_date",
            "open",
            "high",
            "low",
            "close",
            "pre_close",
            "change",
            "pct_chg",
            "vol",
            "amount"
        ])

        df = df.iloc[::-1]
        # tushare数据存入excel后,trade_date变为int类型列,需变成string后转为datatime类型
        df.trade_date = pd.to_datetime(df.trade_date.apply(str))

        data = btfeeds.PandasData(
            dataname=df,
            fromdate=datetime.datetime(2018, 1, 1),
            todate=datetime.datetime(2021, 12, 31),
            timeframe=bt.TimeFrame.Days,
            datetime='trade_date',
            open='open',
            high='high',
            low='low',
            close='close',
            volume='vol',
            openinterest=-1)
        # 在Cerebro中添加股票数据
        cerebro.adddata(data, name=str(stk_code))

        # 设置启动资金
    cerebro.broker.setcash(100000.0)
    # 设置佣金为零
    cerebro.broker.setcommission(commission=0.001)
    idx = cerebro.addstrategy(SmaCross, poneplot=False)  # 添加策略

    cerebro.addsizer_byidx(idx, maxRiskSizer)
    cerebro.addanalyzer(bt.analyzers.SharpeRatio)

    cerebro.addobserver(bt.obs.Broker)  # removed below with stdstats=False
    cerebro.addobserver(bt.obs.Trades)  # removed below with stdstats=False

    cerebro.broker.set_coc(True)
    cerebro.addanalyzer(bt.analyzers.PyFolio, _name='pyfolio')
    cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='SharpeRatio')
    cerebro.addanalyzer(bt.analyzers.DrawDown, _name='DW')
    cerebro.addanalyzer(bt.analyzers.AnnualReturn, _name='AnnualReturn')
    cerebro.addanalyzer(bt.analyzers.Returns, _name='Returns')
    cerebro.addanalyzer(bt.analyzers.SQN, _name='SQN')
    cerebro.addanalyzer(bt.analyzers.PyFolio, _name='pyfolio')

    # 添加观测器observers
    cerebro.addobserver(bt.observers.Broker)
    cerebro.addobserver(bt.observers.Trades)
    cerebro.addobserver(bt.observers.BuySell)
    cerebro.addobserver(bt.observers.DrawDown)
    cerebro.addobserver(bt.observers.TimeReturn)
    cerebro.addobserver(bt.observers.Value)
    print('初始资金: %.2f' % cerebro.broker.getvalue())
    bokeh_cerebro_plot()
    quantstats_cerebro_plot()
    print('最终资金: %.2f' % cerebro.broker.getvalue())

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值