第1章:价差分析基础——从统计特征到实战应用
各位同学,大家好。我是老张,在量化套利这个领域摸爬滚打了十几年。今天咱们开始讲跨期套利的第一块基石——价差分析基础。
很多人一上来就搞模型、跑回测,结果亏得一塌糊涂。为什么?说白了,你连价差的基本脾气都没摸透。我刚开始做套利时也犯过这毛病,后来吃了亏才明白:分析价差,就像医生看病,得先做基础检查。
这一章,咱们就来做这个「基础检查」。内容包括:价差的统计特征、分布形态、平稳性检验,还有自相关性分析。别觉得枯燥,这些是后面所有策略的根基。
核心观点:价差的统计特征决定了套利策略的可行性。一个不平稳、分布畸形的价差,再好的模型也白搭。
1.1 价差统计特征:均值、标准差、分位数
先问个问题:你拿到一组价差数据,第一件事看什么?
我个人习惯,先看三个东西:均值、标准差、分位数。
- 均值:价差的「中心位置」。如果均值在0附近,说明两个合约长期均衡;如果偏离很大,可能有结构性变化。
- 标准差:价差的「波动幅度」。标准差太小,套利空间不足;标准差太大,风险也大。
- 分位数:价差的「极端位置」。我一般看5%和95%分位数,用来设定开仓阈值。
举个例子。我做过螺纹钢的跨期套利,价差均值是-15元,标准差是8元。这意味着什么?价差大部分时间在-23到-7之间晃悠。如果某天价差跑到-35以下,那就是极端情况了。
实战技巧:我建议用滚动窗口计算这些统计量,比如过去60天的滚动均值和滚动标准差。因为价差的统计特征会随时间变化,固定参数容易过时。
来看一段Python代码,计算这些统计量:
import pandas as pd
import numpy as np
# 假设df是价差数据,列名为'spread'
df = pd.read_csv('spread_data.csv')
# 基本统计量
mean_val = df['spread'].mean()
std_val = df['spread'].std()
quantiles = df['spread'].quantile([0.05, 0.25, 0.5, 0.75, 0.95])
print(f"均值: {mean_val:.2f}")
print(f"标准差: {std_val:.2f}")
print("分位数:")
print(quantiles)
# 滚动统计(窗口60天)
df['rolling_mean'] = df['spread'].rolling(60).mean()
df['rolling_std'] = df['spread'].rolling(60).std()
这段代码很简单,但很实用。我每次拿到新数据,第一件事就是跑这个。
1.2 价差分布直方图与正态性检验
接下来,咱们看看价差的分布形态。为什么要看这个?
因为很多套利模型假设价差服从正态分布。如果实际分布偏态严重,或者有厚尾,那模型就会出问题。
我记得有一次做豆粕套利,价差直方图一看,明显双峰分布。后来一查,原来是两个合约的到期月份不同,市场结构变了。这种情况下用正态模型,肯定亏钱。
怎么做正态性检验?我常用两种方法:
- 直方图+QQ图:直观判断。如果直方图呈钟形,QQ图上的点接近直线,那基本正态。
- Shapiro-Wilk检验或Jarque-Bera检验:定量判断。p值大于0.05,不能拒绝正态假设。
来看代码:
import matplotlib.pyplot as plt
import scipy.stats as stats
# 直方图
plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
plt.hist(df['spread'], bins=50, density=True, alpha=0.7)
plt.title('价差分布直方图')
# QQ图
plt.subplot(1, 2, 2)
stats.probplot(df['spread'], dist="norm", plot=plt)
plt.title('QQ图')
plt.tight_layout()
plt.show()
# Jarque-Bera检验
jb_stat, jb_p = stats.jarque_bera(df['spread'].dropna())
print(f"Jarque-Bera统计量: {jb_stat:.2f}, p值: {jb_p:.4f}")
# Shapiro-Wilk检验(样本量小于5000时更准确)
sw_stat, sw_p = stats.shapiro(df['spread'].dropna())
print(f"Shapiro-Wilk统计量: {sw_stat:.2f}, p值: {sw_p:.4f}")
注意:正态性检验对样本量敏感。样本量太大时,即使微小偏离也会被判定为「非正态」。我一般结合直方图和QQ图做综合判断,不只看p值。
1.3 价差平稳性检验(ADF检验)
这是最关键的一步。价差如果不平稳,套利策略就是空中楼阁。
什么叫平稳?简单说,价差的均值、方差不随时间变化。如果价差一路走高或走低,那还套什么利?直接做趋势交易得了。
ADF检验是检验平稳性的标准方法。原假设是「存在单位根,即不平稳」。如果p值小于0.05,拒绝原假设,认为价差平稳。
我曾经踩过一个坑:做甲醇套利时,ADF检验p值0.03,看似平稳。但后来发现是因为样本期太短,只有3个月。拉长到1年,p值变成0.15,根本不平稳。所以,样本期至少要覆盖一个完整的市场周期。
代码实现:
from statsmodels.tsa.stattools import adfuller
# ADF检验
result = adfuller(df['spread'].dropna())
adf_stat = result[0]
p_value = result[1]
critical_values = result[4]
print(f"ADF统计量: {adf_stat:.4f}")
print(f"p值: {p_value:.4f}")
print("临界值:")
for key, value in critical_values.items():
print(f" {key}: {value:.4f}")
if p_value < 0.05:
print("结论:价差平稳,可以用于套利策略")
else:
print("结论:价差不平稳,需要进一步处理(如差分)")
重要提醒:ADF检验对滞后阶数敏感。我建议用AIC或BIC自动选择滞后阶数,不要手动指定。
1.4 价差自相关性分析
最后,咱们看看价差的自相关性。说白了,就是今天的价差和昨天的价差有没有关系。
如果自相关性很强,说明价差有趋势性,套利策略需要更复杂的模型(比如协整)。如果自相关性很弱,那简单均值回归模型就够用了。
我一般看两个东西:
- 自相关函数(ACF)图:看不同滞后期的相关系数。如果衰减缓慢,说明有长期记忆。
- 偏自相关函数(PACF)图:用于确定AR模型的阶数。
举个例子。我做铁矿石套利时,ACF图显示滞后1期和2期的相关系数很高,但3期以后迅速衰减。这说明价差主要受近期影响,用AR(2)模型就够了。
代码实现:
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
# ACF图
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plot_acf(df['spread'].dropna(), lags=30, ax=plt.gca())
plt.title('自相关函数 (ACF)')
# PACF图
plt.subplot(1, 2, 2)
plot_pacf(df['spread'].dropna(), lags=30, ax=plt.gca())
plt.title('偏自相关函数 (PACF)')
plt.tight_layout()
plt.show()
# 计算具体数值
from statsmodels.tsa.stattools import acf, pacf
acf_values = acf(df['spread'].dropna(), nlags=10)
pacf_values = pacf(df['spread'].dropna(), nlags=10)
print("滞后1-10期的自相关系数:")
for i, val in enumerate(acf_values[1:11], 1):
print(f" 滞后{i}期: {val:.4f}")
实战经验:如果ACF图在滞后1期就迅速降到0附近,说明价差是白噪声,套利机会很少。我一般要求至少滞后1-2期有显著自相关,才有做套利的价值。
知识体系总览
为了让大家更直观地理解本章的知识结构,我画了一张图:
这张图把本章的核心逻辑串起来了。你按这个顺序做分析,基本不会漏掉关键点。
好了,第一章的内容就到这里。价差分析是套利策略的「体检报告」,每一项指标都告诉你价差是否「健康」。下一章咱们会深入价差回归策略,到时候这些基础分析就派上用场了。
记住:基础不牢,地动山摇。把这一章的内容吃透,后面的路会顺很多。