多因子选股模型 —— 因子间相关性检验和等权因子法

1. import package  and download data

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

# 获取因子数据
# 单日多标的多因子
# 4个月的动量类因子
names = ['REVS60','REVS120','BIAS60','CCI20','PVT','MA10Close','DEA','RC20','RSTR63','DDI']

factors1 = get_factor_by_day(factor_list= names, target_list=list(get_code_list('hs300',date='2019-02-01').code), date='2019-02-28')

factors2 = get_factor_by_day(factor_list= names, target_list=list(get_code_list('hs300',date='2019-02-01').code), date='2019-03-29')

factors3 = get_factor_by_day(factor_list= names, target_list=list(get_code_list('hs300',date='2019-02-01').code), date='2019-04-30')

factors4 = get_factor_by_day(factor_list= names, target_list=list(get_code_list('hs300',date='2019-02-01').code), date='2019-05-31')

2. factors preprocess

# MAD:中位数去极值
def extreme_MAD(dt,n = 5.2):
    median = dt.quantile(0.5)   # 找出中位数
    new_median = (abs((dt - median)).quantile(0.5))   # 偏差值的中位数
    dt_up = median + n*new_median    # 上限
    dt_down = median - n*new_median  # 下限
    return dt.clip(dt_down, dt_up, axis=1)    # 超出上下限的值,赋值为上下限

# Z值标准化
def standardize_z(dt):
    mean = dt.mean()     #  截面数据均值
    std = dt.std()       #  截面数据标准差
    return (dt - mean)/std

# 行业中性化
shenwan_industry = {
'SWNLMY1':'sse.801010',
'SWCJ1':'sse.801020',
'SWHG1':'sse.801030',
'SWGT1':'sse.801040',
'SWYSJS1':'sse.801050',
'SWDZ1':'sse.801080',
'SWJYDQ1':'sse.801110',
'SWSPCL1':'sse.801120',
'SWFZFZ1':'sse.801130',
'SWQGZZ1':'sse.801140',
'SWYYSW1':'sse.801150',
'SWGYSY1':'sse.801160',
'SWJTYS1':'sse.801170',
'SWFDC1':'sse.801180',
'SWSYMY1':'sse.801200',
'SWXXFW1':'sse.801210',
'SWZH1':'sse.801230',
'SWJZCL1':'sse.801710',
'SWJZZS1':'sse.801720',
'SWDQSB1':'sse.801730',
'SWGFJG1':'sse.801740',
'SWJSJ1':'sse.801750',
'SWCM1':'sse.801760',
'SWTX1':'sse.801770',
'SWYH1':'sse.801780',
'SWFYJR1':'sse.801790',
'SWQC1':'sse.801880',
'SWJXSB1':'sse.801890'
}

# 构造行业哑变量矩阵
def industry_exposure(target_idx):
    # 构建DataFrame,存储行业哑变量
    df = pd.DataFrame(index = [x.lower() for x in target_idx],columns = shenwan_industry.keys())
    for m in df.columns:        # 遍历每个行业
        # 行标签集合和某个行业成分股集合的交集
        temp = list(set(df.index).intersection(set(get_code_list(m).code.tolist())))
        df.loc[temp, m] = 1      # 将交集的股票在这个行业中赋值为1
    return df.fillna(0)         # 将 NaN 赋值为0

# 需要传入单个因子值和总市值
def neutralization(factor,MktValue,industry = True):
  Y = factor.fillna(0)
  df = pd.DataFrame(index = Y.index, columns = Y.columns)    # 构建输出矩阵
  for i in range(Y.shape[1]):    # 遍历每一天的截面数据
      if type(MktValue) == pd.DataFrame:
          lnMktValue = MktValue.iloc[:,i].apply(lambda x:math.log(x))   # 市值对数化
          lnMktValue = lnMktValue.fillna(0)
          if industry:              # 行业、市值
              dummy_industry = industry_exposure(Y.index.tolist())
              X = pd.concat([lnMktValue,dummy_industry],axis = 1,sort = False)  # 市值与行业合并
          else:                     # 仅市值
              X = lnMktValue
      elif industry:              # 仅行业
          dummy_industry = industry_exposure(factor.index.tolist())
          X = dummy_industry
      # X = sm.add_constant(X)
      result = sm.OLS(Y.iloc[:,i].astype(float),X.astype(float)).fit()   # 线性回归
      df.iloc[:,i] = result.resid  # 每日的截面数据存储到df中
  return df

3. corr(mean) test

# 计算因子的相关系数矩阵函数
def factor_corr(factors):
    factors = factors.set_index('code')
    factors_process = standardize_z(extreme_MAD(factors.fillna(0)))
    result = factors_process.fillna(0).corr()
    return result

# 获取相关系数矩阵
factors_corr1 = factor_corr(factors1)
factors_corr2 = factor_corr(factors2)
factors_corr3 = factor_corr(factors3)
factors_corr4 = factor_corr(factors4)
factors_corr = (factors_corr1+factors_corr2+factors_corr3+factors_corr4).div(4)  # 矩阵均值检验

# 相关系数检验
abs(factors_corr).mean()
abs(factors_corr).median()

4. corr hot map plot

# 画图二
fig = plt.figure()
plt.subplots(figsize=(8, 6.4))  # 设置画面大小
sns.heatmap(factors_corr, annot=True, vmax=1, vmin=-1, square=True, cmap="CMRmap_r",)
plt.show()

5. factors equal combine

# 因子合成
# 等权法
corrnames = ['REVS60','REVS120','BIAS60','CCI20','MA10Close','DEA','RC20','DDI']
collinear_factors = factors4.loc[:,corrnames]         # 共线的因子矩阵
composite_factor = collinear_factors.mul(1/len(corrnames)).sum(axis=1)
print(composite_factor)

  • 1
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
多因子选股模型是使用多个因子来评估股票的价值和投资潜力,并根据因子重进行排名和选择股票。下面是一个使用Python编写的多因子选股模型公式的示例: 1. 收集股票数据:从财经网站或数据供应商获取股票的基本信息、财务数据和市场数据等。 2. 定义因子:选择适合的因子来评估和筛选股票。常用的因子包括市盈率、市净率、市销率、股息率、ROE(净资产收益率)等。 3. 因子标准化:对每个因子进行标准化处理,使得因子在同一数量级上进行比较。标准化可以使用z-score标准化,将因子值转化为标准正态分布。 4. 因子:为每个因子分配重,根据因子的重要性和相关程度来确定重。重可以是固定的,也可以通过回归分析等方得出。 5. 构建综合因子:将各个因子乘以相应的重,并将它们相加得到一个综合因子值。 6. 排序和选股:根据综合因子值对股票进行排序,从高到低选取前几名股票作为投资目标。也可以根据各个因子重分别进行排序,再根据一定规则进行加得到最终的排序结果。 7. 风险控制和组合优化:在选股过程中,可以加入一些风险控制机制,如设置止损点和风险控制指标,以避免不可预测的风险。同时,还可以进行组合优化,考虑不同股票之相关性重分配,以达到更好的风险收益平衡。 以上是一个简单的多因子选股模型的Python公式示例,实际应用中可能还涉及更多的细节和调整。具体的公式和代码可能会根据需求和假设的不同而有所变化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值