第四章:因子挖掘基础
因子挖掘,说白了就是量化策略的「找矿」环节。我做了这么多年量化,见过太多人一上来就堆代码、跑回测,结果策略上线就崩。为什么?因为因子没选好,地基就不稳。
今天咱们就聊聊因子到底是什么,怎么分类,以及怎么搭建一个靠谱的单因子测试框架。嗯,这部分内容,我个人觉得是整个量化流程里最容易被低估的一环。
一、什么是因子?
因子,你可以理解成「能解释股票收益的某种特征」。比如市盈率低是不是更容易涨?换手率高是不是代表资金关注?这些特征就是因子。
更学术一点说,因子是资产定价模型中的自变量。经典的Fama-French三因子模型里,市值、账面市值比、市场超额收益就是三个因子。但在公募量化里,我们用的因子要丰富得多。
我习惯把因子比作「选股的筛子」。每个筛子能筛出不同特点的股票,多个筛子叠在一起,就能找到我们想要的标的。
核心要点:因子必须满足三个条件——可量化、可复现、有经济含义。缺一不可。
二、因子的分类
因子分类方式很多,我按最常见的三类来讲:基本面因子、技术面因子、另类因子。
1. 基本面因子
这类因子来自公司财报和经营数据。比如市盈率、市净率、ROE、营收增长率、资产负债率等等。
我在项目中遇到过一个问题:很多人直接用原始财报数据做因子,结果回测效果很好,实盘却一塌糊涂。为什么?因为财报有滞后性。你看到的Q2数据,可能已经是两个月前的了。
所以处理基本面因子时,我建议一定要做「时点对齐」。也就是确保你用的数据,在回测时点上是真实可得的。
| 因子名称 | 计算方式 | 常见方向 |
|---|---|---|
| 市盈率倒数(EP) | 净利润 / 总市值 | 正向(越高越好) |
| ROE | 净利润 / 净资产 | 正向 |
| 营收增长率 | (本期营收 - 上期营收)/ 上期营收 | 正向 |
| 资产负债率 | 总负债 / 总资产 | 负向(越低越好) |
2. 技术面因子
技术面因子来自量价数据。比如动量因子、反转因子、波动率因子、换手率因子等。
这类因子有个特点:更新频率高,每天都能算。但也容易过拟合。我记得有一次,我团队里一个小伙伴发现了一个「神奇」的因子——过去5天涨幅的平方。回测收益高得离谱,但仔细一看,纯粹是数据挖掘出来的噪音。
技术面因子我建议重点关注两个方向:
- 动量/反转:A股市场短期反转效应明显,中期动量也存在
- 波动率:低波动率股票长期有超额收益,这个在A股也成立
小技巧:技术面因子一定要做「滞后处理」。用今天的因子预测明天的收益,而不是用今天的因子解释今天的收益。这个坑我踩过,说出来都是泪。
3. 另类因子
另类因子就是「非传统数据」衍生出来的因子。比如舆情因子、搜索热度、供应链数据、卫星图像等。
公募量化里,另类因子用得越来越多。我见过有人用招聘网站的数据来预测公司业绩——如果一家公司突然大量招人,说明业务在扩张。这个逻辑说得通,但数据清洗的难度也大。
另类因子的核心难点不在因子本身,而在数据获取和清洗。我曾经花了两周时间处理一份舆情数据,最后发现数据源本身就有偏差。嗯,从那以后我养成了一个习惯:先用小样本验证数据质量,再大规模使用。
三、单因子测试框架搭建
因子挖出来了,怎么知道它有没有用?这就需要单因子测试框架。说白了,就是给每个因子「体检」。
我搭建框架的思路是这样的:
- 数据准备:股票池、因子值、收益数据
- 因子处理:去极值、标准化、中性化
- 分组回测:按因子值分组,看各组收益
- 评价指标:IC、IR、分组收益、多空收益
下面是一个简化的单因子测试框架代码示例:
import pandas as pd
import numpy as np
def single_factor_test(factor_df, return_df, groups=10):
"""
单因子测试框架
factor_df: 因子值,index为日期,columns为股票代码
return_df: 收益数据,index为日期,columns为股票代码
"""
results = {}
for date in factor_df.index:
# 获取当日因子值
factor = factor_df.loc[date].dropna()
# 获取次日收益
returns = return_df.shift(-1).loc[date]
# 分组
factor_rank = factor.rank(pct=True)
factor_group = pd.qcut(factor_rank, groups, labels=False)
# 计算各组收益
group_returns = returns.groupby(factor_group).mean()
results[date] = group_returns
result_df = pd.DataFrame(results).T
return result_df
这个框架虽然简单,但核心逻辑都在了。实际项目中,我还会加入:
- 市值中性化处理(防止因子选到大市值股票)
- 行业中性化处理(防止因子选到特定行业)
- 换手率约束(考虑交易成本)
注意:单因子测试最容易犯的错误是「幸存者偏差」。一定要用全样本数据,包括已经退市的股票。否则你的回测结果会虚高,实盘直接打脸。
四、因子测试的核心指标
因子好不好,不能光看收益。我一般看这几个指标:
| 指标 | 含义 | 合格标准 |
|---|---|---|
| IC(信息系数) | 因子值与未来收益的相关系数 | 绝对值 > 0.02 |
| IR(信息比率) | IC均值 / IC标准差 | > 0.5 |
| 分组单调性 | 各组收益是否单调递增/递减 | 单调性明显 |
| 多空收益 | 最高组 - 最低组的收益 | 显著为正 |
我个人最看重的是IR。为什么?因为IC高但波动大,说明因子不稳定,今天有用明天就没用。IR综合考虑了IC的稳定性和大小,更能反映因子的真实质量。
我曾经见过一个因子,IC高达0.08,但IR只有0.2。回测曲线看着漂亮,但实盘三个月就失效了。原因就是IC波动太大,运气成分居多。
五、框架搭建的避坑指南
最后分享几个我踩过的坑:
- 未来函数:我曾经用当天的收盘价计算因子,然后用当天的收益做回测。结果因子和收益天然相关,回测曲线完美,实盘一塌糊涂。记住:因子数据必须滞后于收益数据。
- 过拟合:因子参数不要调太多。比如均线因子,5日均线和10日均线选哪个?都试试,哪个好选哪个。但如果你试了3日、5日、7日、10日、15日...总有一个能拟合出好结果。这就是过拟合。
- 数据质量:因子值出现极端值怎么办?我习惯用MAD法去极值,然后用z-score标准化。不要直接删除极端值,因为极端值可能包含重要信息。
总结一下:因子挖掘不是玄学,是科学。好的因子要有逻辑支撑、有统计显著性、有稳定性。单因子测试框架就是帮你验证这些的工具。别嫌麻烦,这一步做扎实了,后面的策略开发才能事半功倍。
好了,因子挖掘的基础就聊到这儿。记住一句话:因子是策略的基石,框架是验证的工具。这两样东西搞明白了,后面的路就好走了。