python tushare backtrader股票回测双均线策略

前言:
在前面学了点机器学习知识后,发现自己还没有一个回测框架,找了短时间学习资料,还是决定使用backtrader,至于聚宽优米那些平台感觉使用起来好像没那么自由,还是先学习下backtrader,学完后再把自己学到的知识理顺下,然后再整理个符合自己使用的框架来,东学西学,学得越多就越乱,得重新审视下自己的需求。以下是我学习backtrader的一些笔记,主要是直接拿tushaer的数据来用,就不用先本地CSV数据化了,方便快捷,代码如下:

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)
import datetime
import pandas as pd
import backtrader as bt
import tushare as ts
import numpy as np

# 创建策略类
class TestStrategy(bt.Strategy):
    # 设置简单均线周期,以备后面调用
    params = (
        ('maperiod21', 21),
        ('maperiod55', 55)
    )

    def log(self, txt, dt=None):
        # 日记记录输出
        dt = dt or self.datas[0].datetime.date(0)
        print('%s, %s' % (dt.isoformat(), txt))

    def __init__(self):
        # 初始化数据参数
        # 设置当前收盘价为dataclose
        self.dataclose = self.datas[0].close

        self.order = None
        self.buyprice = None
        self.buycomm = None

        # 添加简单均线
        self.sma21 = bt.indicators.SimpleMovingAverage(
            self.datas[0], period=self.params.maperiod21)
        self.sma55 = bt.indicators.SimpleMovingAverage(
            self.datas[0], period=self.params.maperiod55)

    def notify_order(self, order):
        if order.status in [order.Submitted, order.Accepted]:
            # 如果有订单提交或者已经接受的订单,返回退出
            return
        # 主要是检查有没有成交的订单,如果有则日志记录输出价格,金额,手续费。注意,如果资金不足是不会成交订单的
        if order.status in [order.Completed]:
            if order.isbuy():
                self.log(
                    'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                    (order.executed.price,
                     order.executed.value,
                     order.executed.comm))

                self.buyprice = order.executed.price
                self.buycomm = order.executed.comm
            else:  # Sell
                self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                         (order.executed.price,
                          order.executed.value,
                          order.executed.comm))
            # len(self)是指获取截至当前数据一共有多少根bar
            # 以下代码就是指当交易发生时立刻记录下了当天有多少根bar
            # 如果要表示当成交后过了5天卖,则可以这样写 if len(self) >= (self.bar_executed + 5):
            self.bar_executed = len(self)

        elif order.status in [order.Canceled, order.Margin, order.Rejected]:
            self.log('Order Canceled/Margin/Rejected')

        self.order = None

    def notify_trade(self, trade):
        if not trade.isclosed:  # 如果交易还没有关闭,则退出不输出显示盈利跟手续费
            return
        self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' %
                 (trade.pnl, trade.pnlcomm))

    def next(self):
        # 输出显示收盘价
        self.log('Close, %.2f' % self.dataclose[0])

        # 检查是否有订单发送当中,如果有则不再发送第二个订单
        if self.order:
            return

        # 检查是否已经有仓位
        if not self.position:
            # 如果没有则可以执行一下策略了
            if self.sma21[0] > self.sma55[0]:
                # 记录输出买入价格
                self.log('BUY CREATE, %.2f' % self.dataclose[0])
                # 跟踪已经创建好的订单避免重复第二次交易
                self.order = self.buy()

        else:
            if self.sma21[0] < self.sma55[0]:
                self.log('SELL CREATE, %.2f' % self.dataclose[0])
                self.order = self.sell()


if __name__ == '__main__':
    # 创建策略容器
    cerebro = bt.Cerebro()
    # 添加自定义的策略TestStrategy
    cerebro.addstrategy(TestStrategy)

    pro = ts.pro_api('要到tushare官网注册个账户然后将token复制到这里,可以的话请帮个忙用文章末我分享的链接注册,谢谢')
    stock_code = '000001.SZ'
    df = pro.daily(ts_code=stock_code, start_date='20200101', end_date='20200828')
    df['trade_date'] = pd.to_datetime(df['trade_date'])
    # df = df.drop(['change', 'pre_close', 'pct_chg', 'amount'], axis=1)
    df = df.rename(columns={
    
    'vol': 'volume'})
    df.set_index('trade_date', inplace=True)  # 设置索引覆盖原来的数据
    df = df.sort_index(ascending=True)  # 将时间顺序升序,符合时间序列

    dataframe = df
    dataframe['openinterest'] = 0
    data = bt.feeds.PandasData(dataname=dataframe,
                               fromdate=datetime.datetime(2020, 1, 1),
                               todate=datetime.datetime(2020, 8, 20)
                               )
    # 添加数据
    cerebro.adddata(data)
    # 设置资金
    cerebro.broker.setcash(10000.0)
    # 设置每笔交易交易的股票数量
    cerebro.addsizer(bt.sizers.FixedSize, stake=100)
    # 设置手续费
    cerebro.broker.setcommission(commission=0.01)
    # 输出初始资金
    print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
    # 运行策略
    cerebro.run()
    # 输出结果
    print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
    cerebro.plot()

tushare注册链接:link

猜你喜欢

转载自blog.csdn.net/Wilburzzz/article/details/108337972
今日推荐