龙空技术网

Python研报复现 | 基于阻力支撑相对强度的市场择时

Python金融量化 1164

前言:

如今各位老铁们对“回测python”大概比较讲究,我们都需要学习一些“回测python”的相关资讯。那么小编在网上收集了一些对于“回测python””的相关资讯,希望你们能喜欢,各位老铁们快快来学习一下吧!

文章转载自公众号量化小白上分记 , 作者:量化小白H

本文是对光大证券研究报告《基于阻力支撑相对强度(RSRS)的市场择时》前四种择时方法的复现。

报告认为,常用的均线系统和MACD等指标滞后性较高,阻力支撑指标RSRS领先性较好,可以以此为依据构造择时策略,具体原理见报告。(在公众号后台回复"RSRS"获取研报和代码)。

文章仅出于个人对于报告的理解,不一定正确,有问题请指出。回测结果除方法一以外,均与报告差异较大,如果有大佬作出了跟研报差不多的结果,求指导。

语言:python3.6

数据来源:tushare(免费)

回测区间:两个时间段,第一个与研报一致,2005年3月-2017年3月,通过对比来看复制是否准确,第二个为2005年初到当前,看策略现在的表现如何。

文章结构如下:

各种阻力支撑指标的构造及分析斜率策略回测标准分策略回测修正标准分策略回测右偏标准分策略回测回测结果汇总

1. 阻力支撑指标

研报一共构造了4种阻力支撑指标,指标背后的逻辑不过多分析,见研报,仅给出原理和代码实现。

当日斜率指标

当日标准分

修正标准分

右偏标准分

为了后续策略回测方便,我们构造函数getdata从tushare中取出原始价格序列,并一次性计算出所有需要用的指标,其中N为回归用的天数,M为计算标准分所用的时间长度,与研报一致,对于前三种策略,N=18,M=600,对于第四种策略,N=16,M=300。

 1def getdata(dateStart,dateEnd,N,M): 2 HS300 = ts.get_k_data('000300', index=True,start = '{}'.format(dateStart),end = '{}'.format(dateEnd)) 3 HS300=HS300[['date','high','low','open','close']] 4 5 # 斜率 6 HS300['beta'] = 0 7 HS300['R2'] = 0 8 for i in range(1,len(HS300)-1): 910 df_ne=HS300.loc[ i- N+1:i ,:]11 model = sml.ols(formula='high~low',data = df_ne)12 result=model.fit()1314 HS300.loc[i+1,'beta'] = result.params[1]15 HS300.loc[i+1,'R2'] = result.rsquared16 # 日收益率 17 HS300['ret'] = HS300.close.pct_change(1)1819 # 标准分20 HS300['beta_norm'] = (HS300['beta'] - HS300.beta.rolling(M).mean().shift(1))/HS300.beta.rolling(M).std().shift(1)21 for i in range(M):22 HS300.loc[i,'beta_norm'] = (HS300.loc[i,'beta'] - HS300.loc[:i-1,'beta'].mean())/HS300.loc[:i-1,'beta'].std() 23 HS300.loc[2,'beta_norm'] = 024 HS300['RSRS_R2'] = HS300.beta_norm*HS300.R225 HS300 = HS300.fillna(0)2627 # 右偏标准分28 HS300['beta_right'] = HS300.RSRS_R2*HS300.beta29 return(HS300)

斜率指标分布如下

与研报的对比:

斜率指标看起来是基本一致的,但其余指标统计量差异较大,见代码。

斜率250天的滚动均值

报告结果

整体趋势是一致的,只有前期不足250的部分,可能这部分的处理方法与报告有差异,所以结果有差异。

2. 斜率策略回测

策略逻辑:斜率指标超出阈值S1 = 1时买入,斜率指标超出阈值S2 = 0.8时卖出。

 1def RSRS1(HS300,S1 = 1.0,S2 = 0.8): 2 data = HS300.copy() 3 data['flag'] = 0 # 买卖标记 4 data['position'] = 0 # 持仓标记 5 position = 0 # 是否持仓,持仓:1,不持仓:0 6 for i in range(1,data.shape[0]-1): 7 8 # 开仓 9 if data.loc[i,'beta']>S1 and position ==0:10 data.loc[i,'flag'] = 111 data.loc[i+1,'position'] = 112 position = 113 # 平仓14 elif data.loc[i,'beta']<S2 and position ==1: 15 data.loc[i,'flag'] = -116 data.loc[i+1,'position'] = 0 17 position = 01819 # 保持20 else:21 data.loc[i+1,'position'] = data.loc[i,'position'] 2223 data['nav'] = (1+data.close.pct_change(1).fillna(0)*data.position).cumprod() 2425 return(data)

策略净值为10.59,交易次数45次,报告结果为10.57,41次,基本相近,并且相比于沪深300指数(黄色),有明显超额收益,且回撤较小。

但之后的策略都与报告结果差异较大,可能是指标计算上有一定差异。(之后部分策略回测结果中交易次数含0.5次,是因为买卖合计一次,最后一次开仓后未平仓。)

3. 标准分策略回测

之后三部分只给出逻辑和代码,回测结果汇总在最后。

策略逻辑:标准分大于S=0.7买入,小于-0.7卖出。

 1def RSRS2(HS300,S = 0.7): 3 data = HS300.copy() 4 data['flag'] = 0 # 买卖标记 5 data['position'] = 0 # 持仓标记 6 position = 0 # 是否持仓,持仓:1,不持仓:0 7 for i in range(1,data.shape[0]-1): 8 9 # 开仓10 if data.loc[i,'beta_norm']>S and position ==0:11 data.loc[i,'flag'] = 112 data.loc[i+1,'position'] = 113 position = 114 # 平仓15 elif data.loc[i,'beta_norm']<-S and position ==1: 16 data.loc[i,'flag'] = -117 data.loc[i+1,'position'] = 0 18 position = 01920 # 保持21 else:22 data.loc[i+1,'position'] = data.loc[i,'position'] 2324 data['nav'] = (1+data.close.pct_change(1).fillna(0)*data.position).cumprod() 2526 return(data) 

4. 修正标准分策略回测

策略逻辑同3。

 1def RSRS3(HS300,S = 0.7): 2 data = HS300.copy() 3 data['flag'] = 0 # 买卖标记 4 data['position'] = 0 # 持仓标记 5 position = 0 # 是否持仓,持仓:1,不持仓:0 6 for i in range(1,data.shape[0]-1): 7 8 # 开仓 9 if data.loc[i,'RSRS_R2']>S and position ==0:10 data.loc[i,'flag'] = 111 data.loc[i+1,'position'] = 112 position = 113 # 平仓14 elif data.loc[i,'RSRS_R2']<-S and position ==1: 15 data.loc[i,'flag'] = -116 data.loc[i+1,'position'] = 0 17 position = 01819 # 保持20 else:21 data.loc[i+1,'position'] = data.loc[i,'position'] 2223 data['nav'] = (1+data.close.pct_change(1).fillna(0)*data.position).cumprod() 2425 return(data)

5. 右偏标准分策略回测

策略逻辑同3。

 1def RSRS4(HS300,S = 0.7): 2 data = HS300.copy() 3 data['flag'] = 0 # 买卖标记 4 data['position'] = 0 # 持仓标记 5 position = 0 # 是否持仓,持仓:1,不持仓:0 6 for i in range(1,data.shape[0]-1): 7 8 # 开仓 9 if data.loc[i,'beta_right']>S and position ==0:10 data.loc[i,'flag'] = 111 data.loc[i+1,'position'] = 112 position = 113 # 平仓14 elif data.loc[i,'beta_right']<-S and position ==1: 15 data.loc[i,'flag'] = -116 data.loc[i+1,'position'] = 0 17 position = 01819 # 保持20 else:21 data.loc[i+1,'position'] = data.loc[i,'position'] 2223 data['nav'] = (1+data.close.pct_change(1).fillna(0)*data.position).cumprod() 2425 return(data)

6. 回测结果汇总

回测区间:同研报

与研报结果相对比,斜率指标回测结果基本相同,其余均差异较大。此外,右偏标准分策略表现最好与研报一致,但标准分策略表现较差与报告结果不符。

回测区间:2005年3月-当前

从净值曲线来看,右偏标准分策略依然表现最好,btw,2018年后所有策略都在出现明显回撤后保持空仓,所以,入市需谨慎呐。

参考资料

1. 20170501-光大证券-光大证券技术择时系列报告之一:基于阻力支撑相对强度(RSRS)的市场择时

标签: #回测python