4. 因子计算基础:因子定义与分类、因子计算框架、常见因子实现、因子标准化
各位同学,欢迎来到因子计算这一章。
说实话,因子这东西,听起来玄乎,其实就是我们用来预测股票未来涨跌的“信号”。你想想看,做量化交易,本质上就是在找规律。而因子,就是这些规律的数学化表达。
我个人习惯把因子比作“选股的眼睛”。没有因子,你就是在黑箱里瞎摸。有了因子,你至少知道该往哪个方向看。
4.1 因子定义与分类
先给个定义:因子,是指能够解释或预测资产收益的某种特征或变量。
嗯,这里要注意,因子不是凭空捏造的。它背后得有逻辑支撑。比如“动量因子”,逻辑就是“强者恒强”;“反转因子”,逻辑就是“物极必反”。
常见的因子分类,我整理了一张表,大家看看:
| 分类 | 典型因子 | 逻辑简述 |
|---|---|---|
| 动量因子 | 过去N日收益率 | 趋势延续,涨的还会涨 |
| 反转因子 | 过去N日收益率(负相关) | 物极必反,涨多了会跌 |
| 波动率因子 | 过去N日收益率标准差 | 低波动股票长期跑赢高波动 |
| 价值因子 | 市盈率、市净率 | 便宜的好货 |
| 质量因子 | ROE、毛利率 | 好公司更抗跌 |
当然,这只是冰山一角。实际工作中,因子库动辄成百上千个。但核心逻辑就这些:要么追趋势,要么赌反转,要么求稳。
核心要点:因子的有效性会随时间衰减。去年赚钱的因子,今年可能就失效了。所以,因子不是一劳永逸的,需要持续迭代。
4.2 因子计算框架
讲完了分类,咱们聊聊怎么算。我见过很多新手,上来就写一堆for循环,数据量一大直接卡死。其实,因子计算是有套路的。
我个人习惯用向量化计算。说白了,就是利用NumPy和Pandas的底层优化,一次性处理整个数组,而不是一个个循环。
一个标准的因子计算框架,通常包含这几步:
- 数据准备:获取日线数据(开盘价、收盘价、成交量等)
- 因子计算:用向量化函数(如rolling、shift、pct_change)计算原始因子值
- 因子处理:去极值、标准化、中性化
- 因子存储:存入HDF5或数据库,方便后续回测
我曾经在一个项目中,接手了别人写的因子计算代码。好家伙,一个因子跑了三个小时。我改成向量化后,三分钟搞定。你想想看,这差距有多大。
小技巧:写因子计算时,尽量用Pandas的链式操作。比如 df['ret'] = df['close'].pct_change(),一行代码搞定收益率计算。
4.3 常见因子实现
光说不练假把式。咱们直接上代码,看看几个经典因子怎么实现。
4.3.1 动量因子
动量因子,说白了就是“过去涨得好,未来大概率继续涨”。计算方式很简单:
import pandas as pd
import numpy as np
# 假设df是日线数据,包含'close'列
def momentum_factor(df, window=20):
"""
计算动量因子:过去N日的累计收益率
"""
df['momentum'] = df['close'].pct_change(periods=window)
return df
嗯,这里要注意:pct_change(periods=window) 计算的是过去N天的总收益率,不是平均收益率。我个人习惯用总收益率,因为更直观。
4.3.2 反转因子
反转因子和动量因子正好相反。它赌的是“涨多了会跌,跌多了会涨”。
def reversal_factor(df, window=5):
"""
计算反转因子:过去N日的累计收益率(取负值)
"""
df['reversal'] = -df['close'].pct_change(periods=window)
return df
你看,代码几乎一样,就是加了个负号。但逻辑完全不同。动量因子是正相关,反转因子是负相关。
避坑指南:我曾经在A股市场同时用动量和反转因子,结果发现它们经常互相抵消。后来我学乖了,在不同时间尺度上分别使用:短期(1-5天)用反转,中期(20-60天)用动量。
4.3.3 波动率因子
波动率因子,衡量的是股票价格的“上蹿下跳”程度。低波动率的股票,长期来看往往表现更好。
def volatility_factor(df, window=20):
"""
计算波动率因子:过去N日收益率的标准差
"""
df['daily_ret'] = df['close'].pct_change()
df['volatility'] = df['daily_ret'].rolling(window=window).std()
return df
这里有个细节:rolling(window=window).std() 计算的是样本标准差。如果你想要总体标准差,可以加个 ddof=0 参数。不过在实际量化中,样本标准差更常用。
4.4 因子标准化
因子算出来了,但不同因子的量纲不一样。比如动量因子可能是0.05(5%),波动率因子可能是0.02(2%)。直接比较没有意义。所以,我们需要标准化。
常用的标准化方法有两种:
- Z-score标准化:减去均值,除以标准差。结果服从均值为0、标准差为1的分布。
- 排序标准化:将因子值排序,映射到[0,1]区间。说白了,就是看排名。
我个人更推荐Z-score标准化,因为它保留了因子值之间的相对距离信息。
def zscore_normalize(series):
"""
Z-score标准化
"""
return (series - series.mean()) / series.std()
def rank_normalize(series):
"""
排序标准化
"""
return series.rank(pct=True)
嗯,这里要注意:标准化之前,一定要先去极值。否则,一个极端值会把整个分布拉偏。
去极值的方法:我常用的是MAD法(中位数绝对偏差)。把超过3倍MAD的值,替换成3倍MAD。比直接用百分位法更稳健。
好了,因子计算的基础就这些。说白了,就是三步:算出来、标准化、存起来。但每一步都有坑,需要你亲自踩一踩才能记住。
下一章,我们会把这些因子组合起来,构建一个完整的选股模型。到时候你会发现,单个因子可能很弱,但组合起来威力巨大。
公众号:蓝海数据掘金营,微信deep3321