下面对上次实现的多因子选股模型进行一些改进。
首先来看评分标准,增加几个系数。
1 | # 计算评分指标 |
也就是为每个因子赋予不同的权重,然后找到最佳的因子权重组合。
专门写一个函数。
1 | # 对不同的因子权重组合进行优化 |
用的最简单的穷举法。
尝试的情况太大时,手机跑了一个多小时,最后termux死了。只能用最少的情况来测试。看来还是得搞个服务器。
尝试用比穷举好的算法,先试一下随机算法,即在解空间内随机生成系数,再比较年化收益率。
代码如下:
1 | # 采用随机算法进行优化 |
解的空间为[1,200),穷举的话,约200^5次尝试。结果为:
看来最重要的指标是市净率。
现在的问题是有没有办法能扩大搜索范围而效率又更高?
先试试多元线性回归吧。为了获取数据,再把上面的随机算法运行一次,记录每次的5个参数,以及相应的回测年化收益率。
运行完结果是这样
画图看看
看图,市盈率的权重与年化收益率无明显相关关系,每股收益,每股净资产,每股利润的权重与年化收益率都是呈负相关,而市净率的权重与年化收率是呈正相关。但在年化收益率0.1-0.2之间有个区域,权重的改变对其无影响。要不要考虑把这些数据给剔除掉?
剔除以后的情况,先用多元线性回归试试。
之前在手机的termux里运行包含sklearn库的程序时,总是提示:
“This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770.”
没有找到解决方法,只能传到服务器或者docker里运行。刚又搜了一下,找到一个解决方案:把sklearn版本退回到0.19.2,
如下:
1 | pip install scikit-learn==0.19.2 |
搞定!现在程序在termux里运行正常了。只是只能单线程执行。
参考了 https://www.jianshu.com/p/dc53be46d172 特此感谢!
1 | # 回归分析 |
结果很差,画图看看。
看图倒还不错。
画散点图看看。
看来还要生成更大的数据集来训练。
用回归的模型选择系数权重再回测一下看看。
1 | # 用线性回归所得模型选择因子权重 |
结果
差别很小的,跟一开始的随机算法相比,这么做优点是不用每组值都进行回测,那个很耗时间的。这样可以增加尝试次数。试试增加到10000次吧。
用了大概10秒钟。
还有个问题,就是是不是每次运行都需要训练模型,能不能保存下来,下次直接用?
用sklearn的joblib即可。
1 | # 保存模型 |
现在就可以把回归模型那里注释掉啦。另外再扩大因子权重的取值范围,到1000看看。
现在差距就比较大了,而且实测下来的年化收益率并没有增加多少,因此还是改回原来的200以内的范围。程序有好多重复的地方,重构一下。然后再运行随机算法,模拟次数多一点,多生成一些数据。
在我的手机上试了两次,基本上模拟超过200次就比较悬了,不知道什么时候就死了。传到诊室电脑上试试。
在电脑上大概每秒钟能回测一次,我用随机权重系数回测了4000次,生成4000组数据。再把数据传回手机进行回归和选股。
数据多了果然好点。
接下来,就用筛选出来的股票池再进行回测,换一个时间范围看看。
1 | # 根据输入的股票池进行回测检验 |
回测10年的数据。
回测十年,结果蛮不错的。
接下来,如果是正儿八经的量化策略研究,就该上实盘了吧?
嘿嘿,再研究下有没有其它方法吧。我在知乎上提问了:https://www.zhihu.com/question/417584064
没人回我……
下次了。
代码地址还是: https://github.com/zwdnet/MyQuant/tree/master/47
策略文件为facts.py。
我发文章的三个地方,欢迎大家在朋友圈等地方分享,欢迎点“在看”。
我的个人博客地址:https://zwdnet.github.io
我的知乎文章地址: https://www.zhihu.com/people/zhao-you-min/posts
我的微信个人订阅号:赵瑜敏的口腔医学学习园地