多因子分析
作者:北大小菜籽 原文鏈接:Quartz 1.x - 因子分析模板
本篇給出了一個分析因子分布情況、Rank IC序列、分位組合表現、分行業分位組合表現的模板,希望通過這一流程大體認識因子的基本特徵、以及因子生成的α策略是否穩定和有效。
因子分析模板
- 優礦的因子庫中提供了400多個因子,大概可以分為估值與市值類因子、償債能力和資本結構類因子、分析師預期類因子、均線型因子、成交量型因子、成長能力類因子、每股指標因子、現金流指標因子、盈利能力和收益質量類因子、能量型因子、營運能力類因子、超買超賣型因子、趨勢型因子這13類。
pure αlpha 我所欲也,省事亦我所欲也。想要省事地構造α策略,從200多個因子中找出有效因子,一個合適的因子分析模板就顯得不可或缺。最理想的狀態莫過於此:輸入一個所關心的因子的名字,模板乖乖報出因子的基本信息、行業分布、歷史表現、(在某時段)是否能提供α...
- 這裡我做了一個嘗試,建立factorAnalyseMachine類,力圖採用一種模板化的方式讓人儘快認識一個因子。
分析流程
- 給定因子名稱、日期、股票池、時間間隔,初始化factorAnalyseMachine類的一個object.
- 類中提供介面:
describeFactor(self, winsor = True, neutral = False, standard = False):給出因子在給定日期和股票池內的分布情況,並給出因子與一個基礎因子組合的相關性。如果winsor為True,則給出的分布情況是對因子進行winsorize去極值化處理之後的,如果neutral為True,則對因子進行行業中性化處理,如果standard為True,則對因子進行標準化;
displayIndustryDist(self, winsor = True, neutral = False, standard = False):給出因子在給定日期中,在各個行業的20%分位數、中位數與80%分位數圖像;
displayCorrTime(self, figsize = (16,6)):給出2016年初以來,指定時間間隔與股票池內因子與股票收益的秩相關係數的時間序列圖像,即因子的Rank IC.
QuantileBt(self, beginQuantile = 0, endQuantile = 0.2, dropNegtive = False, start = "2014-01-01", end = "2016-08-13", benchmark = "HS300", universe = set_universe("A", "2014-01-01"), capital_base = 3000000, freq = "d", refresh_rate = 20, winsor = True, neutral = True, standard = True):
- 1、形成策略:每次調倉時買入因子值位於分位數範圍內的股票
- 2、快速回測,返回回測bt與perf
- 3、如果dropNegtive為True,表明在篩選分位數範圍內股票時,去除因子值為負數的股票(在研究PE等可能為負值的因子時可以用到)
multiQuantileBt(self, group = 5, dropNegtive = False, start = "2014-01-01", end = "2016-08-13", benchmark = "HS300", universe = set_universe("A", "2014-01-01"), capital_base = 3000000, freq = "d", refresh_rate = 20, winsor = True, neutral = True, standard = True):
- 1、根據組數group,確定多個分位點,對於每一段分位點快速回測2中策略
- 2、形成策略:每次調倉時買入因子值位於分位數範圍內的股票
- 3、返回各分位段bt與perf的字典
industryQuantileBt(self, beginQuantile = 0, endQuantile = 0.2, dropNegtive = False, start = "2014-01-01", end = "2016-08-13", benchmark = "HS300", universe = set_universe("A", "2014-01-01"), capital_base = 3000000, freq = "d", refresh_rate = 20, winsor = True, neutral = True, standard = True):
- 與QuantileBt類似,不過篩選股票時是在各個行業內篩選因子值位於指定分位點內的股票
industryMultiQuantileBt(self, group = 5, dropNegtive = False, start = "2014-01-01", end = "2016-08-13", benchmark = "HS300", universe = set_universe("A", "2014-01-01"), capital_base = 3000000, freq = "d", refresh_rate = 20, winsor = True, neutral = True, standard = True):
- 與industryMultiQuantileBt類似,不過篩選股票時是在各個行業內篩選因子值位於指定分位點內的股票
示例 - ROA
以ROA因子為例展示模板(點擊查看原文代碼)
初始化ROA因子分析類,默認日期為兩個工作日前,默認股票池為兩個工作日前的全A股,默認時間間隔10工作日。
- 給出ROA在A股中分布情況以及與基礎因子池的相關性情況:在A股中有少數公司ROA值為負,其餘公司ROA值基本顯示冪律分布特點;ROA與5年收益增長率(EGRO)、基本每股收益(EPS)等因子有顯著正相關關係。
給出因子在不同行業分布情況:傳媒行業ROA值相對最高,鋼鐵、採掘行業ROA值最低。這也給我們一些提示,在全A股中選ROA比較大的股票可能會對傳媒、醫藥生物等行業有較大的暴露度。
當然,優礦的老爺們對行業分布不均的情況也提供了黑科技 —— neutralize. 下圖提供了neutralize後因子的分布情況,可見因子在各個行業的中位數基本都被標準化到0附近,分布也大致對稱,之後的分位數選股回測中,也可以利用neutralize避免行業集中。進一步,也可以用standardize再對因子進行正態化處理。ROA因子Rank IC隨時間變化情況如下圖所示:可見,因子與股價之間的相關性並不穩定,近期有負相關的表現。
從經濟的意義上看,ROA越大公司的股票越有持有價值,因此考慮持有ROA最高20%股票的策略:可見策略比HS300組合表現略強,α為17.5%,但最大回撤較高,表現不夠穩定。
選股前可以利用通聯RDP中winsorize、neutralize、standardize方法預處理因子值。
接下來考慮ROA在不同分位組別的股票組合表現,分為5個組別:
可見ROA最高的股票有明顯較好的表現
序關係不夠穩定,ROA最低的組合也有較好表現
2016年以來ROA最高組合相對HS300表現不錯,對沖後年化收益58.7%,最大回撤8.1%,波動率23.4%
上面的回歸中使用了原本的neutralize方法解決可能的行業集中問題,同樣,也可以考慮直接從不同行業選股來解決這一問題。
考慮分別在不同行業中選取相應分位數股票進行回測,這樣更能體現因子本身的有效性。
可見選取各行業內ROA值最大20%的股票這一策略從2016年來相對HS300表現較差,相對收益為負。
再考慮不同行業內ROA各分位水平股票組合的表現:
ROA低的股票組合表現反而更好
分位數組合表現的序關係混亂
這表明ROA可能並不是穩定的α因子
本篇給出了一個分析因子分布情況、Rank IC序列、分位組合表現、分行業分位組合表現的模板,希望通過這一流程大體認識因子的基本特徵、以及因子生成的α策略是否穩定和有效。
為了讓模板更加強大,希望之後能引入更多功能,包括但不限於:
- 加入因子打分體系,方便不同因子之間對比:在某時段,因子的行業均衡分(也可以各行業分開)、回測表現分(超額收益、最大回撤、波動性)、Rank IC穩定分、分位組合序關係穩定分
- 分析模板應該適應組合加權因子、甚至自定義因子
- 與歸因模塊融合,進一步剖析因子分位數組合的回測表現
推薦閱讀:
※【史上最詳細】WorldQuant Alpha 101 因子系列 #002 研究
※PonderDNC處理高頻長時間序列模型簡介
※已有python基礎想學習量化。要配新電腦了,請問該用什麼配置?
※混沌價值二號凈值從9月30日狂跌不止,這是動用了多大的頭寸做什麼品種才會跌成這樣??