量化百科

分享一种有效的量化择时方式 RSRS指标及其源码

由polll创建,最终由polll 被浏览 210 用户

阻力支撑相对强度指标(Resistance Support Relative Strength,简称 RSRS)

光大证券最早提出这一择时方法,并认为阻力和支撑位是变化(动态)的,这也就打破了支撑阻力划线分析的静态方法,研究认为每日最高价high与最低价low能很好满足这个需求。

对high和low价格做线性回归

那么既然要定量化研究,可以直接用一个值来表示强度,比如用今日的H / L,得到一个比率Ratio,但是你会发现噪音格外的高。实际上delta(high)/delta(low)是连接高低价格平面上的两点(low[0],high[0])与(low[1],high[1])的斜率,所以用最近N个(low,high)的数据点做线性回归是个降噪的好办法。

回归斜率beta,是低噪音的,然后即可用此值表示强度,这就是原始RSRS,进行择时交易。

归一化前

归一化后

为了方便将这个值归一化到一个区间,对其进行Z-score处理,RSRS_Z = (RSRS - Average(RSRS,ZLength)) / StandardDev (RSRS, ZLength, 1);

归一化前后的RSRS

我也观察了一下RSRS值的分布,的确,为了确定交易逻辑,做一下Z更好。做完Z处理后,按照研报建议,既然均值为0,可以用+-0.7作为交易开仓阈值。

如果标准分大于 S(参数 S=0.7),则买入持有。

如果标准分小于-S,则卖出平仓。

实际上测试了0.5~1,都有一定稳健性,当然在日频数据上,0.7~0.8是建议值。既然引入Z归一化,也就潜在引入了一个窗口期参数,建议使用过去2年的值,比如440个交易日即可,研报上推荐的参数是600。

线性回归因为送入回归函数的是两个序列,所以也有一个序列长度,一般使用10日或者20日,研报推荐18日。

核心逻辑相信熟悉python的朋友能看懂:

    # RSRS斜率指标定义

    prices = attribute_history(security, g.N, '1d', \['high', 'low'\])

    highs = prices.high

    lows = prices.low

    X = sm.add_constant(lows)

    model = sm.OLS(highs, X)

    beta = model.fit().params\[1\]

    g.ans.append(beta)



# 计算标准化的RSRS指标

# 计算均值序列    

section = g.ans\[-g.M:\]

# 计算均值序列

mu = np.mean(section)

# 计算标准化RSRS指标序列

sigma = np.std(section)

zscore = (section\[-1\]-mu)/sigma   

我测试的结果是:

可以说这套择时系统,跑赢指数是没有问题的,而且这是在千2手续费下,只做多的收益。针对不同的指数,在日频上,参数都是完全统一的(600归一化,18个近期高低点,+-0.7开仓阈值)。

我们在TB软件编写这一程序,并对参数稳健性做了测试,测试样本是000300沪深300指数,日线,双边千分之2手续费,结果是这样的:

Z处理回溯期(非常稳健)

开仓阈值0.8附近稳健

送入回归的高低点数量18~30范围稳健

这个结果和券商测试差不多,为什么分享这一择时指标,因为它简单清晰,而且没有引用收盘价,而是引用最高最低价,一定程度上和布林带,均线类模型不同源,可以混用。

用TB系统实现该逻辑,需要自己撰写一个线性回归函数,我想读者们应该能通过网上的资料,计算出两个序列的beta值,然后将其编译为一个函数:series_beta

这个beta的概念可以借鉴CAPM模型,资产和市场的协方差Cov,除以市场的方差Var。将其换成两个A和B序列的协方差,除以A序列的方差。

// 该函数内部结构是这样

xa = Summation(price1,length)/length;
ya = Summation(price2,length)/length;
for i = 0 to length-1
{
Lxx = Lxx + sqr(price1[i] - Xa)/length;  // Lxx = Sum((X - Xa)平方)/length,A品种方差
Lxy = Lxy + (price1[i]-Xa)*(price2[i]-Ya)/length;  // Lxy = Sum((X - Xa)(Y - Ya))/length,A和B品种协方差
}
beta= Lxy / Lxx;
// 函数结束
series_beta(low, high, LRLength, 0, beta);
该函数设定一个出参beta,本行是在模型正文里的引用方法。
RSRS = beta;
RSRS_Z = (RSRS - Average(RSRS,ZLength)) / StandardDev (RSRS, ZLength, 1);
PlotNumeric("OverSell",-1);
PlotNumeric("OverBuy",1);
PlotNumeric("RSRS_Z",RSRS_Z,0,yellow);
// 买入卖出条件
buycon = RSRS_Z[1] > buyrange;
sellcon = RSRS_Z[1] < -1*buyrange;
if ( MarketPosition <> 1 and buycon )
// 做多1
{
buy(lots0, open);
PlotString ("posit=-1","posit=-1",RSRS_Z*1.01,White);
}
// 平仓
else if (MarketPosition == 1 and sellcon )
// 平多
{
sell(0, open);
}
我们同时做多中证500,沪深300,上证50,30分钟和日线,得到以上组合回测结果。我有两个地方想说明:
1、30分钟测试显著增加了交易次数,绩效可信度上升,但是各品种参数无法统一,这是一大遗憾。
2、日线虽然可以使用一样的参数,但是交易次数较少,3个指数5年交易了22~24次。希望之后可以逐渐改进增加交易次数。

\

标签

量化择时