什么是多因子量化選股模型?
》主要介紹了多因子模型產(chǎn)生的理論背景、基本原理和實(shí)現(xiàn)步驟,而《【手把手教你】Python量化Fama-French三因子模型
》則對(duì)國內(nèi)A股市場(chǎng)的三因子模型進(jìn)行了實(shí)證分析。多因子量化模型研究的對(duì)象主要是因子,因此單因子的回測(cè)和有效性檢驗(yàn)是整個(gè)多因子模型的重要組成部分。本文結(jié)合Python開源包Alphalens,以A股市場(chǎng)真實(shí)場(chǎng)景數(shù)據(jù),手把手教你對(duì)單因子進(jìn)行量化回測(cè)。Alphalens是Quantopian公司(美帝最大的量化回測(cè)平臺(tái)之一,國內(nèi)幾個(gè)基本上都是仿他們家的)三大知名Python開源包之一,其他兩個(gè)分別是Zipline(策略回測(cè),一直沒安裝成功)和Pyfolio(策略分析)。Alphalens主要提供因子收益分析、因子IC分析、因子換手分析和事件研究等回測(cè)框架,由于簡單易上手和科學(xué)穩(wěn)定等優(yōu)點(diǎn),是量化分析師最常用的回測(cè)工具包之一。#先引入后面可能用到的包(package)
import?alphalens?#使用pip安裝即可
import?pandas?as?pd??
import?numpy?as?np
import?matplotlib.pyplot?as?plt
%matplotlib?inline???
#正常顯示畫圖時(shí)出現(xiàn)的中文和負(fù)號(hào)
from?pylab?import?mpl
mpl.rcParams['font.sans-serif']=['SimHei']
mpl.rcParams['axes.unicode_minus']=False
#還是使用tushare獲取數(shù)據(jù)
import?tushare?as?ts
token='輸入token'
pro=ts.pro_api(token)
#獲取當(dāng)前交易的股票代碼和名稱
def?get_code():
????df?=?pro.stock_basic(exchange='',?list_status='L')
????#剔除2017年以后上市的新股次新股
????df=df[df['list_date'].apply(int).values<20170101]
????#剔除st股
????df=df[-df['name'].apply(lambda?x:x.startswith('*ST'))]
????codes=df.ts_code.values
????return?codes?
df=pro.daily_basic(ts_code=get_code()[0],start_date='20110101')
for?code?in?get_code()[1:]:
????df1=pro.daily_basic(ts_code=code,start_date='20110101')
????df=pd.concat([df,df1])
df_new=df.loc[:,['ts_code','trade_date','close','pe_ttm']]
df_new.loc[:,'trade_date']=pd.to_datetime(df_new.trade_date)
#設(shè)定雙重重索引的數(shù)據(jù)格式
df_new=df_new.set_index(['trade_date','ts_code'])
#根據(jù)第一索引排序
df_new=df_new.sort_index()
#查看數(shù)據(jù)前幾行
df_new.head() df_new.describe().round(2)#對(duì)數(shù)據(jù)進(jìn)行縮尾處理,并進(jìn)行標(biāo)準(zhǔn)化def?winsor_data(data):
????q=data.quantile([0.02,0.98])
????data[data<q.iloc[0]]=q.iloc[0]
????data[data>q.iloc[1]]=q.iloc[1]
????return?data
#數(shù)據(jù)標(biāo)準(zhǔn)化
def?MaxMinNormal(data):
????"""[0,1]?normaliaztion"""
????x?=?(data?-?data.min())?/?(data.max()?-?data.min())
????return?x
factor=df_new['pe_ttm'].groupby('trade_date').apply(winsor_data)
factor_new=factor.groupby('trade_date').apply(MaxMinNormal)
factor_new.hist(figsize=(12,6),bins=20)

prices=df_new['close'].unstack()
prices.head()
data=alphalens.utils.get_clean_factor_and_forward_returns(factor_new,prices,
??????????????????????????????????????????????????????????quantiles=10,periods=(10,20,60))
data.head()
單因子的收益率分析主要圍繞10、20、60日(可自己設(shè)定)調(diào)倉周期,將因子數(shù)據(jù)從小到大排列,分為10個(gè)分位數(shù)進(jìn)行回測(cè),一行代碼便可實(shí)現(xiàn),但函數(shù)名稱實(shí)在太冗長了。第一張表報(bào)告了不同調(diào)倉期的alpha、beta、高分位(top quantile)和低分位(bottom quantile)的收益情況。柱狀圖清晰地顯示出該因子(市盈率)隨著分位的提高收益由正轉(zhuǎn)負(fù),可見市盈率因子與股票收益存在一定的反向關(guān)系,即市盈率越小,未來收益越高,與理論和直覺基本一致。小提琴圖是多收益率的分布,60日調(diào)倉的收益更加集中,方差更小,收益率更加可信。 ?由于對(duì)因子進(jìn)行了歸一化化處理,因此可以以因子值為權(quán)重構(gòu)建一個(gè)全市場(chǎng)的股票組合進(jìn)行回測(cè)。對(duì)于cumulative return by quantile的評(píng)價(jià)標(biāo)準(zhǔn)是累計(jì)收益率是否發(fā)散,越發(fā)散越好,說明因子的區(qū)分度越高,60天調(diào)倉期出現(xiàn)了明顯的發(fā)散。好的信號(hào):波動(dòng)小,在某一個(gè)方向的占比處于絕對(duì)地位,如大部分的Top minus bottom都是正的。
alphalens.tears.create_returns_tear_sheet(data)信息分析說白了是考察IC和IR指標(biāo)。IC全稱為Information Coefficient, 即信息系數(shù),代表因子預(yù)測(cè)股票收益的能力。其原理是通過計(jì)算全部股票在調(diào)倉周期期初排名和調(diào)倉周期期末收益排名的線性相關(guān)度(correlation)。 不難理解,IC絕對(duì)值越大的因子,選股能力越強(qiáng)。IC的值在[-1,1]區(qū)間內(nèi),最大值為1,表示該因子100%準(zhǔn)確,對(duì)應(yīng)的是排名分最高的股票,選出來的股票在下個(gè)調(diào)倉周期中,漲幅最大;相反,如果IC為-1,則代表排名最高的股票,在下個(gè)調(diào)倉周期中,漲幅最大,是一個(gè)完全反向指標(biāo),也是非常有意義的,使用的時(shí)候反向操作即可。一般而言,當(dāng)IC的絕對(duì)值<0.05時(shí),說明該因子對(duì)于的股票沒有任何預(yù)測(cè)能力或較差,當(dāng)IC絕對(duì)值>0.05時(shí),因子選股能力有一定的意義,當(dāng)IC大于0.5時(shí)因子穩(wěn)定獲取超額收益能力較強(qiáng)。
IR全稱是Information Ratio,等于IC的多周期均值/IC的標(biāo)準(zhǔn)差,或等于超額收益均值/超額收益標(biāo)準(zhǔn)差,代表因子獲取穩(wěn)定Alpha的能力。 整個(gè)回測(cè)時(shí)段由多個(gè)調(diào)倉期組成,每一個(gè)周期都會(huì)計(jì)算出一根不同的IC值,IR等于多個(gè)調(diào)倉周期的IC均值除以IC的標(biāo)準(zhǔn)差。因此IR兼顧了因子的選股能力和因子選股能力的穩(wěn)定性,IR值越大越好。
information analysis表給出了每個(gè)調(diào)倉周期下,IC的均值、方差以及t統(tǒng)計(jì)量,還有偏度、峰度以及年化的IR。因子信息分析好的評(píng)判標(biāo)準(zhǔn)是:IC的均值較高,方差小,而t統(tǒng)計(jì)量大(一般大于2)或p-value?。ㄒ话阈∮?%)。從結(jié)果上看,PE因子的IC均值都比較小,看來不是很理想的選股因子偏度和峰度主要考察和正態(tài)分布的偏離程度,主要用于分析小概率事件的影響。
alphalens.tears.create_information_tear_sheet(data)Q-Q plot圖是查看樣本分布與正態(tài)分布的對(duì)比情況,如果滿足正態(tài)分布,Q-Q圖上的點(diǎn)應(yīng)該在y=x上。雖然有些IC的取值挺大的,但是尾部比較大,均值大是由于極度的尖峰和右偏造成的。還需具體考察IC的分布來決定一個(gè)因子的預(yù)測(cè)能力是不是可靠。
熱力圖提供了不同時(shí)間段因子的預(yù)測(cè)能力表現(xiàn),有利于進(jìn)行因子的情景分析。通過熱力圖我們可以輕易識(shí)別哪些時(shí)間段IC值比較好,哪些時(shí)間段IC比較差,有沒有突發(fā)的情況,然后可以對(duì)此進(jìn)行情景分析。
ic=alphalens.performance.mean_information_coefficient(data,by_time='1y')
from?pyecharts?import?Bar
attr=ic.index.strftime('%Y')
v1=list(ic['10D'].round(2))
v2=list(ic['20D'].round(2))
v3=list(ic['60D'].round(2))
bar=Bar('IC均值:2006-2019')
bar.add('10D',attr,v1)
bar.add('20D',attr,v2)
bar.add('60D',attr,v3)
bar
實(shí)際交易是有手續(xù)費(fèi)的,因子對(duì)單因子的回測(cè)還需要考慮換手率的影響,換手率越高說明交易次數(shù)越多,可能產(chǎn)生的手續(xù)費(fèi)越高。如果一個(gè)因子,今天給一個(gè)股票打了很高的分,明天就打很低的分,這將導(dǎo)致對(duì)該股頻繁的買賣,從而造成很高的手續(xù)費(fèi)。所以,因子的換手率分析也是很重要的一個(gè)部分。
還有一個(gè)角度可以查看因子造成的換手率高低,就是因子的自相關(guān)性。如果因子的自相關(guān)性低,那么就一會(huì)兒高,一會(huì)兒低,往往會(huì)造成很大的換手率。而因子的自相關(guān)性高,就不會(huì)有這樣的問題。因子的截面換手率越低,因子的自相關(guān)性越高
alphalens.tears.create_turnover_tear_sheet(data)