python搭建量化交易策略(Python量化交易利用Tushare数据之三)
python搭建量化交易策略(Python量化交易利用Tushare数据之三)2). 市场变化及时抓:阻力支撑相对强度指标对于市场状态的改变敏感。滞后性低,相比于均线,MACD等有明显滞后性的技术指标,RSRS指标可以当作一种领先指标,对市场变化有预判效果。运用RSRS指标择时的一大优势即使能在市场即将牛熊转换时,提前离场,锁定收益。1). 阻力支撑新视角:有别于传统中对于阻力位与支撑位的定值应用,从变量的角度来探索它们对于未来市场涨跌预测性的价值。通过定义阻力支撑相对强度的概念,设计出对未来市场收益有显著预测性的技术指标。RSRS右偏标准分指标与市场未来2周收益率的相关系数高达75%。常见的确定阻力支撑位的方法有,布林带上下轨突破策略(突破上轨建仓买入,突破下轨卖出平仓)和均线策略(如超过20日均线建仓买入,低于20日均线卖出平仓)。然而,布林带突破策略在震荡期间出现了持续亏损,均线策略交易成本巨大,且在震荡期间的回撤很大。阻力支撑相对强度(Resistance
一、 概述本篇基于光大证券研报《基于阻力支撑相对强度(Resistance Support Relative Strength,简称RSRS)的市场择时》,从支撑位与阻力位相对强度的变化对于未来股票行情状态进行预测,并通过Python编程对Tushare获取的基础数据进行量化分析,为选股提供一定的数据依据。
二、 阻力支撑相关概念2.1 阻力位阻力位是指股票价格上涨时可能遇到的阻力,也就是所谓的瓶颈,导致其继续上涨失败甚至可能回落。即交易者认为卖方力量开始反超买方,从而价格难以继续上涨或从此回调下跌的价位。
2.2 支撑位支撑位是指股价在下跌的过程中遇到了下方的支撑,让股价不至于跌跌不休,甚至出现止跌回稳的走势。即交易者认为买方力量开始反超卖方,从而止跌或反弹上涨的价位。
阻力位与支撑位是相对而言的,在股价运行时,阻力与支撑是可以互换的。具体地说,如果重大的阻力位被有效突破,那么该阻力位则反过来变成未来重要的支撑位;反之,如果重要的支撑位被有效击穿,则该价位反而变成今后股价上涨的阻力位了。
2.3 确定阻力支撑位的常见方法常见的确定阻力支撑位的方法有,布林带上下轨突破策略(突破上轨建仓买入,突破下轨卖出平仓)和均线策略(如超过20日均线建仓买入,低于20日均线卖出平仓)。然而,布林带突破策略在震荡期间出现了持续亏损,均线策略交易成本巨大,且在震荡期间的回撤很大。
三、 阻力支撑相对强度(RSRS)的相关概念阻力支撑相对强度(Resistance Support Relative Strength,RSRS)是另一种阻力位与支撑位的运用方式,它不再把阻力位与支撑位当作一个定值,而是看作一个变量,反应了交易者对目前市场状态顶底的一种预期判断。
3.1 RSRS的特点根据光大证券研报,阻力支撑相对强度(RSRS)具有以下特点:
1). 阻力支撑新视角:有别于传统中对于阻力位与支撑位的定值应用,从变量的角度来探索它们对于未来市场涨跌预测性的价值。通过定义阻力支撑相对强度的概念,设计出对未来市场收益有显著预测性的技术指标。RSRS右偏标准分指标与市场未来2周收益率的相关系数高达75%。
2). 市场变化及时抓:阻力支撑相对强度指标对于市场状态的改变敏感。滞后性低,相比于均线,MACD等有明显滞后性的技术指标,RSRS指标可以当作一种领先指标,对市场变化有预判效果。运用RSRS指标择时的一大优势即使能在市场即将牛熊转换时,提前离场,锁定收益。
3). 配合量价效果佳:RSRS右偏标准分指标做多策略应用在2005年3月至2017年3月沪深300指数数据上,策略交易39次,在不计成本的情况下12年总收益1573.60%,平均年化25.82%,夏普比率1.20。价格优化右偏标准分做多策略交易32次,在不计成本的情况下12年总收益1971.05%,平均年化28.19%,夏普比率1.56。同期沪深300指数总收益350.94%。
4). 多种市场皆有效:RSRS价格优化右偏标准分策略应用在2005年3月至2017年3月上证50指数上,交易32次,在不计成本的情况下12年总收益1432.36%,平均年化24.84%,夏普比率1.42,最大回撤 -18.37%。同期上证50指数总收益290.13%。RSRS价格优化右偏标准分策略应用在2005年3月至2017年3月中证500指数上,交易39次,在不计成本的情况下12年总收益2898.93%,平均年化32.39%,夏普比率1.58,最大回撤 -26.21%。同期中证500指数总收益661.20%。
3.2 RSRS的应用逻辑如果支撑位的强度小,作用弱于阻力位,则表明市场参与者对于支撑位的分歧大于对于阻力位的分歧,市场接下来更倾向于向熊市转变。而如果支撑位的强度大,作用强于阻力位,则表示市场参与者对于支撑位的认可度更高于对于阻力位的认可度,市场更倾向于在牛市转变。按照不同市场状态分类来说明支撑阻力相对强度的应用逻辑:
1). 市场在上涨牛市中:
- 如果支撑明显强于阻力,牛市持续,价格加速上涨。
- 如果阻力明显强于支撑,牛市可能即将结束,价格见顶。
2). 市场在震荡中:
- 如果支撑明显强于阻力,牛市可能即将启动。
- 如果阻力明显强于支撑,熊市可能即将启动。
3). 市场在下跌熊市中:
- 如果支撑明显强于阻力,熊市可能即将结束,价格见底。
- 如果阻力明显强于支撑,熊市持续,价格加速下跌。
从最高价与最低价的形成机制出发,每日最高价和最低价是一种阻力位与支撑位,它是当日全体市场参与者的交易行为所认可的阻力与支撑。一个很自然的想法是建立最高价和最低价的线性回归(线性回归也被称为最小二乘法回归(Linear Regression also called Ordinary Least-Squares (OLS) Regression)),并计算出斜率。即:
high = α β ‧ low ε ε ~ N (0 σ2)
其中,被α称为常数项或截距;β被称为模型的回归系数或斜率;ε为误差项。
那么β值就是我们所需要的斜率。其中N 的取法不能太小,不然不能过滤掉足够多的噪音;但也不能太大,因为我们希望得到的是体现目前市场的支撑阻力相对强度,若取值太大,则滞后性太高。
当斜率β值很大时,支撑强度强于阻力强度。从最高价最低价序列来看,最高价变动比最低价迅速。在上涨牛市中与下跌熊市中很可能以下图中两种走势体现:在牛市中阻力渐小,上方上涨空间大;在熊市中支撑渐强,下跌势头欲止。
当斜率值很大时,支撑强度大于阻力强度。
阻力渐小,上方上涨空间大
支撑渐强,下跌势头欲止
当斜率值很小时,阻力强度大于支撑强度。
阻力渐强,上涨势头渐止
支撑渐弱,下方下跌空间渐大
3.4 阻力支撑相对强度(RSRS)指标的构建在确定阻力与支撑的代理变量以及相对强度的定义之后,我们依此建立RSRS 指标。
(一)直接利用斜率的本身作为指标值。当日RSRS斜率指标的计算方式如下:
1. 取前N日的最高价序列与最低价序列。(N = 18)
2. 将两列数据按以上方程式的模型进行OLS线性回归。
3. 将拟合后的β值作为当日的RSRS斜率指标值。
4. 当RSRS斜率大于Sbuy时,买入;小于Ssell时卖出;(Sbuy=1 Ssell=0.8)
由于市场处于不同时期时,斜率的均值有比较大的波动。因此,直接采用斜率均值作为择时指标并不太合适。
(二)是将RSRS斜率标准化,取其标准分作为指标值。当日标准分的计算方式如下:
1. 取前M日的RSRS斜率时间序列。(N=18 M = 600)
2. 以此序列计算当日RSRS斜率的标准分RSRSstd:
RSRSstd = (RSRS斜率 – μM) / σM
其中:μM为前M日的斜率均值,σM为前M日的标准差。
3. 若RSRSstd大于Sbuy,则全仓买入;若RSRSstd小于Ssell,则卖出平仓。(Sbuy=0.7,Ssell=−0.7)
四、 RSRS指标择时的效果策略应用在2005 年3 月到2017 年4 月的沪深300 指数数据上:斜率策略交易41 次,在不计成本的情况下12 年总收益1056.62%,平均年化21.71%,夏普比率1.10,最大回撤 -51.69%。同期沪深300 指数总收益350.94%。
标准分策略交易52 次,在不计成本的情况下12 年总收益1337.37%,平均年化24.12%,夏普比率1.27,最大回撤 -46.16%。同期沪深300 指数总收益350.94%。
RSRS指标策略在沪深300指数上的净值表现
RSRS斜率指标策略在不同成本下的净值表现
RSRS标准分指标策略在不同成本下的净值表现
五、 RSRS标准分指标优化从标准分策略中,我们发现巨大的回撤发生在2008 年大熊市中期,一种猜测是策略将其误判为下跌见底,从而尝试抄底买入。由于在大熊市中,每日跌幅十分巨大,这样的错误信号即使策略在几天后发现依旧在下跌趋势而平仓,往往也已经造成巨大损失。
我们通过对修正指标本身或融合其它量价信息来使得策略得到优化。
5.1 RSRS修正标准分在使用斜率量化阻力支撑相对强度时,其量化效果很大程度上受拟合本身效果的影响。我们将RSRS标准分与决定系数R2相乘得到RSRS修正标准分,以此降低绝对值很大,但拟合效果很差的RSRS标准分对策略的影响。通过这种变换,修正RSRS标准分有明显的向正态修正的效果。
RSRS标准分分布情况,其尾部较厚
RSRS修正标准分,可以看出修正后更加接近于正态分布
5.2 RSRS右偏标准分然而,修正标准分在预测性上的改善效果主要体现于标准分左侧,在做多策略中,左侧预测性改善对择时策略帮助并不大。我们将RSRS修正标准分与RSRS斜率值相乘得到RSRS右偏标准分。其分布如下图,可以看出右偏标准分左侧较薄,而右侧较厚。
RSRS右偏修正标准分分布
5.3 RSRS右偏标准分指标策略的表现RSRS 右偏标准分指标在成本冲击下的表现。策略开仓39 次,交易成本对策略冲击不大。在无成本下策略净值15.74,双边成本0.4%下策略净值13.49,双边成本0.6%下策略净值12.49。
RSRS右偏标准分指标策略在不同成本下的净值表现
六、 RSRS指标配合量价数据优化策略为了规避掉在大熊市买入的情况,我们尝试在开仓时,加入一个对目前市场状态的判断,过滤掉下跌行情中的开仓。下面给出基于价格趋势和基于交易量趋势两种优化。
6.1 RSRS右偏标准分指标 市场价格趋势优化交易策略一个直接的想法是从近期历史价格趋势进行判断,使用前1日的20日均线值和3日前的20日均线值的相对大小来判断近期市场状态。策略如下(取值来自研报):
1、 计算RSRS右偏标准分指标RSRSrightdev。(N = 18 M = 600)
2、 若RSRSrightdev大于Sbuy,同时满足前1日的MA20的值大于前3日的MA20的值,则全仓买入。(Sbuy=0.7)
3、 若RSRSrightdev小于Ssell,同时满足前1日的MA20的值小于前3日的MA20的值,则卖出平仓。(Ssell=−0.7)
不同分布标准分指标策略在价格优化下的净值比较
6.2 基于RSRS 指标与交易量相关性的优化交易量相关性优化交易策略:
1、 计算RSRS 标准分指标RSRSrightdev。(N = 18 M = 600)
2、 若RSRSrightdev大于Sbuy,同时满足前10 日交易量与修正标准分之间的相关性为正,则买入。(Sbuy=0.7)
3、 若RSRSrightdev小于Ssell,则卖出平仓。(Ssell=−0.7)
各标准分指标策略在交易量相关性优化下的净值比较
七、 标准分优化策略在多空及其它市场上的实证效果RSRS 价格优化右偏标准分策略应用在2005 年3 月至2017 年3 月上证50 指数上,净值14.32,交易32 次,在0.6%双边成本下净值11.82,最大回撤 -18.37%。同期上证50 指数净值2.90。
策略应用在2005 年3 月至2017 年3 月中证500 指数上,净值28.99,交易39 次,在0.6%双边成本下净值22.95,最大回撤 -26.21%。同期中证500 指数总收益661.20%。
价格优化右偏标准分指标多空策略在沪深300指数上的净值表现
价格优化右偏标准分指标策略在上证500指数上的净值表现
价格优化右偏标准分指标策略在中证500指数上的净值表现
八、 右偏标准分 价格趋势优化策略的Python实现综合以上分析,RSRS 右偏标准分 价格趋势优化指标策略对于市场未来收益的择时效果显著,有较强预判市场顶底的能力。因此,我们以此策略来进行Python实现。
8.1 所需Tushare接口数据1) stock_basic股票基础数据接口。
2) daily股票日线行情数据接口。
以上两个接口数据均为免费接口,注册用户即可调用获取数据。详细接口说明,参见我的上篇文章:Python量化交易:利用Tushare数据之二——神奇九转指标策略。
8.2 Python主要代码注:因篇幅原因,以下代码为主要实现逻辑,非全部代码。如需请联系。
1) 计算RSRS斜率以及决定系数R2
""" ==================================================
*** Name: get_slope_and_r2
*** 获取指定股票指定日期的斜率和决定系数
*** Paras: lows: 前N日最低价格序列
*** highs: 前N日最高价格序列
*** Return: jason格式:slope: 斜率; r2:决定系数
"""
def get_slope_and_r2(lows highs):
slope = 0.0
r2 = 0.0
x_mean = np.mean(lows)
y_mean = np.mean(highs)
xy_mean = np.mean(lows * highs)
xx_mean = np.mean(lows * lows)
yy_mean = np.mean(highs*highs)
slope = (x_mean * y_mean - xy_mean)/(np.square(x_mean) - xx_mean)
intercept = y_mean – slope * x_mean
f = slope * lows intercept
sst = sum(np.square(highs - y_mean))
sse = sum(np.square(highs - f))
ssr = sum(np.square(f - y_mean))
r2 = ssr / sst
return {'slope':slope 'r2':r2}
2) 计算RSRS标准分以及右偏标准分
""" ==================================================
*** Name: get_rsrs_right_values
*** 获取指定股票的RSRS标准分以及右偏标准分
*** Paras: oBase: 前M日股票斜率列表
*** slope: 当日RSRS斜率
*** R2 : 当日RSRS决定系数
*** Return: jason格式。rsrs_std: RSRS标准分
*** rsrs_right: RSRS右偏标准分
"""
def get_rsrs_right_values(oBase slope R2):
s_mean = np.mean(oBase)
s_stdr = np.std(oBase)
rsrs_std = (slope - s_mean) / s_stdr
rsrs_right = rsrs_std * R2 * slope
return {'rsrs_std':rsrs_std 'rsrs_right':rsrs_right}
3) 计算股票MA20均线值
由于已经通过Tushare获取到股票每日交易数据,所有通过股票每日交易数据直接计算股票的每日MA20均线值并存储使用即可。
""" ==================================================
*** Name: get_stock_ma20_value
*** 从DB中每日交易数据表中SQL方式获取指定股票指定日期的MA20均线值
*** Paras: tscode: 股票代码
*** trdate: 交易日期
*** Return: List格式;
*** tscode: 股票代码
*** trdate: 交易日期
*** ma20 : MA20均线值
"""
def get_stock_ma20_value(tscode trdate):
sql = "SELECT T.ts_code {} AS trade_date ".format(trdate)
sql = " CASE WHEN COUNT(T.close)=20 THEN avg(T.close) ELSE 0 END AS ma20 "
sql = "FROM (SELECT D.ts_code D.trade_date D.close FROM "
sql = " stock_daily AS D WHERE D.ts_code = '{}' ".format(tscode)
sql = " AND D.trade_date <= '{}' ".format(trdate)
sql = " ORDER BY D.trade_date DESC LIMIT 20) AS T "
sql = " GROUP BY T.ts_code;"
return self.get_data_from_db(sql)
4) 右偏标准分 价格趋势优化策略实现结果
以最新2022年1月10日星期一的最新数据为基础,计算结果如下图所示。
计算结果,仅供参考