6. 基差统计分析:描述性统计、正态性检验、自相关与偏自相关分析、平稳性检验(ADF检验)
各位同学,欢迎来到第六章。
前面我们聊了基差的基础概念,也讲了数据怎么拿、怎么清洗。但说实话,拿到数据只是第一步。你想想看,一堆数字摆在你面前,你总得先摸清楚它们的脾气吧?
这一章,我们就来干这件事——对基差序列做一次彻底的“体检”。我个人习惯把这套流程叫做“数据四件套”:描述性统计、正态性检验、自相关分析、平稳性检验。做完这四步,你对基差的性格基本就心里有数了。
6.1 描述性统计:先看看基差长什么样
描述性统计,说白了就是给数据拍一张“证件照”。你不用管它背后多复杂,先看看它的均值、标准差、最大值、最小值这些基本特征。
我在项目中遇到过一件事:有一次我拿到一个品种的基差数据,扫了一眼均值是-20,觉得挺正常。结果一算偏度,发现严重左偏。后来一查,原来是某个月份出现了极端负基差,把整个序列带偏了。嗯,这就是描述性统计的价值——它能帮你快速发现异常。
我们一般关注这几个指标:
- 均值(Mean):基差的平均水平。如果长期均值不为零,说明存在系统性偏差。
- 标准差(Std):基差的波动程度。标准差越大,套利机会可能越多,但风险也越高。
- 偏度(Skewness):判断分布是否对称。正偏表示右尾长,负偏表示左尾长。
- 峰度(Kurtosis):判断分布的“尖胖”程度。峰度大于3,说明有厚尾特征——极端值出现的概率比正态分布高。
- 最大值/最小值:看一眼极端值,心里有个底。
代码实现很简单,用pandas的describe()就能搞定。但我建议你额外算一下偏度和峰度:
import pandas as pd
import numpy as np
# 假设df['basis']是你的基差序列
desc = df['basis'].describe()
skew = df['basis'].skew()
kurt = df['basis'].kurtosis()
print(f"均值: {desc['mean']:.2f}")
print(f"标准差: {desc['std']:.2f}")
print(f"偏度: {skew:.2f}")
print(f"峰度: {kurt:.2f}")
6.2 正态性检验:基差到底是不是正态分布?
很多量化模型都假设数据服从正态分布。但现实是,基差序列很少是完美的正态分布。为什么会这样?因为基差受交割日、库存变化、政策扰动等多种因素影响,尾部往往更厚。
常用的正态性检验方法有:
- Jarque-Bera检验(JB检验):基于偏度和峰度。如果p值小于0.05,拒绝正态假设。
- Shapiro-Wilk检验:小样本下更准确,但大样本时计算较慢。
- Kolmogorov-Smirnov检验(KS检验):比较经验分布与理论分布的差异。
我个人习惯用JB检验,因为它计算快,而且对厚尾特征比较敏感。来看代码:
from scipy.stats import jarque_bera, shapiro, kstest
# Jarque-Bera检验
jb_stat, jb_p = jarque_bera(df['basis'].dropna())
print(f"JB统计量: {jb_stat:.2f}, p值: {jb_p:.4f}")
# Shapiro-Wilk检验(样本量不宜过大)
sw_stat, sw_p = shapiro(df['basis'].dropna().sample(5000))
print(f"SW统计量: {sw_stat:.2f}, p值: {sw_p:.4f}")
6.3 自相关与偏自相关分析:基差有没有“记忆”?
基差序列有一个很有意思的特点——它往往存在自相关性。什么意思?就是今天的基差和昨天的基差有关系。你想想看,如果昨天基差很大,今天大概率也不会突然归零,对吧?
自相关函数(ACF)衡量的是序列与其滞后项的相关性。偏自相关函数(PACF)则是在剔除中间滞后项影响后,衡量直接的相关性。
这两个工具在实战中特别有用:
- 判断均值回复速度:如果ACF衰减很快,说明基差回复速度快,套利窗口期短。
- 识别周期模式:比如某些品种的基差在交割周前后有明显的周期特征。
- 为建模提供依据:ACF和PACF的截尾/拖尾特征,能帮你决定用AR还是MA模型。
画ACF和PACF的代码:
import matplotlib.pyplot as plt
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8))
plot_acf(df['basis'].dropna(), lags=40, ax=ax1)
ax1.set_title('基差自相关函数 (ACF)')
plot_pacf(df['basis'].dropna(), lags=40, ax=ax2)
ax2.set_title('基差偏自相关函数 (PACF)')
plt.tight_layout()
plt.show()
6.4 平稳性检验(ADF检验):基差能不能用?
这一节是重点中的重点。为什么?因为大多数时间序列模型都要求数据是平稳的。如果基差不平稳,你做的回归、套利模型可能全是伪回归——看着漂亮,实际没用。
平稳性,简单说就是:均值和方差不随时间变化。如果基差序列有趋势、有季节性,或者方差在变大,那它就是不平稳的。
ADF检验(Augmented Dickey-Fuller test)是最常用的单位根检验方法。它的原假设是“序列存在单位根(即不平稳)”。如果p值小于0.05,拒绝原假设,认为序列平稳。
代码实现:
from statsmodels.tsa.stattools import adfuller
result = adfuller(df['basis'].dropna())
print(f'ADF统计量: {result[0]:.4f}')
print(f'p值: {result[1]:.4f}')
print(f'临界值:')
for key, value in result[4].items():
print(f' {key}: {value:.4f}')
if result[1] < 0.05:
print("结论:基差序列平稳,可以放心使用")
else:
print("结论:基差不平稳,需要差分或做协整处理")
autolag='AIC'参数,导致滞后阶数选择不当。所以我的建议是:一定要用信息准则自动选择滞后阶数,别用手动设置。另外,如果序列有明显的趋势,记得加上regression='ct'参数。
6.5 知识体系总览
说了这么多,我们来画一张图,把这一章的核心逻辑串起来:
这张图把四个分析模块的关系理清楚了。你从基差序列出发,先做描述性统计了解基本特征,再做正态性检验判断分布形态,接着用ACF/PACF分析时间依赖结构,最后用ADF检验确认平稳性。四步走完,你对基差的“性格”基本就摸透了。
好了,这一章的内容就到这里。记住,统计分析不是目的,目的是为后面的套利策略打下基础。下一章我们会聊怎么用这些分析结果来构建具体的交易信号。