欢迎大家订阅《教你用 Python 进阶量化交易》专栏!为了能够提供给大家更轻松的学习过程,笔者在专栏内容之外已陆续推出一些手记来辅助同学们学习本专栏内容,目前推出的扩展篇链接如下:
第一篇《管理概率==理性交易》
第二篇《线性回归拟合股价沉浮》
第三篇《最大回撤评价策略风险》
第四篇《寻找最优化策略参数》
第五篇《标记A股市场涨跌周期》
第六篇《Tushare Pro接口介绍》
第七篇《装饰器计算代码时间》
第八篇《矢量化计算KDJ指标》
第九篇《移植量化交易小工具》
第十篇《统计学预测随机漫步》
第十一篇《TA-Lib库扩展介绍》
第十二篇《股票分笔数据跨周期处理》
第十三篇《TA-Lib库量价指标分析》
第十四篇《ATR在仓位管理的应用》
第十五篇《扒一扒量化回测常见陷阱》
第十六篇《量化回测工具更新版1》
第十七篇《GUI控件在回测工具上的添加》
第十八篇《文本框显示Tushare股票信息》
第十九篇《建立基于TA-Lib的指标库》
第二十篇《爬虫抓取股票论坛帖子》
为了将专栏中分散的知识点贯穿起来,笔者在专栏的末尾小节《制作自己的量化交易工具》中分享了早期制作的一个简易版量化交易小工具,希望大家能够通过调试代码的方式掌握相关的知识。
目前在场外篇第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指标只是第一步,下一节我们会针对这些数据展开可视化选股分析。
关于完整代码可以加入专栏交流群获取。更多的量化交易内容欢迎大家订阅专栏阅读!!
共同学习,写下你的评论
评论加载中...
作者其他优质文章