为了账号安全,请及时绑定邮箱和手机立即绑定

Python进阶量化交易专栏场外篇21-欧奈尔RPS指标的计算

欢迎大家订阅《教你用 Python 进阶量化交易》专栏!为了能够提供给大家更轻松的学习过程,笔者在专栏内容之外已陆续推出一些手记来辅助同学们学习本专栏内容,目前推出的扩展篇链接如下:

为了将专栏中分散的知识点贯穿起来,笔者在专栏的末尾小节《制作自己的量化交易工具》中分享了早期制作的一个简易版量化交易小工具,希望大家能够通过调试代码的方式掌握相关的知识。

目前在场外篇第9篇中已经移植到了Python3.7x版本上,接下来我们在这个版本的基础上逐步完善这个工具,使专栏的读者不仅能够通过小工具掌握专栏的相关知识点,也能够把工具用到自己的股票量化交易中去。

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

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

概括地说,CANSLIM体系是典型的价值投资法,它专注于挑选基本面优秀、技术面突出、又有足够机构投资者支持的领涨股。这里有两本威廉·欧奈尔著作的CANSLIM相关书籍:《How to Make Money in Stocks: A winning system in good times or bad》(《笑傲股市》、《The Successful Investor》(《股票买卖原则》)。

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

欧奈尔研究了40年(1953年至1993年),500只年度涨幅最大的美股股票,发现每年表现好的股票,在他们股价真正大幅度狂飙之前,其平均的相对强弱指标RPS为87%。

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,为了显示比较直观以5日涨幅为例,如下所示:

"""
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
"""

当然对于缺失值我们应该用0去填充。其实也可以使用DataFrame.pct_change()这个方法,效果是一样的。
因为RPS指标指的是一段时间内个股涨幅在全部股票涨幅排名中的位次值,所以接下来我们要计算出全部股票的120日涨跌幅数值,如下所示。其中不同股票因为上市的时间不同,所以120日周期的移动涨跌幅会存在缺失值,我们可以用0去填充。

"""
                平安银行      万科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]
"""

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

data.iloc[:,0:10].plot(figsize=(12, 8))
plt.legend(loc='best')
plt.show()

图片描述

下一步对全部股票的涨跌幅值进行排序,如下所示:

for index, row in data.iterrows():
    df = pd.DataFrame(row.sort_values(ascending=False))

排序完成后我们可以得到每一天的涨幅排名,如下所示:

"""
       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
"""

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

# 构建一个以时间——收益率/RPS/股票名称的DataFrame空表
df_new = pd.DataFrame(np.NaN, columns = ['pct','name','rps'], index = rps_period_120.keys())
# 按时间汇集每日排名第一的数据
for date in df_new.index:
    rps_df = rps_period_120[date]
    df_new.loc[date, 'pct'] = rps_df.loc[1, 'pct']
    df_new.loc[date, 'name'] = rps_df.loc[1, 'name']
    df_new.loc[date, 'rps'] = rps_df.loc[1, 'rps']

"""
               pct  name   rps
20190703  0.524483  平安银行  95.0
20190704  0.507543  平安银行  95.0
20190705  0.427692  平安银行  95.0
20190708  0.395277  平安银行  95.0
20190709  0.406832  平安银行  95.0
...            ...   ...   ...
20191225  0.501892   飞亚达  95.0
20191226  0.480488   深科技  95.0
20191227  0.529915   深科技  95.0
20191230  0.529268   深科技  95.0
20191231  0.553571   深科技  95.0

[124 rows x 3 columns]

"""

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

关于完整代码可以加入专栏交流群获取。更多的量化交易内容欢迎大家订阅专栏阅读!!

点击查看更多内容
5人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消