Python量化交易进阶讲堂-基于欧奈尔RPS指标选股策略

4,622 阅读8分钟

欢迎大家订阅《Python实战-构建基于股票的量化交易系统》小册子,小册子会陆续推出与小册内容相关的专栏文章,对涉及到的知识点进行更全面的扩展介绍,并且会有选择地收录至小册中,更便于广大读者查阅知识点。本篇专栏为小册子内容的加推篇!!!

前言

在国内大家可能对彼得·林奇(Peter Lynch)、沃伦·巴菲特(Warren E. Buffett)这些华尔街(wall street)的金融大鳄比较熟悉,其实威廉·欧奈尔(William J. O’Neil)的投资成就同样和他们相媲美。

威廉·欧奈尔把投资理念集中于他自创的CANSLIM选股系统,凭借着这个系统驰骋股票市场数十年,无论在牛市还是熊市,这个系统都是最稳定、表现最好的系统之一。

概括地说,CANSLIM体系是典型的价值投资法,它专注于挑选基本面优秀、技术面突出、又有足够机构投资者支持的领涨股。

CANSLIM选股系统中有一个RPS指标(Relative Price Strength Rating),即股价相对强度指标,根据一段时间内个股涨幅在全部股票涨幅排名中的位次值,选取出市场中的强势股。

本节我们就来介绍下如何计算欧奈尔RPS指标,以及如何基于欧奈尔RPS指标制定选股策略。

涨跌幅指标的计算

RPS指标怎么计算呢?RPS的值介于0-100之间,比如A股共有1000只股票,若某只股票的250日的涨幅在所有股票中排名第100位,则该股票的RPS值为:(1-100/1000)*100=90。

RPS的值代表该股的250日涨幅超过其他90%的股票的涨幅。通过该指标可以反映出个股的走势在同期市场中的相对强弱表现。因此在过去250个交易日,所有股票的涨幅排行中,前1%的股票的RPS值为99至100,前2%的股票的RPS值为98至99……以此类推。

RPS时间周期可以自己根据需要进行调整,默认定义为250日(一年),当然常用的还有60日(3个月)、120日(半年)等等。

接下来我们一步步用代码来实现RPS指标的计算。这里我们使用tushare的数据,查看下股票伟星新材的收盘价序列,数据获取可参照《差异化分析常用股票交易数据接口》小节。如下所示:

"""
trade_date
2018-01-02    19.78
2018-01-03    20.36
2018-01-04    20.60
2018-01-05    20.77
2018-01-08    20.62
2018-01-09    20.96
2018-01-10    20.53
              ...  
2019-12-31    13.17
Name: close, Length: 487, dtype: float64
"""

计算股票N日的涨跌幅,公式为:今日收盘价/昨日收盘价-1,其实也可以使用DataFrame.pct_change()这个方法,效果是一样的。为了显示比较直观以5日涨幅为例,如下所示,当然对于缺失值我们应该按之前介绍的方法用0去填充。

"""
trade_date
2018-01-02         NaN
2018-01-03         NaN
2018-01-04         NaN
2018-01-05         NaN
2018-01-08         NaN
2018-01-09    0.059656
2018-01-10    0.008350
                ...   
2019-12-31    0.025701
Name: close, Length: 487, dtype: float64
"""

因为RPS指标指的是一段时间内个股涨幅在全部股票涨幅排名中的位次值,所以接下来我们要计算出全部股票的120日涨跌幅数值,如下所示:

"""
                平安银行      万科A     国农科技    ...   继峰股份     方盛制药   读者传媒
trade_date                                  ...                                 
2019-07-03  0.524483  0.220502       NaN    ...     0.016753  0.576159  0.147368
2019-07-04  0.507543  0.227669       NaN    ...          NaN  0.554585  0.151579
2019-07-05  0.427692  0.181308       NaN    ...     0.040506  0.495763  0.096192
2019-07-08  0.395277  0.163673       NaN    ...    -0.008906  0.389344  0.043478
2019-07-09  0.406832  0.166000       NaN    ...    -0.044529  0.384146  0.029703
2019-07-10  0.364185  0.151599       NaN    ...    -0.047134  0.338614  0.043651
2019-07-11  0.340594  0.163282       NaN    ...    -0.034982  0.324803  0.048000
2019-07-12  0.384314  0.171937       NaN    ...    -0.028894  0.333992  0.029762
2019-07-15  0.384768  0.199041       NaN    ...    -0.014066  0.355865  0.042510
2019-07-16  0.342773  0.194754       NaN    ...    -0.007732  0.351085  0.021825
2019-07-17  0.306298  0.185287  0.267123    ...    -0.040764  0.339921  0.034137
2019-07-18  0.333659  0.205046  0.244923    ...    -0.033376  0.338028  0.011834
2019-07-19  0.341323  0.192158  0.225904    ...    -0.011796  0.370297 -0.011583
2019-07-22  0.339458  0.212476  0.138211    ...    -0.045514  0.352475 -0.046967
2019-07-23  0.338521  0.181102  0.148126    ...    -0.045337  0.406000 -0.027668
2019-07-24  0.341063  0.184117  0.162694    ...    -0.029948  0.394790 -0.002004
...              ...       ...       ...    ...          ...       ...       ...
2019-12-31  0.210449  0.103945  0.085536    ...     0.037227  0.224189  0.390152

[124 rows x 3003 columns]
"""

其中不同股票因为上市的时间不同,所以120日周期的移动涨跌幅会存在缺失值,我们可以用0去填充。

同学们可以参照《股票交易策略:线性回归算法建立选股策略》小节获取市场全部股票信息,再逐个获取个股数据。

当然笔者已经把数据存储为CSV文件,这样下次可以从CSV文件中导入,有需要的同学可以通过交流群获取,文件如下所示:

我们看下2019-12-31这一天平安银行120日涨幅为0.210449,我们用可视化方法看下这一天全部股票的涨跌幅排布如何,显示效果如下所示:

可以发现在3000只股票中, 120日收益率在[-0.11188698 -0.03826044]区间的股票最多,有657只,在这个区间附近也非常多。分布的数值如下所示:

"""
[  3.   8.   7.  22.  67. 151. 348. 657. 547. 427. 225. 145. 102.  97.
  62.  25.  30.  15.  15.   6.   9.   8.   8.   5.   2.   0.   2.   0.
   2.   0.   1.   0.   0.   1.   0.   1.   0.   0.   3.   0.   0.   0.
   0.   0.   0.   0.   0.   0.   1.   1.] 
[-0.62727273 -0.55364619 -0.48001966 -0.40639312 -0.33276658 -0.25914005
 -0.18551351 -0.11188698 -0.03826044  0.03536609  0.10899263  0.18261916
  0.2562457   0.32987224  0.40349877  0.47712531  0.55075184  0.62437838
  0.69800491  0.77163145  0.84525799  0.91888452  0.99251106  1.06613759
  1.13976413  1.21339066  1.2870172   1.36064373  1.43427027  1.50789681
  1.58152334  1.65514988  1.72877641  1.80240295  1.87602948  1.94965602
  2.02328256  2.09690909  2.17053563  2.24416216  2.3177887   2.39141523
  2.46504177  2.5386683   2.61229484  2.68592138  2.75954791  2.83317445
  2.90680098  2.98042752  3.05405405]
"""

我们选取前10只股票可视化涨跌幅值,显示效果如下所示:

RPS指标的计算

下一步对全部股票的涨跌幅值进行排序,排序完成后我们可以得到每一天的涨幅排名,如下所示:

"""
       2019-11-22
中国天楹     0.548611
中国长城     0.515271
深大通      0.502844
深桑达A     0.490971
全新好      0.450980
德赛电池     0.408602
神州数码     0.325490
平安银行     0.257258
...           ...
长虹华意    -0.139588
特发信息    -0.140711
兴业矿业    -0.148893
方大集团    -0.152330
"""

然后对每个股票的涨跌幅从1开始逐个编号排序,并且计算出RPS指标,以下是某一天经过排序后涨跌幅排名以及对应的RPS值和股票代码,以DataFrame数据格式存储,此处我们只罗列了其中的10只,如下所示:

"""
         pct   name   rps
n                        
1   0.457271    全新好  90.0
2   0.190374   平安银行  80.0
3   0.101951   国农科技  70.0
4   0.088542   中国宝安  60.0
5   0.071986    万科A  50.0
6  -0.051693   深振业A  40.0
7  -0.052493   神州高铁  30.0
8  -0.058116   深物业A  20.0
9  -0.077844   世纪星源  10.0
10 -0.078804  *ST美丽   0.0
"""

同样我们看下截止到2019-12-31这一天涨幅榜前十名和后十名分别是什么股票,如下所示:

RPS指标的选股

有了每天的股票RPS值排名以后,我们就可以把每天排名第一的股票汇集起来,如下所示:

"""
               pct  name      rps
20190703  2.925358  金运激光  99.9667
20190704  2.883792  金运激光  99.9667
20190705  2.779621  兴齐眼药  99.9667
20190708  3.089744  兴齐眼药  99.9667
20190709  3.130105  兴齐眼药  99.9667
...            ...   ...      ...
20191120  2.724040  宝鼎科技  99.9667
20191230  2.931699   漫步者  99.9667
20191231  3.054054   漫步者  99.9667

[124 rows x 3 columns]
"""

好了,计算RPS指标只是第一步,然后我们会针对这些数据展开可视化选股分析。

首先查看下2019年7月3日-2019年12月31日每日RPS的情况,这里我们仅列出每日RPS排名前十的股票,显示效果如下所示:

从中可以看到里面出现不少熟悉的“妖股”身影,比如金运激光、兴齐眼药、宝鼎科技、漫步者……

拿漫步者和金运激光来说,漫步者在A点开始RPS一直处于高位,保持着强势股的特征。金运激光在B点开始一直下跌,然后持续处于低位,股价一直反弹不起来。可见RPS的实战意义是,在强势股出现第一波上涨后发现它,然后深入挖掘,。当强势股转弱时也可以通过RPS的变化来观察。

总结

由此可见通过RPS指标可以初步筛选出市场中的强势股,对于选股过程来说意义重大。另一方面,该指标仍旧需要结合CANSLIM系统的其他指标一起使用,对初步筛选的股票进一步的过滤。

以上策略及涉及到的股票仅用于教学,不构成任何投资建议!投资需谨慎,入市有风险!!!

更多的量化交易内容欢迎大家订阅小册阅读!!

同时也欢迎大家关注我的微信公众号【元宵大师带你用Python量化交易】了解更多Python量化交易相关内容