共计 1883 个字符,预计需要花费 5 分钟才能阅读完成。
多因子模型基础认知
- 因子投资的核心逻辑 :通过多个维度(如估值、动量、质量等)对股票进行综合评分,每个因子代表一种选股逻辑。例如:
- PE(市盈率)因子反映估值水平
- 20 日收益率因子捕捉动量效应
-
ROE 因子衡量盈利质量

-
IC(信息系数)的定义 :因子值与下期收益的秩相关系数,范围 [-1,1]。计算示例:
import scipy.stats as stats ic = stats.spearmanr(factor_rank, future_return_rank)[0]IC>0.05 通常认为因子有效,但需注意 …
-
IC 衰减的典型表现 :因子有效性随时间递减的现象。通过计算不同时间间隔的 IC 值可观察到:
# 计算 T +1,T+5,T+20 日的 IC 值 ic_dict = {'1day': calculate_ic(factor, return_1d), '5day': calculate_ic(factor, return_5d), '20day': calculate_ic(factor, return_20d) }
动态权重技术详解
静态权重的局限性
- 固定权重无法适应因子有效性的变化
- 忽略市场环境对因子表现的调节作用
- 案例:2020 年疫情期间质量因子突然失效
滚动窗口计算方法
-
核心参数设置 :
WINDOW_SIZE = 252 # 1 年交易日的滚动窗口 HALF_LIFE = 63 # 半衰期参数(季度调整) -
权重计算逻辑 (完整代码见附录):
- 计算窗口内各因子 IC 均值
-
根据半衰期公式调整近期 IC 权重:
decay_weight = np.exp(-np.arange(WINDOW_SIZE)/HALF_LIFE) weighted_ic = (ic_series * decay_weight).sum() -
动态调整触发机制 :
- 设置权重调整阈值(如 5% 变化)
- 监控因子 IC 的 20 日移动标准差
过拟合防范体系
分层抽样验证
- 实施步骤 :
- 按市值、行业分层抽样构建测试集
-
保持训练集与测试集分布一致
-
Python 实现 :
from sklearn.model_selection import StratifiedShuffleSplit sss = StratifiedShuffleSplit(n_splits=5, test_size=0.3, random_state=42) for train_idx, test_idx in sss.split(X, industry_labels): X_train, X_test = X.iloc[train_idx], X.iloc[test_idx]
样本外测试流程
- 严格划分回测区间(建议 7:3 比例)
- 禁止在样本外数据上做任何参数优化
- 特别警惕 2015 年、2018 年极端行情
性能优化实践
计算效率对比
| 调仓周期 | 100 因子计算耗时 | 内存占用 |
|---|---|---|
| 日频 | 45min | 8GB |
| 周频 | 12min | 3GB |
| 月频 | 3min | 1GB |
因子相关性处理
-
聚类降维方法 :
from sklearn.cluster import KMeans kmeans = KMeans(n_clusters=10).fit(factor_corr_matrix) cluster_labels = kmeans.labels_ -
正交化处理 :
from statsmodels.regression.linear_model import OLS residual = OLS(factor_new, factor_base).fit().resid
关键问题思考
- 因子数量与 IC 稳定性 :
- 通过 Bootstrap 方法评估 IC 估计误差
-
建议初期聚焦 5 - 8 个核心因子
-
非线性调整可行性 :
- 尝试 Sigmoid 函数调整权重变化速率
-
市场波动率作为调节参数
-
Regime 切换应对 :
- 建立市场状态识别模型(HMM/SVM)
- 准备不同市况下的权重预案
附录:核心代码
# 因子标准化处理(行业市值中性化)def standardize_factor(factor):
"""
factor: DataFrame(index=date, columns=stock)
返回:行业市值调整后的因子值
"""
# 行业哑变量处理
industry_dummy = pd.get_dummies(stock_industry)
# 市值对数处理
log_mktcap = np.log(market_cap)
# 回归去除行业市值影响
for date in factor.index:
X = pd.concat([industry_dummy, log_mktcap], axis=1)
model = sm.OLS(factor.loc[date], X).fit()
factor.loc[date] = model.resid
return factor
(完整代码文件见 GitHub 仓库链接)
正文完

