量化交易回测框架Backtrader初识

Backtrader知识储备

框架的概念还挺多:Cerebro,Data Feeds,Strategy,Indicators,Orders,Broker,Analyzers,Observers,Sizers。逐个来看看大概的功能和角色。对学习框架好处多多。

  • Cerebro :翻译过来是大脑的意思。可以说是backtrader的基石,有点类似cpu的感觉,处理收集所有数据、运行策略,执行回溯测试,操作交易,绘图等等。
  • Data Feeds:交易数据,这个没什么好说的,都是各种金融平台的交易数据,开盘价,收盘价啥的。
  • Strategy:策略,根据定义的策略会处理或者说遍历数据,来判定具体的买卖等动作。
  • Indicators:指标,用股市打比方,比如相对强弱指标(RSI)、随机指标(KD)、趋向指标(DMI)、平滑异同平均线(MACD)、能量潮(OBV)等等这些都已经实现好的,不用咱们自己实现,拿来使用即可。当然也支持自定义指标。
  • Orders:下单员,可以理解具体交易订单执行单元,触发了对应的策略,发出订单信号,具体交给orders处理订单操作。
  • Broker:经纪人,可以理解为交易所,收取手续费,管理账户资金。
  • Analyzers:看样子辅助分析执行的流程,协助改进和修正问题的角色(暂且这么理解)
  • Observers:看样子辅助分析执行的流程,协助改进和修正问题的角色(暂且这么理解)
  • Sizers:这个比较好理解,不同的交易所,交易的单位不一样,比如,1手是100股,交易都是以100为单位。通过这个来设置交易的基本单位。

看了下官方给出的:Quickstart Guide。由于官网举得例子都是国外的数据。要是想掌握这个必须把源头先搞定,就是提供交易数据(Data Feeds ),还好官方支持按照规范自己实现自己的数据。所以还是从这里开始研究。

第一弹:Data Feeds(交易数据)

背景

因为数据的获取,我使用的是tushare。tushare返回的是pandas的dataframe格式。所以我就主攻pandas-datafeed这块。

原理

参考官方文档pandas-datafeed:

class PandasData(feed.DataBase):
    '''
    The ``dataname`` parameter inherited from ``feed.DataBase`` is the pandas
    DataFrame
    '''

    params = (
        # Possible values for datetime (must always be present)
        #  None : datetime is the "index" in the Pandas Dataframe
        #  -1 : autodetect position or case-wise equal name
        #  >= 0 : numeric index to the colum in the pandas dataframe
        #  string : column name (as index) in the pandas dataframe
        ('datetime', None),

        # Possible values below:
        #  None : column not present
        #  -1 : autodetect position or case-wise equal name
        #  >= 0 : numeric index to the colum in the pandas dataframe
        #  string : column name (as index) in the pandas dataframe
        ('open', -1),
        ('high', -1),
        ('low', -1),
        ('close', -1),
        ('volume', -1),
        ('openinterest', -1),
    )

PandasData类继承feed.DataBase类,初始化数据需要7列数据 分别为:datetime、open、high、low、close、volume、openinterest,其中datetime是索引列。经过实践送过去的数据按照这个顺序排列,不包含header部分即可。

实践(Data Feeds 使用pandas数据)

使用的是601668 中国建筑的股票数据,csv文件我放到github上了。可以自行去下载,按照官方文档的源码改了下数据元,正常执行。

# -*- coding: utf-8 -*-
"""
搞定自定义的数据送给backtrader
"""
#############################################################
#import
#############################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)
import os,sys
import pandas as pd
import backtrader as bt
#############################################################
#global const values
#############################################################
#############################################################
#static function
#############################################################
#############################################################
#class
#############################################################
#############################################################
#global values
#############################################################
#############################################################
#global function
#############################################################
def G_get_dataframe():
     # Get a pandas dataframe
    datapath = './data/stockinfo.csv'
    tmpdatapath = './data/stockinfo_tmp.csv'
    print('-----------------------read csv---------------------------')
    dataframe = pd.read_csv(datapath,
                                skiprows=0,
                                header=0,
                                parse_dates=True,
                                index_col=0)
    print(dataframe)
    print('--------------------------------------------------')
    print('-----------------------change time------------------------')
    dataframe.trade_date =  pd.to_datetime(dataframe.trade_date, format="%Y%m%d")
    print(dataframe)
    print('--------------------------------------------------')
    print('-----------------------add openinterest-------------------')
    dataframe['openinterest'] = '0'
    print(dataframe)
    print('--------------------------------------------------')
    print('-----------------------make feedsdf-----------------------')
    feedsdf = dataframe[['trade_date', 'open', 'high', 'low', 'close', 'vol', 'openinterest']]
    print(feedsdf)
    print('--------------------------------------------------')
    print('-----------------------change columns---------------------')
    feedsdf.columns =['datetime', 'open', 'high', 'low', 'close', 'volume', 'openinterest']
    print(feedsdf)
    print('--------------------------------------------------')
    print('-----------------------change index-----------------------')
    feedsdf.set_index(keys='datetime', inplace =True)
    print(feedsdf)
    print('--------------------------------------------------')
    feedsdf.iloc[::-1].to_csv(tmpdatapath)
    feedsdf = pd.read_csv(tmpdatapath, skiprows=0, header=0, parse_dates=True, index_col=0)
    if os.path.isfile(tmpdatapath):
        os.remove(tmpdatapath)
        print(tmpdatapath+" removed!")
    return feedsdf
########################################################################
#main
########################################################################
if __name__ == '__main__':
    # Create a cerebro entity
    cerebro = bt.Cerebro(stdstats=False)

    # Add a strategy
    cerebro.addstrategy(bt.Strategy)

    # Get a pandas dataframe
    feedsdf = G_get_dataframe()
    
    # Pass it to the backtrader datafeed and add it to the cerebro
    data = bt.feeds.PandasData(dataname=feedsdf)
    print(data)

    cerebro.adddata(data)

    # Run over everything
    cerebro.run()

    # Plot the result
    cerebro.plot(style='bar')

输出图形

Figure_0.png

源码:

qtbt

你可能感兴趣的:(量化交易回测框架Backtrader初识)