因子暴露的数学定义

聊因子暴露之前,我先问个问题:你凭什么说某只股票「偏向」价值因子?

凭感觉?凭它市盈率低?嗯,这其实已经接近答案了。但量化交易里,我们需要一个精确的数学表达。说白了,就是给每只股票、每个因子算一个「数字」,这个数字就叫因子暴露。

因子暴露的线性代数表示

我个人习惯把因子暴露理解成「股票在因子空间里的坐标」。你想想看,如果我们把因子当成坐标轴,那每只股票就是空间里的一个点。

假设我们有 N 只股票,K 个因子。那么因子暴露矩阵 X 就是一个 N×K 的矩阵:

X = [[x₁₁, x₁₂, ..., x₁K],
     [x₂₁, x₂₂, ..., x₂K],
     ...
     [xN₁, xN₂, ..., xNK]]

这里 xᵢⱼ 表示第 i 只股票在第 j 个因子上的暴露度。举个例子,如果第 1 个因子是「市值因子」,那 x₁₁ 就是股票 1 的市值暴露。

核心公式:

股票收益率 = 因子暴露 × 因子收益率 + 残差

用矩阵写就是:R = X × F + ε

我在项目中遇到过不少新手,上来就把因子暴露和因子收益率混为一谈。这两者完全不同——暴露是「特征」,收益率是「回报」。就像你不能说一个人「高」就是「跑得快」,对吧?

因子载荷矩阵

因子载荷矩阵,其实就是上面那个 X 矩阵的另一种叫法。不过在实际应用中,它通常特指「标准化后的暴露矩阵」。

为什么要标准化?

因为不同因子的量纲不一样。比如市值因子,数值可能是几百亿;而动量因子,可能只是 0.8 或 1.2。如果不标准化,你没法比较哪个因子对股票的影响更大。

标准化的方法我常用两种:

  1. Z-score 标准化:减去均值,除以标准差
  2. Rank 标准化:把数值转成百分位数,再映射到 [-1, 1] 区间
# 我个人习惯用 Z-score
import numpy as np

def standardize_exposure(raw_exposure):
    mean = np.mean(raw_exposure)
    std = np.std(raw_exposure)
    return (raw_exposure - mean) / std

小技巧: 标准化后的因子载荷矩阵,每列的均值是 0,标准差是 1。这样你在做回归时,系数的大小直接反映了因子的相对重要性。

暴露度计算

暴露度怎么算?这得看因子类型。我把它分成三类:

因子类型 计算方法 例子
基本面因子 直接用财务指标 市盈率、市净率
技术面因子 用历史价格计算 动量、波动率
另类因子 用非结构化数据 舆情得分、搜索热度

举个例子,计算「动量因子」的暴露度:

def momentum_exposure(prices, lookback=252):
    """
    计算过去252个交易日的动量暴露
    """
    # 过去一年的累计收益率
    momentum = (prices[-1] - prices[0]) / prices[0]
    return momentum

嗯,这里要注意:动量因子通常还要做「中性化处理」。什么意思?就是剔除市值、行业等已知因子的影响。我曾经吃过这个亏——算出来的动量暴露和市值高度相关,结果回测漂亮,实盘一塌糊涂。

避坑指南: 我曾经在计算因子暴露时,忘了做行业中性化。结果发现所有高暴露的股票全是科技股,低暴露的全是银行股。这哪是因子选股?分明是行业选择!

多因子暴露矩阵的构建

实际工作中,我们很少只用一两个因子。构建多因子暴露矩阵时,我建议按以下步骤来:

  1. 收集原始数据:每个因子对应的原始指标
  2. 清洗异常值:去掉极端值,比如市值最大的那 0.1%
  3. 标准化处理:让不同因子可比
  4. 中性化处理:剔除已知风险因子的影响
  5. 正交化处理:降低因子之间的相关性

最后一步「正交化」很多人会忽略。但你想,如果两个因子高度相关,比如「价值因子」和「低波动因子」经常重叠,那你的模型就会出现多重共线性问题。

# 正交化示例:用 Gram-Schmidt 方法
def orthogonalize(X):
    """
    对因子暴露矩阵做正交化
    """
    n_factors = X.shape[1]
    Q = np.zeros_like(X)
    
    for i in range(n_factors):
        v = X[:, i].copy()
        for j in range(i):
            v = v - np.dot(Q[:, j], X[:, i]) * Q[:, j]
        Q[:, i] = v / np.linalg.norm(v)
    
    return Q

记住: 因子暴露不是算出来就完事了。你得定期更新——我一般每月重新计算一次。因为股票的因子特征会变,今天的小盘股,明天可能就变成中盘股了。

用 SVG 画一张因子暴露结构图

下面这张图展示了因子暴露的核心逻辑,从原始数据到最终暴露矩阵的完整流程:

因子暴露计算流程 原始数据 财务指标/价格/舆情 数据清洗 去极值/填充缺失值 标准化 Z-score / Rank 中性化处理 剔除行业/市值影响 正交化 因子载荷矩阵 X N×K 矩阵 每列一个因子 最终暴露度 用于回归分析 输入 清洗 标准化 中性化 正交化

这张图把整个流程串起来了。你从原始数据开始,经过清洗、标准化、中性化、正交化,最后得到干净的因子暴露矩阵。每一步都有它的意义——跳过任何一步,都可能让你的策略出问题。

好了,因子暴露的数学定义就聊到这儿。记住一句话:因子暴露是量化交易的「语言」,你得学会用它说话。

专注资料整理