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",
adjust='qfq'
)
print(stock_zh_a_hist_df[: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(
dataname=dataframe,
datetime=0,
open=1,
high=3,
low=4,
close=2,
volume=5,
openinterest=-1,
fromdate=begin_date,
todate=end_date
)
return feeds
## PandasData拓展line
可以看到原始的 bt.feeds.PandasData使用的line为:datetime、open、high、low、close、volume
希望将行情数据中的 换手率 加入行情数据需要如下操作:
from backtrader.feeds import PandasData
class PandasData_Change(PandasData):
'''增加 换手率线的 数据源类'''
lines = ('change', )
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,
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,
fromdate=begin_date,
todate=end_date,
change=10-1
)
return feeds
|