通过Tushare和backtrader实现量化投资回测

一.Tushare介绍

Tushare是一个免费开源的python财经数据接口包。主要实现对股票数据等从数据采集、清晰加工和数据存储的过程。考虑到Python pandas包在金融量化分析中体现出的优势,Tushare返回的绝大部分的数据格式都是pandas DataFrame类型,非常便于用pandas/NumPy/Matplotlib进行数据分析和可视化。当然也可以通过Tushare的数据存储功能将数据保存到本地后用excel或关系数据库分析。

二.安装Tushare

方式1:pip install tushare
方式2:访问https://pypi.python.org/pypi/Tushare/下载安装
在这里插入图片描述
可以通过https://tushare.pro/register?reg=418443 注册,在个人中心中获取token值
在这里插入图片描述

token=‘你复制下来的token’
ts.set_token(token)
pro=ts.pro_api()

三.backtrader介绍和安装

Backtrader的特点,就是两点:

1、易于使用;

2、参见第1条。

那么如何使用Backtrader呢?比把大象装进冰箱复杂点,一共4步:

创建一个Cerebro引擎:

1、加入一个Strategy。

2、加载数据。

3、执行:cerebro.run()。

4、对执行结果可视化。

就是这么简单!

这么简单如何执行那么多复杂的量化策略,关键就是Backtrader作为一个平台,具有极高的可配置性,也就是可以根据需要进行不同的配置,完成不同的量化策略回测,后续将进行详细描述。

安装Backtrader

pip install backtrader

四.编写代码

本次使用pycharm软件作为python开发环境。

1、初始化tushare,获取指定股票代码的股票历史数据。

token = '你复制下来的token'
ts.set_token(token)
pro = ts.pro_api(timeout=60)
# 指定股票代码
ts_code = '000400.SZ'
code = '000400'
start_date = '20200101'
# 获取数据
def get_data(start):
    df = ts.pro_bar(ts_code=ts_code, adj='qfq', start_date=start)
    df = df.iloc[::-1]
    df.index = pd.to_datetime(df.trade_date)
    df['openinterest'] = 0
    df = df[['open', 'high', 'low', 'close', 'vol', 'openinterest']]
    df = df.rename(columns={'vol': 'volume'})
    return df

2、加载数据

start_time = '2020-01-01'
accept_date = getdate(1)  # 查找这个日期是买入卖出点的股票
start = datetime.datetime.strptime(start_time, "%Y-%m-%d")
end = datetime.datetime.strptime(accept_date, "%Y-%m-%d")
buy_count = 0   # 买入次数
sell_count = 0   # 卖出次数
k_line_data = get_data(start.date().strftime("%Y%M%D"))
print(k_line_data)
k_line_data.to_csv("csvfile\\" + ts_code + ".csv")
data = bt.feeds.PandasData(dataname=k_line_data, fromdate=start, todate=end)

3、加载backtrader引擎,初始化投资金额

# 加载backtrader引擎
back_trader = bt.Cerebro()
# 将数据传入
back_trader.adddata(data)
# 策略加进来
back_trader.addsizer(bt.sizers.FixedSize, stake=2000)
# 设置以收盘价成交,作弊模式
back_trader.broker.set_coc(True)
# 账号资金初始化
startCash = 100000
back_trader.broker.set_cash(startCash)
# 设置手续费
back_trader.broker.setcommission(commission=0.001)

4、增加策略

# 布林线规则:跌破下轨,买入;超过上轨,卖出
back_trader.addstrategy(boll_strategy)

5、布林线规则策略的具体实现

# 定义策略
class boll_strategy(bt.Strategy):
    def log(self, txt, dt=None):
        dt = dt or self.datas[0].datetime.date(0)
        print('%s,%s' % (dt.isoformat(), txt))

    def __init__(self):
        # 指定价格序列
        self.dataclose = self.datas[0].close

        #交易订单状态初始化
        self.order = None

        #计算布林线
        ##使用自带的indicators中自带的函数计算出支撑线和压力线,period设置周期,默认是20
        self.lines.top = bt.indicators.BollingerBands(self.datas[0], period=20).top
        self.lines.bot = bt.indicators.BollingerBands(self.datas[0], period=20).bot

    def next(self):
        # 检查订单状态
        if self.order:
            print("等待成交")
            return

        # 检查持仓
        if not self.position:
            # 没有持仓,买入开仓
            if self.dataclose <= self.lines.bot[0]:
                print("================")
                print("收盘价跌破lower线,执行买入")
                self.order = self.buy()
        else:
            # 手里有持仓,判断卖平
            if self.dataclose >= self.lines.top[0]:
                print("======================")
                print("收盘价超过upper线,执行卖出")
                self.order = self.sell()

    def notify(self, order):

        if order.status in [order.Submitted, order.Accepted]:
            if order.status in [order.Submitted]:
                self.log("提交订单......")
            if order.status in [order.Accepted]:
                self.log("接受订单......")
            return

        # Check if an order has been completed
        # Attention: broker could reject order if not enougth cash
        if order.status in [order.Completed, order.Canceled, order.Margin]:
            if order.isbuy():
                self.log('执行买入, %.2f' % order.executed.price)
                gloVar.buy_count = gloVar.buy_count + 1
            elif order.issell():
                self.log('执行卖出, %.2f' % order.executed.price)
                gloVar.sell_count = gloVar.sell_count + 1
            self.bar_executed = len(self)

        self.log("订单完成......")
        print("======================")
        # Write down: no pending order
        self.order = None

6、输出回测结果并打印图形

# 输出初始化数据
d1 = start.date().strftime("%Y-%m-%d")
d2 = end.date().strftime("%Y-%m-%d")
print(f'初始化资金:{startCash},回测时间:{d1}:{d2}')
# 开启回测
result = back_trader.run()

# Print out the final result
print('最终资金: %.2f' % back_trader.broker.getvalue())
profit_ratio = (int(back_trader.broker.getvalue()) - startCash) / startCash * 100
print('投资收益率: %.2f%%' % profit_ratio)
print('买入次数:%s ;卖出次数:%s' % (gloVar.buy_count, gloVar.sell_count))
print("股票代码:%s,%s净资产收益率:%s%%" % (ts_code, profit_time, roe))
# Plot the result
back_trader.plot(style='candlestick')

五.运行结果

从下面的执行结果,可以清晰看到本次投资股票的投资收益率和交易次数:

最终资金: 106992.30
投资收益率: 6.99%
买入次数:6 ;卖出次数:6
股票代码:000400.SZ,净资产收益率:%

输出交易图形:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值