基于随机森林算法的多因子选股方法分析与实现(2,代码实现)
摘要
量化投资中经常听到的“多因子模型”是个什么鬼?因子是影响因素的简称,或简单理解成指标。我们都知道股票收益受到多重因素的影响,比如宏观、行业、流动性、公司基本面、交易情绪等等。所谓“多因子模型”,说白了就是寻找那些对股票收益率最相关的影响因素,使用这些因素(因子或指标)来刻画股票收益并进行选股。
1952年马柯维茨(Markowitz)在The Journal of Finance(金融学最*的学术期刊)上发表了《证券组合选择》论文,开启了现代证券组合管理理论的先河。马柯维茨开创性地引入了均值和方差来定量刻画股票投资的收益和风险(被认为是量化交易策略的鼻祖),建立了确定最佳资产组合的基本模型。其后,越来越多的经济金融学者通过数量化的模型以及周边市场和投资交易问题。夏普(William Sharpe)、林特尔(John Lintner)、特里诺(Jack Treynor)和莫辛(Jan Mossin)分别于1964、1965和1966年在马柯维茨投资组合理论基础上,发展出了资本资产定价模型(CAPM)。该模型不仅提供了评价收益-风险相互转换特征的可运作框架,也为投资组合分析、基金绩效评价提供了重要的理论基础。本文将基于随机森林算法实现多因子的选股策略,既是从N只股票中选择得分最高的前 X%只股票。
数据描述
本文选择的数据是从网上爬取的2783家上市公司的股票数据,具体如下图所示,时间段为2012年-2016年,在每年中随机选择一些2到3个样本数据,这样就构成了具有时间序列的股票数据。选择的因子有:,QDturn,QMretnd,QIdxrtn,CR,PB,PS,ROA,ROE,NSR,NQMret;根据上节(https://haosen.blog.csdn.net/article/details/108719768)介绍的构建数据集的方法,构建本样本数据的标签(将股票池中表现好的个股标为类别 1,而表现不好的标类别0等)。
构建数据标签样本代码:
for i in range(len(data)-1):
if data['NQMret'].iloc[i]>0:
NQMclass2[i] = 1
elif data['NQMret'].iloc[i]<0:
NQMclass2[i] = 0
构建好的一种股票其数据样本类型如图所示:
模型构建
之所以选择随机森林算法进行选股,就是因为利用oob对每个特征,迭代进行,评估分数,然后做一个排序,分数越高,特征越重要,然后利用分数由到到低,进行组合,在看模型是否精度是否发生变化,从而选择最优特征组合。具体参考(https://haosen.blog.csdn.net/article/details/108719768)。因此该模型代码如下:
def class2(ntree=20, train=train,test=test):
clf = RandomForestClassifier(n_jobs=2, oob_score=True, n_estimators=ntree)
clf.fit(train[features], train['NQMclass2'])
return(clf)
clf2 = class2(20)
preds = clf2.predict(test[features])
print(pd.crosstab(test['NQMclass2'], preds, rownames=['actual'], colnames=['preds']))
print(clf2.oob_score_)
pd.DataFrame({'features':features,'importance':clf2.feature_importances_}).to_csv('features.csv') #返回特征值权值
print(clf2.predict(test[features])[:10],clf2.predict_proba(test[features])[:10])
k = []
numb = []
for i in range(30):
numb.append(i+1)
clf2 = class2(i+1)
k.append(clf2.oob_score_)
ntree = pd.DataFrame({'ntree':numb,'oob':k})
ntree.to_csv('ntree.csv')
构建backtest测试收益率、夏普率等,代码如下:
def backtestor(self, period, numberofcom):
market = []
ret = []
ret_forecast = []
date = []
timeline = self.timelist[int(np.where(self.timelist==period[0])[0]):int(np.where(
self.timelist==period[1])[0]+1)]
for month in timeline:
r,r_f = backtest.profit(self, month, numberofcom)
m = backtest.marketprofit(self, month)
ret.append(r)
ret_forecast.append(r_f)
market.append(m)
date.append(month)
def cummulti(ret):#累积收益率
cumret = []
c = 1
for i in ret:
c = c*(i+1)
cumret.append(c)
return(cumret)
def yearret(ret):# 年化收益率
# print(ret)
# print(ret.shape)
year_ret = (ret[-1] / ret[0] - 1) / 5
# print(year_ret)
return year_ret
def yearsigma(ret,year_ret):# 夏普比率
ret = np.array(ret)
year_sigma = ret.std() / 5 # 年化收益标准差
# 无风险设为4%
sharpe = (year_ret - 0.04) / year_sigma
return (sharpe)
def Maxdrawdown(ret):# 最大回撤
down_list = []
ret=np.array(ret)
for i in range(1, len(ret)):
down = (1 - ret[i] / ret[:i]).max()
down_list.append(down)
return (max(down_list))
结果分析与展示
该模型选择靠前的15家公司,从2014年至2016年的平均年化收益率为15.08%,市场指数收益率为12.32%。选择出的公司如下:
结论
本文基于随机森林算法的多因子选股模型在回测期2014年到2016年内取得的年化收益为15.08%,大幅度领先市场基准(沪深300与中证500),可证明该选股模型具有较好的选股性能。,本文构建的动态学习模型体现出其时效性,在一定程度上能反映市场的变化。
多因子量化选股本质是基于历史数据的统计分析,通过寻找那些与股票收益率最相关的因子,并基于套利定价理论(APT),将多个影响因子进行组合,构建综合选股指标来筛选股票。任何一个多因子选股模型具有一定的时效性、风险性,需要使用者根据市场情况进行调整和更新,这是多因子选股策略存在的不足。多因子选股模型作为一种量化投资选股策略,最大的优势在于其结果是根据客观的数据和完整的模型得出的,可以避免交易者个人主观意念的干扰,具有一定客观性。多因子选股研究的对象主要是因子,因此单因子的回测和有效性检验是整个多因子模型的重要组成部分。但是,本文并没有做相关因子的分析与选择。大家可自行尝试。联系QQ:525894654
参考
https://baike.baidu.com/item/%E9%9A%8F%E6%9C%BA%E6%A3%AE%E6%9E%97/1974765?fr=aladdin
华泰证券研报《多因子选股策略——数量化选股策略之十二》