SPL 量化系列实践:RSRS 择时策略
当股价上涨时遇到压力,呈现出卖方力量强于买方力量的势态,此时股价趋于滞涨或回撤,把该价位看做阻力位;反之,把买方力量强于卖方力量,股价趋于止跌或反弹时的价位看作支撑位。阻力支撑相对强度(Resistance Support Relative Strength,RSRS)即一种阻力位与支撑位的运用方式。
RSRS择时量化交易策略使用相对强度(如斜率、标准化等参数)作为判断点,横向比较支撑位和阻力位的作用力,当支撑位作用力的强度小且弱于阻力位时,众多交易者对支撑位的分歧大于对阻力位的分歧,市场主要呈现下跌趋势;相反地,当支撑位作用力的强度大且强于阻力位时,交易者对阻力位的分歧大于对支撑位的分歧,市场倾向于上涨趋势。
对于具体该如何量化定义支撑位与阻力位,以及如何量化定义它们的相对强度的问题,需要考虑:
(1)并非要将支撑位与阻力位作为交易策略的阈值,而是要更关注市场参与者对阻力位与支撑位的定位一致性;
(2)需要能迅速反映近期市场对阻力位与支撑位态度的性质;
(3)被全体市场参与者的交易行为所认可。
经过上述分析,把每日最高价与每日最低价看作较好满足需求的代理变量。
相对位置变化程度以类似Δhigh/Δlow的值来描述支撑位与阻力位的相对强度,实际上是连接高低价格线的斜率。
详细过程如下:
1. 用线性模型计算low,high的斜率β:
β=linefit(low,high)
其中low和high都是N个交易日的最低价和最高价序列。
2. 计算M个交易日的标准分RSRS_std:
RSRS_std=(β-μ)/σ
其中u是M个β的均值,是M个β的标准差。
标准分RSRS_std度量原始斜率偏离其均值多少个标准差。
3. 修正标准分RSRS_std_u:
R2=1-sum((high-high’)2)/var(high)
RSRS_std_u= RSRS_std * R2
其中var()是方差计算方法,high是M个交易日的最高价,high’是预测最高价。
4. 右偏标准分
RSRS_std_r=RSRS_std_u*β
5. 买入信号和卖出信号signal
右偏标准分RSRS_std_r >s1,买入信号(signal=1),RSRS_std_r <s2,卖出信号(signal=-1)
其中s1,s2是标准分阈值,本例设s1=0.7,s2=-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 <s2,flag=-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:取2020年1月1日前的数据用于计算β,R2,MA20等,2020年1月1日后的数据用来计算买入卖出信号。
A11、A12:计算后复权价,包括开、高、低、收。
A12数据:
A13:根据上述计算方法,计算β,R2,RSRS_std_u,RSRS_std_r,MA20等,并根据这些指标计算买入卖出信号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 |