多因子模型 —— 因子正交化處理

Why do this?

傳統的多因子模型處理共線性的方法,如IC加權、IR加權,ICIR加權等,都以IC值爲基礎確定各因子在模型中的權重。而IC是當期因子暴露與下一期收益間的相關係數。

傳統方法的缺陷是:如果因子間存在較強的相關性,通過上述加權方式,最終會導致因子對於某種風格的因子重複暴露。使得整個組合的表現嚴重偏向於該因子,削弱其他因子的效果。

具體來說,當因子表現好時,組合會獲得更高的超額收益,當因子表現不好時,會出現更大幅的回撤。

這個時候,便需要採取因子正交處理的方式解決此問題。

What is 正交化?

正交化目的是消除因子間的相關性,並保持因子對於收益的解釋度不變。

How?

1.import package

from atrader import *
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import math
import statsmodels.api as sm
import datetime as dt
import scipy.stats as stats
import seaborn as sns

2.因子標準化

# Z-Score標準化
def standardize_z(dt):
    mean = dt.mean()     #  截面數據均值
    std = dt.std()       #  截面數據標準差
    return (dt - mean)/std

# 獲取截面因子數據,單日多標的多因子
names = ['REVS60','REVS120','BIAS60','CCI20','PVT','MA10Close','DEA','RC20','RSTR63','DDI']
factors = get_factor_by_day(factor_list= names, target_list=list(get_code_list('hs300').code), date='2019-05-31')
factors = factors.set_index('code').fillna(0)

3. 計算過渡矩陣

factors_standardize = standardize_z(factors)   # 標準化
M = (factors_standardize.shape[0]-1)* np.cov(factors_standardize.T.astype(float))   # 矩陣M

D,U = np.linalg.eig(M)  # 獲取特徵值和特徵向量
U = np.mat(U)           # 轉換爲np中的矩陣
d = np.mat(np.diag(D**(-0.5)))  # 對特徵根元素開(-0.5)指數
S = U * d * U.T         # 獲取過度矩陣S

4.獲取對稱正交矩陣

factors_orthogonal_mat = np.mat(factors_standardize) * S   # 獲取對稱正交矩陣
factors_orthogonal= pd.DataFrame(factors_orthogonal_mat,columns = names,index=factors_standardize.index)   # 矩陣轉爲dataframe

5.正交化前後因子相關性檢驗

# 因子相關性
F_o = factors_orthogonal.fillna(0).corr()    #  正交化後的因子相關性
F = factors.fillna(0).corr()                 #  正交化前的因子相關性


# 相關性畫圖
fig = plt.figure()
plt.subplots(figsize=(8, 6.4))  # 設置畫面大小
sns.heatmap(F, annot=True, vmax=1, vmin=-1, square=True, cmap="CMRmap_r",)
plt.show()
plt.subplots(figsize=(8, 6.4))  # 設置畫面大小
sns.heatmap(F_o, annot=True, vmax=1, vmin=-1, square=True, cmap="CMRmap_r",)
plt.show()

6.正交化前後因子相關性

# 正交化前後的因子相關性
corr = list()
for i in range(factors.shape[1]):
    c = factors_standardize.iloc[:,i].astype(float).corr(factors_orthogonal.iloc[:,i].astype(float))
    corr.append(c)     # 獲取正交前後因子的相關性
corr_df = pd.DataFrame(np.asarray(corr).T,index=names,columns=['corr'])  # 轉爲DataFrame
corr_mean = corr_df.mean()
print(corr_df)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章