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

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)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 5
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值