3. 相关性分析:别被数字骗了

相关性分析,说白了就是找两个变量之间的「默契程度」。你涨我也涨,你跌我也跌——这叫正相关。你涨我跌,你跌我涨——这叫负相关。嗯,听起来很简单对吧?但我在量化交易这行干了十几年,见过太多人在这一步翻车了。

今天咱们就聊聊三种常用的相关性度量方法,以及那个让人又爱又恨的「伪相关」陷阱。

3.1 皮尔逊相关系数:最经典,但也很挑剔

皮尔逊相关系数,大家通常叫它 r 值。取值范围在 -1 到 1 之间。1 表示完全正相关,-1 表示完全负相关,0 表示没关系。

公式我就不手写了,你肯定见过。但我要说的是它的脾气——皮尔逊只认线性关系。什么意思?就是两个变量必须像直尺一样直来直去。

核心要点:皮尔逊相关系数假设数据是正态分布的,且关系是线性的。如果数据有异常值,结果会被严重扭曲。

我记得有一次做股票配对交易,用皮尔逊算出来两只股票的相关系数高达 0.92。我差点就直接上仓位了。但多看了一眼散点图,发现有个极端值把整个结果拉上去了。去掉那个点,r 值直接掉到 0.6。嗯,从那以后我养成了「先看图,再算数」的习惯。

用 Python 算皮尔逊很简单:

import numpy as np
from scipy import stats

# 假设有两只股票收益率数据
stock_a = np.array([0.01, 0.02, -0.01, 0.03, -0.02])
stock_b = np.array([0.015, 0.025, -0.005, 0.035, -0.015])

r, p_value = stats.pearsonr(stock_a, stock_b)
print(f"皮尔逊相关系数: {r:.4f}")
print(f"p值: {p_value:.4f}")

我的习惯:p 值小于 0.05 我才认为相关性是显著的。但别只看 p 值,样本量大了 p 值很容易显著,这时候要结合 r 的绝对值一起看。

3.2 斯皮尔曼秩相关系数:不挑食的替代方案

皮尔逊太挑剔了,那怎么办?用斯皮尔曼啊。

斯皮尔曼不关心原始数值,它只关心排名。你把数据从小到大排个序,然后算排名的相关性。这样一来,异常值的影响就小多了。

我举个例子你就明白了。假设有两只股票,A 的收益率是 [1, 2, 3, 4, 100],B 是 [2, 4, 6, 8, 200]。皮尔逊算出来接近 1,因为线性关系很强。但如果你把第 5 个异常点去掉,皮尔逊可能就变了。斯皮尔曼呢?它只看排名,不管 100 和 200 有多大,只要排名一致,结果就稳定。

代码实现:

rho, p_value = stats.spearmanr(stock_a, stock_b)
print(f"斯皮尔曼相关系数: {rho:.4f}")
print(f"p值: {p_value:.4f}")

什么时候用斯皮尔曼?

  • 数据明显不是正态分布
  • 有异常值,但你不想手动处理
  • 关系可能是单调的,但不一定是线性的

我个人习惯是:两个都算一下。如果皮尔逊和斯皮尔曼结果差不多,那说明关系比较稳健。如果差很多,嗯,那就要小心了——可能数据有问题,或者关系不是线性的。

3.3 相关性矩阵:一眼看穿全局

做多资产策略的时候,你不可能只盯着两只股票看。几十上百个标的,两两算相关性?手算会疯的。这时候就需要相关性矩阵了。

说白了就是一个表格,行和列都是资产,交叉点就是它们的相关系数。对角线全是 1,因为自己和自己当然完全相关。

用 pandas 一行代码搞定:

import pandas as pd

# 假设 df 是收益率数据,每列一个资产
corr_matrix = df.corr(method='pearson')  # 或者 method='spearman'
print(corr_matrix)

我一般会用热力图来可视化:

import seaborn as sns
import matplotlib.pyplot as plt

plt.figure(figsize=(10, 8))
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', center=0)
plt.title('资产相关性矩阵')
plt.show()

颜色越红,正相关越强;越蓝,负相关越强。一眼就能看出哪些资产「抱团」,哪些资产「对冲」。

避坑指南:我曾经用日收益率算相关性矩阵,发现大部分股票之间相关系数都在 0.5 以上。后来换成周收益率,相关性就降下来了。为什么?因为日收益率受市场微观结构影响大,比如非同步交易。你想想看,A 股和美股交易时间都不一样,用日收益率算相关性,结果能准吗?

3.4 相关性陷阱与伪相关:最容易被忽视的风险

好了,重点来了。相关性分析最大的坑,不是算不对,而是算对了但没用

什么叫伪相关?就是两个变量在统计上显著相关,但没有任何因果关系。比如「美国黄油产量」和「缅因州离婚率」在过去几十年里高度相关。你觉得这两者有关系吗?显然没有。这就是伪相关。

在量化交易里,伪相关更隐蔽。我见过有人发现「某只股票前一天的成交量」和「第二天的天气」有 0.8 的相关性。然后他建了个策略...结果可想而知。

伪相关的常见来源:

  • 共同趋势:两个资产都受同一个宏观因素影响,比如利率。它们之间可能没有直接关系,但都跟着利率走。
  • 数据挖掘:你试了 1000 个变量,总能找到几个显著相关的。这叫多重比较问题。
  • 样本期选择:换一个时间段,相关性可能就消失了。我习惯用滚动窗口算相关性,看看它是不是稳定的。
  • 滞后相关性:今天 A 涨了,明天 B 也涨了。这可能是领先滞后关系,但不代表它们有稳定的相关性。

怎么避免?我分享几个经验:

  1. 先有逻辑,后有统计。不要盲目跑数据。先问自己:这两个资产之间有没有经济意义上的联系?
  2. 做滚动相关性分析。固定窗口长度,比如 60 天,每天算一次相关性。看看这个序列是不是稳定的。
  3. 用不同频率的数据验证。日度、周度、月度都算一遍。如果结果不一致,那就要小心了。
  4. 做格兰杰因果检验。虽然不完美,但至少能帮你排除一些明显的伪相关。

代码示例:滚动相关性

# 滚动60天相关性
rolling_corr = df['stock_a'].rolling(window=60).corr(df['stock_b'])
rolling_corr.plot(title='滚动60天相关性')
plt.axhline(y=0, color='r', linestyle='--')
plt.show()

总结一下我的经验:

相关性分析是统计套利的基础,但也是最容易出错的地方。皮尔逊适合线性关系,斯皮尔曼更稳健。相关性矩阵帮你快速了解全局。而伪相关,嗯,那是每个量化交易者都要面对的「心魔」。

记住一句话:相关不等于因果。你可以在策略里用相关性,但千万别把它当成真理。我见过太多人因为一个漂亮的相关性数字就冲进去,最后亏得底朝天。

下一章咱们聊聊协整关系,那才是统计套利的真正核心。相关性只是表面,协整才是灵魂。