Backtrader(六) - 关于datafeed

PandasData

将pandas的dataframe,对象加载到 bt.feeds.PandasData。生成回测的行情数据对象。
范例:
数据来源 akshare

import akshare as ak
# 获取历史行情数据
stock_zh_a_hist_df = ak.stock_zh_a_hist(
    symbol=g_stock_code,  # 股票代码
    period="daily",  # {'daily', 'weekly', 'monthly'}
    adjust='qfq'  # qfq:前复权;hfq:后复权
)

print(stock_zh_a_hist_df[:5])  # 查看前5行数据

注意:这里是一份dataframe数据,换行后分开两份展示

     日期     开盘     收盘     最高   最低     成交量    成交额      振幅  \
0 2021-08-18  14.50  18.00  19.88  14.50  780346  1.265741e+09  130.27   
1 2021-08-19  17.00  15.42  17.48  15.36  629396  1.026323e+09   11.78   
2 2021-08-20  15.16  14.81  16.48  14.71  486654  7.591273e+08   11.48   
3 2021-08-23  14.20  15.62  16.21  13.98  445712  6.849244e+08   15.06   
4 2021-08-24  15.27  15.51  16.20  14.82  445999  6.878077e+08    8.83
  涨跌幅    涨跌额    换手率  
0  335.84  13.87  88.95  
1  -14.33  -2.58  71.74  
2   -3.96  -0.61  55.47  
3    5.47   0.81  50.81  
4   -0.70  -0.11  50.84

下面定义一个函数,接收dataframe对象,生成一个行情数据对象

def get_feeds(dataframe):
    dataframe['日期'] = dataframe['日期'].apply(str)
    dataframe['日期'] = pd.to_datetime(dataframe['日期'])
    date_list = dataframe['日期'].to_list()

    begin_date = datetime.strptime(str(date_list[0]), "%Y-%m-%d %H:%M:%S")  # 数据的起始日期
    end_date = datetime.strptime(str(date_list[-1]), "%Y-%m-%d %H:%M:%S")  # 数据的起始日期

    feeds = bt.feeds.PandasData(
    	name='数据名称', # 多股回测时用户区分数据对象
        dataname=dataframe,
        datetime=0,  # 日期行所在列
        open=1,  # 开盘价所在列
        high=3,  # 最高价所在列
        low=4,  # 最低价所在列
        close=2,  # 收盘价价所在列
        volume=5,  # 成交量所在列
        openinterest=-1,  # 无未平仓量列.(openinterest是期货交易使用的)
        fromdate=begin_date,  # 起始日
        todate=end_date
    )
    return feeds

## PandasData拓展line

可以看到原始的 bt.feeds.PandasData使用的line为:datetime、open、high、low、close、volume

希望将行情数据中的 换手率 加入行情数据需要如下操作:

# 自定义数据类,继承PandasData
from backtrader.feeds import PandasData
class PandasData_Change(PandasData):
    '''增加 换手率线的 数据源类'''
    # 增加pe线
    lines = ('change', )
    # 默认第8列
    params = (
        ('change', 8),
    )

将数据注入自定义的数据类,我们修改了一下生成行情数据对象的方法,增加了 change 参数,并定义为第10列数据:

def get_feeds(dataframe):

    dataframe['日期'] = dataframe['日期'].apply(str)
    dataframe['日期'] = pd.to_datetime(dataframe['日期'])
    date_list = dataframe['日期'].to_list()

    begin_date = datetime.strptime(str(date_list[0]), "%Y-%m-%d %H:%M:%S")  # 数据的起始日期
    end_date = datetime.strptime(str(date_list[-1]), "%Y-%m-%d %H:%M:%S")  # 数据的起始日期

    feeds = PandasData_Change(
        dataname=dataframe,
        datetime=0,  # 日期行所在列
        open=1,  # 开盘价所在列
        high=3,  # 最高价所在列
        low=4,  # 最低价所在列
        close=2,  # 收盘价价所在列
        volume=5,  # 成交量所在列
        openinterest=-1,  # 无未平仓量列.(openinterest是期货交易使用的)
        fromdate=begin_date,  # 起始日
        todate=end_date,
        change=10  # 新定义 换手率线 的索引
    )
    return feeds

运行策略查看 新的line可以像这样获取

class SmaCross(bt.Strategy):

    def __init__(self):

        '''获取 换手率线'''
        change_line = self.data.change
        lg.info(
            change_line
        )

    def next(self):
        pass


cerebro = bt.Cerebro()
cerebro.adddata(feed)
cerebro.addstrategy(SmaCross)
cerebro.broker.setcash(10000)
cerebro.run()

使用pandasDirectData

后期新版增加,作用是提高效率
使用pandasDirectData 需要遵循一下规则:
1、dataframe的日期时间列要设为索引列
2、dataframe里不能有字符串列,如:股票代号
3、bt.PandasDirectData(…)时,不能设置datatime列

继续使用上面的行情数据,修改生成行情数据对象的方法:
1、重新索引 dataframe.set_index()
2、删除字符串列 dataframe.drop() ,这里没有

def get_feeds(dataframe):
    dataframe['日期'] = dataframe['日期'].apply(str)
    dataframe['日期'] = pd.to_datetime(dataframe['日期'])
    date_list = dataframe['日期'].to_list()
		# 增加重新索引
    dataframe = dataframe.set_index(keys=['日期'], inplace=True)

    begin_date = datetime.strptime(str(date_list[0]), "%Y-%m-%d %H:%M:%S")  # 数据的起始日期
    end_date = datetime.strptime(str(date_list[-1]), "%Y-%m-%d %H:%M:%S")  # 数据的起始日期

    feeds = PandasDirectData(
        dataname=dataframe,
        open=1-1,  # 开盘价所在列
        high=3-1,  # 最高价所在列
        low=4-1,  # 最低价所在列
        close=2-1,  # 收盘价价所在列
        volume=5-1,  # 成交量所在列
        openinterest=-1,  # 无未平仓量列.(openinterest是期货交易使用的)
        fromdate=begin_date,  # 起始日
        todate=end_date,
        change=10-1  # 新定义 换手率线 的索引
    )
    return feeds
  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
backtrader是一个用于开发交易策略的Python框架,它提供了许多功能强大的工具和类来帮助交易者开发和测试交易策略。其中,backtraderdatafeed是用于提供数据的类,它可以从各种来源获取数据,并将其转换为backtrader所需的格式。 下面是backtraderdatafeed代码详解: ```python from datetime import datetime import backtrader as bt class MyDataFeed(bt.feeds.GenericCSVData): params = ( ('dtformat', '%Y-%m-%d'), # 数据的时间格式 ('datetime', 0), # 数据中时间所在的列数 ('open', 1), # 开盘价所在的列数 ('high', 2), # 最高价所在的列数 ('low', 3), # 最低价所在的列数 ('close', 4), # 收盘价所在的列数 ('volume', 5), # 成交量所在的列数 ('openinterest', -1), # 持仓量所在的列数,默认为-1,表示没有持仓量数据 ) ``` 代码中定义了一个名为MyDataFeed的类,它继承自backtrader的GenericCSVData类,这个类是backtrader内置的用于读取CSV格式数据的类,如果我们需要读取其他格式的数据,可以继承GenericCSVData类并进行修改。 在params参数中,我们定义了许多数据的属性,包括时间格式、开盘价、最高价、最低价、收盘价、成交量和持仓量等。这些属性需要根据数据文件的格式进行设置,如果数据文件与上述定义的属性不同,则需要进行修改。 接下来,我们需要实例化这个类,并将数据文件的路径传递给它: ```python data = MyDataFeed(dataname='data.csv') ``` 这行代码中,我们创建了一个名为data的对象,并将数据文件的路径(data.csv)传递给它。这个对象现在可以被用于backtrader的策略中,数据将会按照我们定义的格式进行读取和处理。 总之,backtraderdatafeed是一个非常强大的类,它可以从各种来源获取数据,并将其转换为backtrader所需的格式。我们只需要根据数据文件的格式进行一些简单的设置,就可以轻松地获取数据并进行回测分析。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值