SPL 量化系列实践:RSRS 择时策略

当股价上涨时遇到压力,呈现出卖方力量强于买方力量的势态,此时股价趋于滞涨或回撤,把该价位看做阻力位;反之,把买方力量强于卖方力量,股价趋于止跌或反弹时的价位看作支撑位。阻力支撑相对强度(Resistance Support Relative StrengthRSRS)即一种阻力位与支撑位的运用方式。

RSRS择时量化交易策略使用相对强度(如斜率、标准化等参数)作为判断点,横向比较支撑位和阻力位的作用力,当支撑位作用力的强度小且弱于阻力位时,众多交易者对支撑位的分歧大于对阻力位的分歧,市场主要呈现下跌趋势;相反地,当支撑位作用力的强度大且强于阻力位时,交易者对阻力位的分歧大于对支撑位的分歧,市场倾向于上涨趋势。

对于具体该如何量化定义支撑位与阻力位,以及如何量化定义它们的相对强度的问题,需要考虑:

1)并非要将支撑位与阻力位作为交易策略的阈值,而是要更关注市场参与者对阻力位与支撑位的定位一致性;

2)需要能迅速反映近期市场对阻力位与支撑位态度的性质;

3)被全体市场参与者的交易行为所认可。

经过上述分析,把每日最高价与每日最低价看作较好满足需求的代理变量。

相对位置变化程度以类似Δhigh/Δlow的值来描述支撑位与阻力位的相对强度,实际上是连接高低价格线的斜率。

详细过程如下:

1. 用线性模型计算lowhigh的斜率β

β=linefit(low,high)

其中lowhigh都是N个交易日的最低价和最高价序列。

2. 计算M个交易日的标准分RSRS_std

RSRS_std=(β)

其中uMβ的均值,是Mβ的标准差。

标准分RSRS_std度量原始斜率偏离其均值多少个标准差。

3. 修正标准分RSRS_std_u

R2=1-sum((high-high’)2)/var(high)

RSRS_std_u= RSRS_std * R2

其中var()是方差计算方法,highM个交易日的最高价,high’是预测最高价。

4. 右偏标准分

RSRS_std_r=RSRS_std_u*β

5. 买入信号和卖出信号signal

右偏标准分RSRS_std_r >s1,买入信号(signal=1),RSRS_std_r <s2,卖出信号(signal=-1

其中s1s2是标准分阈值,本例设s1=0.7s2=-0.7

6. 价格趋势优化买入信号

RSRS右偏标准分指标发出买入信号时,需判断市场价格趋势情况,如判断前一日MA20的值是否大于前三日的MA20值,若是,则买入。

其中MA20是后复权收盘价20日指数移动平均。

7. 确认买入和卖出标志flag

买入条件:

1. RSRS右偏标准分指标发出买入信号RSRS_std_r >s1

2. MA20的值大于前三日的MA20值。

3. 空仓。

三个条件同时满足,flag=1

卖出条件:

1. RSRS右偏标准分指标发出卖出信号RSRS_std_r <s2flag=-1

2. 有仓位

SPL代码


A

1

=N=18

2

=M=252

3

=MA=20

4

=k=2/(MA+1)

5

=s1=0.7

6

=s2=-0.7

7

=file("daily/300750.csv").import@tc()

8

=A7.pselect@b(if(trade_date>20200101,1,0):1)

9

=A8-N-M

10

=A7.to(A9,)

11

=A10.derive(if(#>1, close/ pre_close *factor[-1], close/pre_close):factor)

12

=hfq_fst=A11(1),A11.new(ts_code,trade_date,(fcls=factor/hfq_fst.factor*hfq_fst.close,c=fcls/close,round(c*open,2)): hfq_open,round(c*high,2): hfq_high,round(c*low,2): hfq_low,round(fcls,2): hfq_close)

13

=r2=null,ps=0,A12.derive(if(#<=N,,(h=hfq_high[-N+1:0],l=hfq_low[-N+1:0],lb=l.(~|1),w=linefit(lb,h),hp=mul(lb,w).(~(1)),r2=1-(hp--h).sum(abs(~))/var@s(h),w.~(1))):beta,if(#<=N+M,,(bt=beta[-M+1:0],miu=bt.avg(),sigma=sqrt(var@s(bt)),(beta-miu)/sigma)):RSRS_std,RSRS_std*r2:RSRS_std_u,RSRS_std_u*beta:RSRS_std_r,if(#>1,k* hfq_close+(1-k)*MA20[-1],hfq_close):MA20,if(RSRS_std_r>s1&&MA20>MA20[-3:-1].max(),1,if(RSRS_std_r<s2,-1,0)):signal,if(ps==0&&signal==1,(ps=1,1),if(ps!=0&&signal==-1,(ps=0,-1),0)):flag,if(flag!=0,100,0):shares).to(M+N+1,)

A1~A6:设置策略需要的参数。

A7~A10:取202011日前的数据用于计算βR2MA20等,202011日后的数据用来计算买入卖出信号。

A11A12:计算后复权价,包括开、高、低、收。

A12数据:

..

A13:根据上述计算方法,计算βR2RSRS_std_uRSRS_std_rMA20等,并根据这些指标计算买入卖出信号signal和买入卖出标志flag

..

A13中的代码看起来多,其实都是按照计算方法,一步一步算的,只不过省去了for循环的过程,而且有~,#,[]的支持,使得代码书写更流畅便捷。

根据A13的数据画出买卖信号图:

..

横轴是日期,左纵轴是后复权收盘价,右纵轴是RSRS_std_r值,红色圆点是买入点,绿色方点是卖出点。

从图中不难看出,买点和卖点都是按照计算逻辑得到的。

过滤出A13数据中flag不为0的行,调用回测接口即可得到回测收益率图和回测指标。

回测收益率图:

..

回测指标:

indicators

value

累计收益率 (cumulative rate of return)

228.2%

年化收益率 (annualized rate of return)

33.01%

年化波动率 (annual volatility)

110.44%

夏普比率 (sharpe ratio)

0.27

最大回撤 (maximum drawdown)

55.65%

投入现金 (cash invested)

13158.48

总资产 (total assets)

43185.48

仓位占比 (stock holding ratio)

89.23%

盈利次数 (profit times)

3

亏损次数 (losses times)

1