import pandas as pd import datetime
#日度行情数据集 daily_price = pd.read_csv("C:/Users/10712/Desktop/learn_backtrader-main/data/daily_price.csv", parse_dates = [‘datetime‘]) #parse_dates:将某一列设置为时间索引 #daily_price.head()
sec_code:代码 open:开盘价 high:最高价 low:最低价 close:收盘价 volume:交易量 openinterest:未平仓量
除sec_code外其他是必须导入到datafeeds中的字段
#月末调仓成分股数据集 trade_info = pd.read_csv("C:/Users/10712/Desktop/learn_backtrader-main/data/trade_info.csv", parse_dates = [‘trade_date‘]) trade_info.head()
sec_code:持仓成分股代码 weight:持仓权重
导入大脑!
import backtrader as bt #实例化 cerebro = bt.Cerebro()
# 打印初始资金 print(‘Starting Portfolio Value: %.2f‘ % cerebro.broker.getvalue()) # 启动回测(这是一个空回测,所以买入卖出肯定一个价格啦!) cerebro.run() # 打印回测完成后的资金 print(‘Final Portfolio Value: %.2f‘ % cerebro.broker.getvalue())
#导入多只股票的历史行情数据 #用DataFeeds的PandasData()导入,必须以交易日datetime为index for stock in daily_price[‘sec_code‘].unique():#unique():去除重复值并让元素从大到小排列,返回一个列表 data = pd.DataFrame(index = daily_price.index.unique())#获取回溯期内所有交易日,index是建立索引 df = daily_price.query(f"sec_code==‘{stock}‘")[[‘open‘,‘high‘,‘low‘,‘close‘,‘volume‘,‘openinterest‘]] #query():查询 data_ = pd.merge(data, df, left_index=True, right_index=True, how=‘left‘)#合并索引和数据 #缺失值处理(会有些交易日为空) data_.loc[:,[‘volume‘,‘openinterest‘]] = data_.loc[:,[‘volume‘,‘openinterest‘]].fillna(0) data_.loc[:,[‘open‘,‘high‘,‘low‘,‘close‘]] = data_.loc[:,[‘open‘,‘high‘,‘low‘,‘close‘]].fillna(method=‘pad‘)#method=‘pad‘:用之前的数据填充 data_.loc[:,[‘open‘,‘high‘,‘low‘,‘close‘]] = data_.loc[:,[‘open‘,‘high‘,‘low‘,‘close‘]].fillna(0) #导入数据 datafeed = bt.feeds.PandasData(dataname=data_, fromdate=datetime.datetime(2019,1,2), todate=datetime.datetime(2021,1,28)) cerebro.adddata(datafeed, name=stock) # 通过 name 实现数据集与股票的一一对应 print(f"{stock} Done !") #导入数据时的注意点在笔记详细讲
导入数据时的注意点:
1. 各个股票交易日总数量可能不统一,所以要以回测区间内所有交易日为基础,对每只股票缺失的交易日进行补齐;
2. 行情数据缺失:在补齐交易日过程中,会使得补充的交易日缺失行情数据,需对缺失数据进行填充;
3.实现行情数据和股票的一一对应:通过设置 adddata() 方法中 name 参数,来实现数据集与股票的一 一对应关系。
#配置回测条件 #初始资金 cerebro.broker.setcash(100000000.0) #佣金,0.03% cerebro.broker.setcommission(commission=0.0003) #滑点,0.0001:挂单价格和实际成交价格之间的差(笔记中详细讲) cerebro.broker.set_slippage_perc(perc=0.0001)
#提前配置要返回的回测结果 cerebro.addanalyzer(bt.analyzers.TimeReturn, _name=‘pnl‘)#返回收益率时序数据 cerebro.addanalyzer(bt.analyzers.AnnualReturn, _name=‘_AnnualReturn‘)#年化收益率 cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name=‘_SarpeRatio‘)#夏普比率 cerebro.addanalyzer(bt.analyzers.DrawDown, _name=‘_DrawDown‘)#回撤
交易策略因为是最重要且*的一块,所以拎出来放到笔记里面
#直接进入提取回测结果流程 result = cerebro.run() #提取result结果 strat = result[0] #返回日度收益率序列 daily_return = pd.Series(strat.analyzers.pnl.get_analysis()) #打印评价指标 print("AnnualReturn",strat.strat.analyzers._AnnualReturn.get_analysis()) print("SharpeRatio",strat.strat.analyzers._SharpeRatio.get_analysis()) print("DrawDown",strat.strat.analyzers._DrawDown.get_analysis())