3、行业中性化数学原理:线性回归与正交化、残差构建与解释、行业虚拟变量的设置
好,咱们直接进入正题。行业中性化,说白了就是要把行业因素从配对交易中「剥离」出去。为什么要这么做?因为两只股票即使基本面再像,如果分属不同行业,它们的价差波动很可能被行业大环境带着跑,而不是真正的统计套利机会。
我个人习惯把行业中性化理解成「过滤」。就像做咖啡要过滤掉咖啡渣一样,我们要过滤掉行业因子对股票收益的影响。剩下的那部分,才是我们真正关心的、个股自身的「纯味」。
3.1 行业虚拟变量的设置
先聊聊最基础的东西——行业虚拟变量。这东西其实不复杂,但很多新手容易栽跟头。
假设我们有 5 个行业:金融、科技、医药、消费、能源。那我们就需要设置 4 个虚拟变量(为什么是 4 个?因为要避免「虚拟变量陷阱」,这个我后面会讲)。
举个例子:
# 假设我们有 10 只股票,分属不同行业
# 行业编码:1=金融, 2=科技, 3=医药, 4=消费, 5=能源
import pandas as pd
import numpy as np
# 生成示例数据
data = {
'stock_id': range(1, 11),
'industry': [1, 2, 1, 3, 4, 2, 5, 3, 4, 1],
'return': [0.02, 0.05, -0.01, 0.03, 0.04, -0.02, 0.01, 0.06, -0.03, 0.02]
}
df = pd.DataFrame(data)
# 设置虚拟变量(用 pandas 的 get_dummies)
dummies = pd.get_dummies(df['industry'], prefix='ind')
# 去掉第一列,避免多重共线性
dummies = dummies.iloc[:, 1:]
df = pd.concat([df, dummies], axis=1)
print(df.head())
嗯,这里要注意:虚拟变量的数量 = 行业数量 - 1。为什么?因为如果你把 5 个行业都设成虚拟变量,那这 5 列加起来刚好等于 1(每只股票只属于一个行业),这就产生了完美的多重共线性。回归模型会直接崩溃给你看。
3.2 线性回归与正交化
有了虚拟变量,接下来就是做回归。我们的目标很简单:用行业虚拟变量去解释股票收益。
数学上长这样:
r_i = α + β₁·D₁ + β₂·D₂ + ... + βₖ·Dₖ + ε_i
其中:
- r_i 是股票 i 的收益率
- D₁ 到 Dₖ 是行业虚拟变量
- β₁ 到 βₖ 是行业因子暴露
- ε_i 就是我们要的残差——行业中性化后的收益
你想想看,这个回归本质上在做什么?它是在把股票收益「投影」到行业空间上。投影出来的部分(拟合值)就是行业因子能解释的部分,剩下的残差就是个股自己的东西。
这就是正交化的思想。说白了,残差和行业因子是正交的——它们之间没有线性关系。这就保证了我们剥离干净了。
我在项目中遇到过一种情况:有些股票横跨多个行业(比如综合类企业)。这时候虚拟变量就不能简单设成 0/1 了,得用行业权重。比如某公司 60% 业务在科技、40% 在消费,那虚拟变量就设成 0.6 和 0.4。这叫「模糊行业归属」,处理起来稍微麻烦点,但原理一样。
3.3 残差构建与解释
残差 ε_i 就是我们最终要的东西。它代表的是:剔除了行业因子后,股票自身的异常收益。
怎么用?在配对交易里,我们不再直接用原始价格或收益率做价差,而是用残差做价差。比如:
# 假设我们有两支股票 A 和 B
# 先对每支股票做行业中性化回归,得到残差
# 伪代码示意
residual_A = return_A - fitted_A # 行业中性化后的收益
residual_B = return_B - fitted_B
# 然后用残差做配对
spread = residual_A - residual_B
# 当 spread 偏离均值超过 2 个标准差时,开仓
这样做的好处很明显:即使 A 和 B 分属不同行业,它们的残差价差也不会被行业趋势带偏。你捕捉到的,是两只股票之间真正的、独立于行业的联动关系。
残差还有一个重要的统计性质:它的均值理论上为 0。因为回归的残差和总是 0(如果模型包含截距项)。这意味着行业中性化后的收益序列是「零均值」的,方便我们做统计检验。
但要注意一点:残差并不一定是白噪声。它可能还包含其他因子(比如市值因子、动量因子)的影响。如果你想要更干净的信号,可以继续做多因子中性化。不过那是后面章节的内容了。
3.4 知识体系总览
为了让你对整个流程有个直观印象,我画了张图:
这张图把整个流程串起来了。从左到右看:输入数据 → 设置虚拟变量 → 做回归 → 得到拟合值和残差。残差就是我们最终要的东西。
3.5 几点补充
最后聊几个实操中容易忽略的点:
- 行业分类的粒度:用申万一级行业还是二级行业?我建议先用一级行业试,如果发现同行业股票残差相关性还是很高,再考虑用二级行业。太细的行业分类会导致虚拟变量过多,样本量不够用。
- 时间窗口的选择:回归窗口太短(比如 20 天),估计出来的行业暴露不稳定;太长(比如 250 天),又可能跟不上行业结构的变化。我个人习惯用 60 天,也就是一个季度左右。
- 截距项的处理:如果模型包含截距项 α,那它代表的是「市场平均收益」中不能被行业解释的部分。有些做法会去掉截距项,让行业虚拟变量完全吸收所有截面差异。两种做法各有道理,看你的具体需求。
好了,这一节的内容就到这。数学原理其实不复杂,关键是理解「正交化」这个思想——把收益分解成行业部分和个股部分,然后只取个股部分。下一节我们会讲怎么用这些残差来构建配对交易策略,包括协整检验和阈值设定。到时候见。