Backtrader量化&回测2——在策略中读取Pandas数据,添加更多自定义数据列到策略中

Backtrader量化&回测2——在策略中读取Pandas数据,添加更多自定义数据列到策略中,第1张

文章目录
  • Backtrader读取Pandas数据集基本
  • 在策略中获取数据信息
  • 自定义数据集,拓展更多列数据

Backtrader读取数据 官方文档:https://www.backtrader.com/docu/dataautoref/

Backtrader读取Pandas数据集基本

使用Backtrader的内置类backtrader.feeds.PandasData读取dataframe数据后,会按照列名称,将已有的数据列名映射到backtrader的PandasData类中,默认只会包含以下数据:

* close
* low
* high
* open
* volume
* openinterest
* datetime

如果想要获取更多数据,需要手动添加,详情请参考自定义数据集部分

在策略中获取数据信息
import backtrader
import efinance
import pandas as pd
from datetime import datetime


def get_k_data(stock_code, begin: datetime, end: datetime) -> pd.DataFrame:
    """
    根据efinance工具包获取股票数据
    :param stock_code:股票代码
    :param begin: 开始日期
    :param end: 结束日期
    :return:
    """
    # stock_code = '600519'  # 股票代码,茅台
    k_dataframe: pd.DataFrame = efinance.stock.get_quote_history(
        stock_code, beg=begin.strftime("%Y%m%d"), end=end.strftime("%Y%m%d"))
    k_dataframe = k_dataframe.iloc[:, :9]
    k_dataframe.columns = ['name', 'code', 'date', 'open', 'close', 'high', 'low', 'volume', 'turnover']
    k_dataframe.index = pd.to_datetime(k_dataframe.date)
    k_dataframe.drop(['name', 'code', "date"], axis=1, inplace=True)
    return k_dataframe


class MyStrategy1(backtrader.Strategy):  # 策略
    def __init__(self):
        # 初始化交易指令、买卖价格和手续费
        self.close_price = self.datas[0].close  # 这里加一个数据引用,方便后续 *** 作
        this_data = self.getdatabyname("stock_600519")  # 获取传入的 name = stock_600519 的数据
        print("全部列名:", this_data.getlinealiases())  # 全部的列名称
        print("总交易日:", self.datas[0].buflen())  # 数据集中一共有多少行

    def next(self):  # 框架执行过程中会不断循环next(),过一个K线,执行一次next()
        print('==========================')
        print("今日{}, 是第{}个交易日 , 收盘价:{}".format(self.datetime.date(), len(self.datas[0]), self.datas[0].close[0]))
        print("前天、昨天、今天的收盘价:", list(self.datas[0].close.get(ago=0, size=3)))  # 使用 get() 向前获取数据
        if len(self.datas[0]) <= self.datas[0].buflen() - 2:
            print("明天、后天的收盘价:", self.datas[0].close[1], self.datas[0].close[2])


if __name__ == '__main__':
    # 获取数据
    start_time = datetime(2015, 1, 1)
    end_time = datetime(2015, 1, 10)
    dataframe = get_k_data('600519', begin=start_time, end=end_time)
    # =============== 为系统注入数据 =================
    # 加载数据
    data = backtrader.feeds.PandasData(dataname=dataframe, fromdate=start_time, todate=end_time)
    # 初始化cerebro回测系统
    cerebral_system = backtrader.Cerebro()  # Cerebro引擎在后台创建了broker(经纪人)实例,系统默认每个broker的初始资金量为10000
    # 将数据传入回测系统
    cerebral_system.adddata(data, name="stock_600519")  # 导入数据,在策略中使用 self.datas 来获取数据源
    # 将交易策略加载到回测系统中
    cerebral_system.addstrategy(MyStrategy1)
    # =============== 系统设置 ==================
    # 运行回测系统
    cerebral_system.run()

可以看到打印的结果:

全部列名: ('close', 'low', 'high', 'open', 'volume', 'openinterest', 'datetime')
总交易日: 5
==========================
今日2015-01-05, 是第1个交易日 , 收盘价:105.32
前天、昨天、今天的收盘价: []
明天、后天的收盘价: 101.06 96.61
==========================
今日2015-01-06, 是第2个交易日 , 收盘价:101.06
前天、昨天、今天的收盘价: []
明天、后天的收盘价: 96.61 95.54
==========================
今日2015-01-07, 是第3个交易日 , 收盘价:96.61
前天、昨天、今天的收盘价: [105.32, 101.06, 96.61]
明天、后天的收盘价: 95.54 94.22
==========================
今日2015-01-08, 是第4个交易日 , 收盘价:95.54
前天、昨天、今天的收盘价: [101.06, 96.61, 95.54]
==========================
今日2015-01-09, 是第5个交易日 , 收盘价:94.22
前天、昨天、今天的收盘价: [96.61, 95.54, 94.22]
自定义数据集,拓展更多列数据

如果看原始的数据,可以发现原有的数据集列名称是:‘open’, ‘close’, ‘high’, ‘low’, ‘volume’, ‘turnover’

但是在策略中列名变成了:(‘close’, ‘low’, ‘high’, ‘open’, ‘volume’, ‘openinterest’, ‘datetime’)

这是因为backtrader对原有的数据做了一层封装,查看源码中的class PandasData(feed.DataBase):可以看到,PandasData类接受的输入是:(‘nocase’, ‘close’, ‘low’, ‘high’, ‘open’, ‘volume’, ‘openinterest’, ‘datetime’),如果要拓展,需要继承自这个类然后重写params这个参数:

添加自定义列只需要两步:

  1. 修改lines
  2. 修改params
import backtrader
import efinance
import pandas as pd
from datetime import datetime


def get_k_data(stock_code, begin: datetime, end: datetime) -> pd.DataFrame:
    """
    根据efinance工具包获取股票数据
    :param stock_code:股票代码
    :param begin: 开始日期
    :param end: 结束日期
    :return:
    """
    # stock_code = '600519'  # 股票代码,茅台
    k_dataframe: pd.DataFrame = efinance.stock.get_quote_history(
        stock_code, beg=begin.strftime("%Y%m%d"), end=end.strftime("%Y%m%d"))
    k_dataframe = k_dataframe.iloc[:, :9]
    k_dataframe.columns = ['name', 'code', 'date', 'open', 'close', 'high', 'low', 'volume', 'turnover']
    k_dataframe.index = pd.to_datetime(k_dataframe.date)
    k_dataframe.drop(['name', 'code', "date"], axis=1, inplace=True)
    return k_dataframe


class PandasDataPlus(backtrader.feeds.PandasData):
    lines = ('turnover',)  # 要添加的列名
    # 设置 line 在数据源上新增的位置
    params = (
        ('turnover', -1),  # turnover对应传入数据的列名,这个-1会自动匹配backtrader的数据类与原有pandas文件的列名
        # 如果是个大于等于0的数,比如8,那么backtrader会将原始数据下标8(第9列,下标从0开始)的列认为是turnover这一列
    )


class MyStrategy1(backtrader.Strategy):  # 策略
    def __init__(self):
        # 初始化交易指令、买卖价格和手续费
        self.close_price = self.datas[0].close  # 这里加一个数据引用,方便后续 *** 作
        this_data = self.getdatabyname("stock_600519")  # 获取传入的 name = stock_600519 的数据
        print("全部列名:", this_data.getlinealiases())  # 全部的列名称

    def next(self):  # 框架执行过程中会不断循环next(),过一个K线,执行一次next()
        pass


if __name__ == '__main__':
    # 获取数据
    start_time = datetime(2015, 1, 1)
    end_time = datetime(2015, 1, 10)
    dataframe = get_k_data('600519', begin=start_time, end=end_time)
    # =============== 为系统注入数据 =================
    # 加载数据
    data = PandasDataPlus(dataname=dataframe, fromdate=start_time, todate=end_time)
    # 初始化cerebro回测系统
    cerebral_system = backtrader.Cerebro()  # Cerebro引擎在后台创建了broker(经纪人)实例,系统默认每个broker的初始资金量为10000
    # 将数据传入回测系统
    cerebral_system.adddata(data, name="stock_600519")  # 导入数据,在策略中使用 self.datas 来获取数据源
    # 将交易策略加载到回测系统中
    cerebral_system.addstrategy(MyStrategy1)
    # =============== 系统设置 ==================
    # 运行回测系统
    cerebral_system.run()

可以看到新增了turnover列的数据,在策略中就可以选择了:

全部列名: ('close', 'low', 'high', 'open', 'volume', 'openinterest', 'datetime', 'turnover')

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/870322.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存