请 [注册] 或 [登录]  | 返回主站

量化交易吧 /  数理科学 帖子:3364705 新帖:26

RSRS(阻力支撑相对强度)择时策略研究

SCSDV_d发表于:5 月 10 日 04:00回复(1)

量化课堂对光大证券研报《基于阻力支撑相对强度(RSRS)的市场择时》,给出了RSRS斜率指标择时,以及在斜率基础上的标准化指标择时策略,如下:
【量化课堂】RSRS(阻力支撑相对强度)择时策略(上)

【量化课堂】RSRS(阻力支撑相对强度)择时策略(下)

但只提供了最终的策略代码,刚好今天整理资料发现了以前保存的RSRS研究文档,意外的是在聚宽的研究模块里Tushare是可以用的,所以原封不动的复制过来(除了日期略作改动),RSRS可以做什么,建议阅读原研报,
个人认为可以利用RSRS来对板块进行轮动,追踪强势板块,或者进行仓位管理,风控等。

import pandas as pdimport osimport datetimeimport numpy as np import statsmodels.formula.api as smlimport matplotlib.pyplot as pltimport tushare as tsimport scipy.stats as scsimport matplotlib.mlab as mlab#聚宽#import statsmodels.api as sm#from pandas.stats.api import ols
dateStart = datetime.date(2005,3,8)dateEnd = datetime.date(2019,3,8)HS300 = ts.get_k_data('000300', index=True,start = '{}'.format(dateStart),end = '{}'.format(dateEnd))HS300.head()

.dataframe tbody tr th:only-of-type {        vertical-align: middle;    }    .dataframe tbody tr th {        vertical-align: top;    }    .dataframe thead th {        text-align: right;    }


dateopenclosehighlowvolumecode
02005-04-08984.661003.451003.70979.5314762500.0sh000300
12005-04-111003.88995.421008.73992.7715936100.0sh000300
22005-04-12993.71978.70993.71978.2010226200.0sh000300
32005-04-13987.951000.901006.50987.9516071700.0sh000300
42005-04-141004.64986.971006.42985.5812945700.0sh000300
def getdata(dateStart,dateEnd,N,M):HS300 = ts.get_k_data('000300', index=True,start = '{}'.format(dateStart),end = '{}'.format(dateEnd))HS300=HS300[['date','high','low','open','close']]# 斜率HS300['beta'] = 0HS300['R2'] = 0for i in range(1,len(HS300)-1):df_ne=HS300.loc[ i- N+1:i + 1 ,:]model = sml.ols(formula='high~low',data = df_ne)result=model.fit()HS300.loc[i+1,'beta'] = result.params[1]HS300.loc[i+1,'R2'] = result.rsquared# 日收益率 HS300['ret'] = HS300.close.pct_change(1)# 标准分HS300['beta_norm'] = (HS300['beta'] - HS300.beta.rolling(M).mean().shift(1))/HS300.beta.rolling(M).std().shift(1)for i in range(M):HS300.loc[i,'beta_norm'] = (HS300.loc[i,'beta'] - HS300.loc[:i-1,'beta'].mean())/HS300.loc[:i-1,'beta'].std() HS300.loc[2,'beta_norm'] = 0HS300['RSRS_R2'] = HS300.beta_norm*HS300.R2HS300 = HS300.fillna(0)# 右偏标准分HS300['beta_right'] = HS300.RSRS_R2*HS300.betareturn(HS300)
dateStart = datetime.date(2005,3,8)dateEnd = datetime.date(2017,12,31)N = 18M = 600HS300 = getdata(dateStart,dateEnd,N,M)HS300.head()
/opt/conda/lib/python3.6/site-packages/ipykernel_launcher.py:22: RuntimeWarning: divide by zero encountered in double_scalars

.dataframe tbody tr th:only-of-type {        vertical-align: middle;    }    .dataframe tbody tr th {        vertical-align: top;    }    .dataframe thead th {        text-align: right;    }


datehighlowopenclosebetaR2retbeta_normRSRS_R2beta_right
02005-04-081003.70979.53984.661003.450.0000000.0000000.0000000.0000000.0000000.000000
12005-04-111008.73992.771003.88995.420.0000000.000000-0.0080020.0000000.0000000.000000
22005-04-12993.71978.20993.71978.700.7672380.653529-0.0167970.0000000.0000000.000000
32005-04-131006.50987.95987.951000.900.7912160.6871220.0226831.2088310.8306150.657196
42005-04-141006.42985.581004.64986.970.8044970.670781-0.0139170.9219750.6184440.497536
HS300 = HS300.loc[2:]HS300 =HS300.reset_index(drop = True)HS300.head()

.dataframe tbody tr th:only-of-type {        vertical-align: middle;    }    .dataframe tbody tr th {        vertical-align: top;    }    .dataframe thead th {        text-align: right;    }


datehighlowopenclosebetaR2retbeta_normRSRS_R2beta_right
02005-04-12993.71978.20993.71978.700.7672380.653529-0.0167970.0000000.0000000.000000
12005-04-131006.50987.95987.951000.900.7912160.6871220.0226831.2088310.8306150.657196
22005-04-141006.42985.581004.64986.970.8044970.670781-0.0139170.9219750.6184440.497536
32005-04-15982.61971.93982.61974.081.2148340.812732-0.0130601.7196671.3976291.697887
42005-04-18970.91958.65970.91963.771.2201310.923110-0.0105841.2711251.1733881.431687
#斜率数据分布plt.figure(figsize=(15,5))plt.hist(HS300['beta'], bins= 100, range= None, normed= False, weights= None, cumulative= False, 
         bottom= None, histtype= 'bar', align= 'mid', orientation= 'vertical', rwidth= None, log= False, color= 'r', 
         label='直方图', stacked= False)plt.show()
/opt/conda/lib/python3.6/site-packages/matplotlib/axes/_axes.py:6521: MatplotlibDeprecationWarning: 
The 'normed' kwarg was deprecated in Matplotlib 2.1 and will be removed in 3.1. Use 'density' instead.
  alternative="'density'", removal="3.1")
#RSRS标准分和右偏变准分分布plt.figure(figsize=(15,5))plt.hist(HS300['beta_norm'], bins= 100, range= None, normed= False, weights= None, cumulative= False, 
         bottom= None, histtype= 'bar', align= 'mid', orientation= 'vertical', rwidth= None, log= False, color= 'r', 
         label='直方图', stacked= False)plt.show()plt.figure(figsize=(15,5))plt.hist(HS300['RSRS_R2'], bins= 100, range= None, normed= False, weights= None, cumulative= False, 
         bottom= None, histtype= 'bar', align= 'mid', orientation= 'vertical', rwidth= None, log= False, color= 'r', 
         label='直方图', stacked= False)plt.show()
/opt/conda/lib/python3.6/site-packages/matplotlib/axes/_axes.py:6521: MatplotlibDeprecationWarning: 
The 'normed' kwarg was deprecated in Matplotlib 2.1 and will be removed in 3.1. Use 'density' instead.
  alternative="'density'", removal="3.1")
/opt/conda/lib/python3.6/site-packages/matplotlib/axes/_axes.py:6521: MatplotlibDeprecationWarning: 
The 'normed' kwarg was deprecated in Matplotlib 2.1 and will be removed in 3.1. Use 'density' instead.
  alternative="'density'", removal="3.1")
sta = scs.describe(HS300.beta)stew = sta[4]kurtosis = sta[5]sta1 = scs.describe(HS300.beta_norm)stew1 = sta1[4]kurtosis1 = sta1[5]sta2 = scs.describe(HS300.RSRS_R2)stew2 = sta2[4]kurtosis2 = sta2[5]print('斜率的均值:%s' % (HS300['beta'].mean()))print('斜率的标准差:%s' % (HS300['beta'].std()))print('斜率的偏度:%s' % (stew))print('斜率的峰度:%s' % (kurtosis))print('')print('斜率标准分的均值:%s' % (HS300['beta_norm'].mean()))print('斜率标准分的标准差:%s' % (HS300['beta_norm'].std()))print('斜率标准分的偏度:%s' % (stew1))print('斜率标准分的峰度:%s' % (kurtosis1))print('')print('斜率标准分的均值:%s' % (HS300['RSRS_R2'].mean()))print('斜率标准分的标准差:%s' % (HS300['RSRS_R2'].std()))print('斜率标准分的偏度:%s' % (stew2))print('斜率标准分的峰度:%s' % (kurtosis2))
斜率的均值:0.9107300548852182
斜率的标准差:0.11510992220867003
斜率的偏度:-0.37650035325581255
斜率的峰度:0.880393019660489

斜率标准分的均值:-0.02022967957717388
斜率标准分的标准差:1.0215397882843733
斜率标准分的偏度:-0.44956956799879083
斜率标准分的峰度:1.2596938448054438

斜率标准分的均值:0.04386035016941067
斜率标准分的标准差:0.8333195496560563
斜率标准分的偏度:0.13435897885521442
斜率标准分的峰度:0.4567819364025256
#斜率指标过去250天均值曲线HS300['beta_mean'] = HS300.beta.rolling(250).mean().shift(1)for i in range(250):HS300.loc[i,'beta_mean'] = HS300.loc[:i-1,'beta'].mean()result = HS300.loc[10:].copy()result = result.reset_index(drop = True)xtick = np.arange(0,result.shape[0],int(result.shape[0]/7))xticklabel = pd.Series(result.date[xtick])plt.figure(figsize=(15,3))fig = plt.axes()plt.plot(np.arange(result.shape[0]),result.beta_mean,linewidth = 3,color = 'black')fig.set_xticks(xtick)fig.set_xticklabels(xticklabel,rotation = 45)plt.legend()plt.show()
#斜率指标交易策略标准分策略def RSRS1(HS300,S1 = 1.0,S2 = 0.8):data  = HS300.copy()data['flag'] = 0 # 买卖标记data['position'] = 0 # 持仓标记position = 0 # 是否持仓,持仓:1,不持仓:0for i in range(1,data.shape[0]-1):# 开仓if data.loc[i,'beta']>S1 and position ==0:data.loc[i,'flag'] = 1data.loc[i+1,'position'] = 1position = 1# 平仓elif data.loc[i,'beta']<S2 and position ==1: data.loc[i,'flag'] = -1data.loc[i+1,'position'] = 0     position = 0# 保持else:data.loc[i+1,'position'] = data.loc[i,'position']     
        data['n*'] = (1+data.close.pct_change(1).fillna(0)*data.position).cumprod() 
        return(data)
#标准分策略def RSRS2(HS300,S = 0.7):data = HS300.copy()data['flag'] = 0 # 买卖标记data['position'] = 0 # 持仓标记position = 0 # 是否持仓,持仓:1,不持仓:0for i in range(1,data.shape[0]-1):# 开仓if data.loc[i,'beta_norm']>S and position ==0:data.loc[i,'flag'] = 1data.loc[i+1,'position'] = 1position = 1# 平仓elif data.loc[i,'beta_norm']<-S and position ==1: data.loc[i,'flag'] = -1data.loc[i+1,'position'] = 0     position = 0# 保持else:data.loc[i+1,'position'] = data.loc[i,'position']     
        data['n*'] = (1+data.close.pct_change(1).fillna(0)*data.position).cumprod() 
           return(data)
# 修正标准分策略def RSRS3(HS300,S = 0.7):data = HS300.copy()data['flag'] = 0 # 买卖标记data['position'] = 0 # 持仓标记position = 0 # 是否持仓,持仓:1,不持仓:0for i in range(1,data.shape[0]-1):# 开仓if data.loc[i,'RSRS_R2']>S and position ==0:data.loc[i,'flag'] = 1data.loc[i+1,'position'] = 1position = 1# 平仓elif data.loc[i,'RSRS_R2']<-S and position ==1: data.loc[i,'flag'] = -1data.loc[i+1,'position'] = 0     position = 0# 保持else:data.loc[i+1,'position'] = data.loc[i,'position']     
        data['n*'] = (1+data.close.pct_change(1).fillna(0)*data.position).cumprod() 
           return(data)
#右偏标准分策略def RSRS4(HS300,S = 0.7):data = HS300.copy()data['flag'] = 0 # 买卖标记data['position'] = 0 # 持仓标记position = 0 # 是否持仓,持仓:1,不持仓:0for i in range(1,data.shape[0]-1):# 开仓if data.loc[i,'beta_right']>S and position ==0:data.loc[i,'flag'] = 1data.loc[i+1,'position'] = 1position = 1# 平仓elif data.loc[i,'beta_right']<-S and position ==1: data.loc[i,'flag'] = -1data.loc[i+1,'position'] = 0     position = 0# 保持else:data.loc[i+1,'position'] = data.loc[i,'position']     
        data['n*'] = (1+data.close.pct_change(1).fillna(0)*data.position).cumprod() 
           return(data)
result = RSRS1(HS300)num = result.flag.abs().sum()/2n* = result.n*[result.shape[0]-1]print('交易次数 = ',num)print('策略净值为= ',n*)
交易次数 =  44.0
策略净值为=  11.211012175460354
xtick = np.arange(0,result.shape[0],int(result.shape[0]/7))xticklabel = pd.Series(result.date[xtick])plt.figure(figsize=(15,3))fig = plt.axes()plt.plot(np.arange(result.shape[0]),result.n*,label = 'RSRS1',linewidth = 2,color = 'red')plt.plot(np.arange(result.shape[0]),result.close/result.close[0],color = 'yellow',label = 'HS300',linewidth = 2)fig.set_xticks(xtick)fig.set_xticklabels(xticklabel,rotation = 45)plt.legend()plt.show()
result2 = RSRS2(HS300)num = result2.flag.abs().sum()/2n* = result2.n*[result.shape[0]-1]ret_year = (n* - 1)print('交易次数 = ',num)print('策略净值为= ',n*)
交易次数 =  49.5
策略净值为=  9.793926481255566
result3 = RSRS3(HS300)num = result3.flag.abs().sum()/2n* = result3.n*[result.shape[0]-1]ret_year = (n* - 1)print('交易次数 = ',num)print('策略净值为= ',n*)
交易次数 =  44.5
策略净值为=  8.58132605273418
dateStart = datetime.date(2005,3,8)dateEnd = datetime.date(2017,12,31)N = 16M = 300HS300 = getdata(dateStart,dateEnd,N,M)HS300 = HS300.loc[2:]HS300 =HS300.reset_index(drop = True)
/opt/conda/lib/python3.6/site-packages/ipykernel_launcher.py:22: RuntimeWarning: divide by zero encountered in double_scalars
result4 = RSRS4(HS300)num = result4.flag.abs().sum()/2n* = result4.n*[result.shape[0]-1]ret_year = (n* - 1)print('交易次数 = ',num)print('策略净值为= ',n*)
交易次数 =  37.5
策略净值为=  9.946785407409507
xtick = np.arange(0,result.shape[0],int(result.shape[0]/7))xticklabel = pd.Series(result.date[xtick])plt.figure(figsize=(15,3))fig = plt.axes()plt.plot(np.arange(result.shape[0]),result.n*,label = 'RSRS1',linewidth = 2)plt.plot(np.arange(result.shape[0]),result2.n*,label = 'RSRS2',linewidth = 2)plt.plot(np.arange(result.shape[0]),result3.n*,label = 'RSRS3',linewidth = 2)plt.plot(np.arange(result.shape[0]),result4.n*,label = 'RSRS4',linewidth = 2)plt.plot(np.arange(result.shape[0]),result.close/result.close[0],color = 'yellow',label = 'HS300',linewidth = 2)fig.set_xticks(xtick)fig.set_xticklabels(xticklabel,rotation = 45)plt.legend()plt.show()
#四种策略时间更新到当前dateStart = datetime.date(2005,3,1)dateEnd = datetime.date(2019,3,8)N = 18M = 600HS300 = getdata(dateStart,dateEnd,N,M)HS300 = HS300.loc[2:]HS300 =HS300.reset_index(drop = True)HS300.head()
/opt/conda/lib/python3.6/site-packages/ipykernel_launcher.py:22: RuntimeWarning: divide by zero encountered in double_scalars

.dataframe tbody tr th:only-of-type {        vertical-align: middle;    }    .dataframe tbody tr th {        vertical-align: top;    }    .dataframe thead th {        text-align: right;    }


datehighlowopenclosebetaR2retbeta_normRSRS_R2beta_right
02005-04-12993.71978.20993.71978.700.7672380.653529-0.0167970.0000000.0000000.000000
12005-04-131006.50987.95987.951000.900.7912160.6871220.0226831.2088310.8306150.657196
22005-04-141006.42985.581004.64986.970.8044970.670781-0.0139170.9219750.6184440.497536
32005-04-15982.61971.93982.61974.081.2148340.812732-0.0130601.7196671.3976291.697887
42005-04-18970.91958.65970.91963.771.2201310.923110-0.0105841.2711251.1733881.431687
#斜率指标策略result = RSRS1(HS300)num = result.flag.abs().sum()/2n* = result.n*[result.shape[0]-1]print('交易次数 = ',num)print('策略净值为= ',n*)
交易次数 =  47.5
策略净值为=  11.833232225885457
#标准分策略result2 = RSRS2(HS300)num = result2.flag.abs().sum()/2n* = result2.n*[result.shape[0]-1]ret_year = (n* - 1)print('交易次数 = ',num)print('策略净值为= ',n*)
交易次数 =  53.5
策略净值为=  10.546245684216888
#修正标准分策略result3 = RSRS3(HS300)num = result3.flag.abs().sum()/2n* = result3.n*[result.shape[0]-1]ret_year = (n* - 1)print('交易次数 = ',num)print('策略净值为= ',n*)
交易次数 =  46.5
策略净值为=  9.87532821653873
dateStart = datetime.date(2005,3,1)dateEnd = datetime.date(2019,3,8)N = 16M = 300HS300 = getdata(dateStart,dateEnd,N,M)HS300 = HS300.loc[2:]HS300 =HS300.reset_index(drop = True)HS300.head()
/opt/conda/lib/python3.6/site-packages/ipykernel_launcher.py:22: RuntimeWarning: divide by zero encountered in double_scalars

.dataframe tbody tr th:only-of-type {        vertical-align: middle;    }    .dataframe tbody tr th {        vertical-align: top;    }    .dataframe thead th {        text-align: right;    }


datehighlowopenclosebetaR2retbeta_normRSRS_R2beta_right
02005-04-12993.71978.20993.71978.700.7672380.653529-0.0167970.0000000.0000000.000000
12005-04-131006.50987.95987.951000.900.7912160.6871220.0226831.2088310.8306150.657196
22005-04-141006.42985.581004.64986.970.8044970.670781-0.0139170.9219750.6184440.497536
32005-04-15982.61971.93982.61974.081.2148340.812732-0.0130601.7196671.3976291.697887
42005-04-18970.91958.65970.91963.771.2201310.923110-0.0105841.2711251.1733881.431687
result4 = RSRS4(HS300)num = result4.flag.abs().sum()/2n* = result4.n*[result.shape[0]-1]ret_year = (n* - 1)print('交易次数 = ',num)print('策略净值为= ',n*)
交易次数 =  39.5
策略净值为=  11.446891338270705
xtick = np.arange(0,result.shape[0],int(result.shape[0]/7))xticklabel = pd.Series(result.date[xtick])plt.figure(figsize=(15,3))fig = plt.axes()plt.plot(np.arange(result.shape[0]),result.n*,label = 'RSRS1',linewidth = 2)plt.plot(np.arange(result.shape[0]),result2.n*,label = 'RSRS2',linewidth = 2)plt.plot(np.arange(result.shape[0]),result3.n*,label = 'RSRS3',linewidth = 2)plt.plot(np.arange(result.shape[0]),result4.n*,label = 'RSRS4',linewidth = 2)plt.plot(np.arange(result.shape[0]),result.close/result.close[0],color = 'yellow',label = 'HS300',linewidth = 2)fig.set_xticks(xtick)fig.set_xticklabels(xticklabel,rotation = 45)plt.legend()plt.show()
 

全部回复

0/140

量化课程

    移动端课程