4、相关性分析:皮尔逊、斯皮尔曼相关系数在资产筛选中的应用

做跨资产套利,第一步不是找策略,而是找「对的人」。

什么意思?你得先搞清楚哪些资产之间真的存在联动关系。如果两个品种八竿子打不着,你硬要做配对套利,那纯粹是给自己找麻烦。我早年就干过这种蠢事——把螺纹钢和豆粕放在一起算相关性,结果回测曲线漂亮得不行,实盘一跑直接崩了。后来才明白,那纯粹是数据挖掘出来的伪相关。

4.1 为什么相关性是套利的基石?

套利的本质,是赚「价差回归」的钱。但前提是——价差必须会回归。

如果两个资产根本不相关,价差就是随机游走,你进去就是赌大小。相关性分析,说白了就是帮你筛选出那些「天生就该在一起」的品种。

核心逻辑: 只有高相关性的资产,价差才具备均值回归特性。相关性越低,套利策略的胜率越接近抛硬币。

我个人习惯把相关性分成三个档次:

  • 0.8 以上: 强相关,适合做套利。比如沪深300和上证50,同涨同跌是常态。
  • 0.5 - 0.8: 中等相关,可以做,但需要额外筛选。比如黄金和白银,有时候会背离。
  • 0.5 以下: 弱相关,别碰。你想想看,两个走势都没关系的品种,价差怎么回归?

4.2 皮尔逊相关系数:最常用的线性关系度量

皮尔逊相关系数,大家应该都见过。公式我就不写了,你肯定知道。它的核心是衡量两个变量之间的线性关系

但这里有个坑——皮尔逊对异常值极其敏感。我在项目中遇到过一件事:有一次分析比特币和以太坊的相关性,正常情况都在0.9以上。结果某天比特币闪崩,数据里多了一个极端值,相关系数直接掉到0.3。我当时差点把这个配对删掉,还好多看了一眼散点图。

注意: 皮尔逊相关系数假设数据是正态分布且线性相关。如果你的数据有厚尾、有异常值,结果会严重失真。

代码实现很简单,用 numpy 或者 pandas 都行:

import numpy as np
import pandas as pd

# 假设你有两个资产的价格序列
asset_a = np.array([100, 102, 101, 105, 107])
asset_b = np.array([50, 51, 50.5, 52.5, 53.5])

# 计算皮尔逊相关系数
pearson_corr = np.corrcoef(asset_a, asset_b)[0, 1]
print(f"皮尔逊相关系数: {pearson_corr:.4f}")

# 用pandas也行
df = pd.DataFrame({'A': asset_a, 'B': asset_b})
print(f"pandas 结果: {df.corr().iloc[0, 1]:.4f}")

嗯,这里要注意:计算之前最好先做差分或者对数收益率,直接用价格算相关性会有伪回归的问题。我早期吃过这个亏,后来就养成了习惯——永远用收益率算相关性。

4.3 斯皮尔曼相关系数:非线性关系的救星

皮尔逊搞不定的情况,斯皮尔曼来补。它不关心具体数值,只关心排名。说白了,就是看两个资产的涨跌顺序是否一致。

举个例子:假设资产A涨了5%,资产B涨了3%。皮尔逊看的是「5%和3%」这两个数字的关系,斯皮尔曼看的是「A涨得比B多」这个排名关系。

为什么需要斯皮尔曼?因为金融市场很多时候不是线性的。比如极端行情下,所有资产一起暴跌,但跌幅比例可能完全不同。这时候皮尔逊会告诉你相关性下降,但斯皮尔曼会告诉你——其实它们还是同涨同跌的。

我的经验: 做跨品种套利时,我一般两个系数都算。如果皮尔逊和斯皮尔曼差距很大(比如超过0.2),说明可能存在非线性关系或者异常值干扰,这时候我会进一步检查数据。

代码实现:

from scipy.stats import spearmanr

# 继续用上面的数据
spearman_corr, p_value = spearmanr(asset_a, asset_b)
print(f"斯皮尔曼相关系数: {spearman_corr:.4f}")
print(f"p值: {p_value:.4f}")

p值很重要。如果p值大于0.05,说明相关性不显著,就算系数算出来是0.9也别信。我见过有人拿着p值0.1的相关性去做套利,结果亏得底裤都不剩。

4.4 实战:如何用相关性筛选套利对?

光讲理论没意思,咱们来点实际的。假设你有10个资产,想找出最适合做套利的配对,怎么做?

我的流程是这样的:

  1. 数据准备: 取日线数据,计算对数收益率。记住,用价格算相关性是新手才会犯的错。
  2. 计算相关性矩阵: 同时算皮尔逊和斯皮尔曼,得到两个矩阵。
  3. 筛选候选对: 两个系数都大于0.8的,进入候选池。
  4. 检查差异: 如果皮尔逊和斯皮尔曼差距大于0.15,标记为「需人工复核」。
  5. 可视化验证: 画散点图,肉眼确认一下。这一步不能省,我吃过亏。

避坑指南: 我曾经用全自动筛选跑出来一组「完美」的套利对——黄金和某只小盘股,相关性0.95。结果一查,那只股票是黄金矿企,本身就是跟黄金走的。这种相关性是假的,因为存在共同因子。所以筛选完一定要做逻辑验证。

下面是一个完整的筛选代码框架:

import pandas as pd
import numpy as np
from scipy.stats import spearmanr
import itertools

def filter_pairs(price_df, threshold=0.8):
    """
    筛选套利候选对
    price_df: DataFrame, 每列是一个资产的价格
    threshold: 相关性阈值
    """
    # 计算对数收益率
    returns = np.log(price_df / price_df.shift(1)).dropna()
    
    # 计算皮尔逊矩阵
    pearson_matrix = returns.corr()
    
    # 准备结果
    results = []
    assets = returns.columns
    
    for a, b in itertools.combinations(assets, 2):
        # 皮尔逊
        p_corr = pearson_matrix.loc[a, b]
        
        # 斯皮尔曼
        s_corr, p_val = spearmanr(returns[a], returns[b])
        
        # 筛选条件
        if p_corr > threshold and s_corr > threshold:
            diff = abs(p_corr - s_corr)
            results.append({
                'pair': f"{a}-{b}",
                'pearson': round(p_corr, 4),
                'spearman': round(s_corr, 4),
                'diff': round(diff, 4),
                'p_value': round(p_val, 4)
            })
    
    result_df = pd.DataFrame(results)
    result_df = result_df.sort_values('pearson', ascending=False)
    return result_df

# 使用示例
# result = filter_pairs(price_data)
# print(result.head(10))

4.5 知识体系总览

说了这么多,我画了一张图帮你理清思路。相关性分析在整个套利流程中的位置,以及两种系数的适用场景,一目了然。

相关性分析在资产筛选中的核心逻辑 多资产价格数据 步骤1:计算对数收益率序列 皮尔逊相关系数(线性) 斯皮尔曼相关系数(排名) 两者均 > 0.8? 且差异 < 0.15? p值 < 0.05? 逻辑验证通过? ✅ 套利候选对列表

4.6 总结一下

相关性分析不是万能的,但没有相关性分析是万万不能的。我见过太多人一上来就搞协整、搞机器学习,结果连最基本的皮尔逊和斯皮尔曼都没搞清楚。

记住三点:

  • 用收益率算相关性,别用价格
  • 皮尔逊和斯皮尔曼一起看,互相验证
  • 算完一定要做逻辑验证,别信数据挖掘

做到这三点,你的套利对筛选至少不会犯低级错误。至于更高级的协整分析、半衰期计算,那是后面章节的事。先把基础打牢,后面才能走远。

一个小技巧: 如果你发现两个资产的皮尔逊系数很高但斯皮尔曼很低,大概率是存在异常值。这时候别急着删数据,先看看那段时间发生了什么。有时候异常值本身就是交易机会。


公众号:蓝海资料掘金营,微信deep3321