为了应付一个考试,停了一个多月。现在学习继续。这次要实现的是多因子选股。即通过多个因子来在股票池中选择一个或数个股票,以期获得高于市场平均水平的收益。属于量化选股的一种。
主要有打分法和回归法两种。先实现最简单的打分法吧。
由于我使用的是tushare获取数据,先看看能获取哪些因子。
用ts.get_stock_basics(),结果是这样的:
pe是市盈率,outstanding是流通股本,totals是总股本,totalAssets是总资产,liquidAssets是流动资产,fixedAssets是固定资产,reversved是公积金,esp每股收益,bvps每股净资,pb市净率,timeToMarket上市日期,undp未分利润,rev收入同比,profit利润同比,gpr毛利润,npr净利润,holders,股东人数。
还有获取其它数据的函数,第一次弄,先用这个吧。
首先排除一些股票:
①上市不满2年的股票。
②ST的股票
③亏损的股票。
1 | # coding:utf-8 |
1 | 平均市盈率:138.04 |
画图看看。
1 | # 分析数据 |
图形大多是这样的,长尾形的。值越高的股票越少。
现在来找因子了,我就主观定义吧:
选取市盈率、每股收益、每股净资产、市净率、净利润这几个指标,其中市盈率是越小越好,其它都是越大越好。因此设计的评分公式为:
评分 = -1×市盈率/平均市盈率 + 每股收益/平均每股收益 + 每股净资产/平均每股净资产 + 市净率/平均每股市净率 + 净利润/平均每股净利润
即把每个值都与所有值的平均值相除最后再相加。
1 | # 计算评分指标 |
提取评分最高的10个股票,结果如下:
1 | Int64Index([661, 600695, 603301, 2582, 600620, 603444, 600061, 617, 2069, |
发现一个问题:661,2582这些是啥?唉,在一开始的筛选的代码里再加一条,排除代码小于100000的。
1 | Int64Index([600895, 600621, 600674, 600685, 600695, 603301, 600620, 603444, |
现在就对了!
接下来就用这十只股票来回测,策略就是买入持有。
1 | ['张江高科' '华鑫股份' '川投能源' '中船防务' '绿庭投 资' '振德医疗' '天宸股份' '吉比特' '国投资本' '贵州茅台'] ['600895', '600621', '600674', '600685', '600695', '603301', '600620', '603444', '600061', '600519'] |
就这十只股票。
下面是回测代码:
1 | # 交易策略类,一开始买入然后持有。 |
结果
结果还不错,年化收益率15.8%,最大回撤达41.6%。夏普值0.44。有个问题,我用的因子数据应该是最近的,而回测时间是2018-2020年的,也就是用了未来数据。原因是我不知道怎么获取历史的因子数据,先掌握方法吧。还有画的图很烂,我再研究下。
代码地址还是: https://github.com/zwdnet/MyQuant/tree/master/47
策略文件为facts.py。
我发文章的三个地方,欢迎大家在朋友圈等地方分享,欢迎点“在看”。
我的个人博客地址:https://zwdnet.github.io
我的知乎文章地址: https://www.zhihu.com/people/zhao-you-min/posts
我的微信个人订阅号:赵瑜敏的口腔医学学习园地