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}")
我的小技巧: 如果偏度的绝对值大于1,或者峰度大于5,我一般会多留个心眼。这种序列往往藏着“惊喜”——可能是数据错误,也可能是市场结构发生了变化。

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}")
注意: 我曾经在分析股指期货基差时,发现JB检验的p值接近0.05,差点就接受了正态假设。后来我画了Q-Q图,发现尾部明显偏离。所以我的建议是:不要只看p值,一定要配合图形判断。Q-Q图、直方图、核密度图,这些可视化工具比单一统计量更可靠。

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()
实战经验: 我在做螺纹钢基差分析时,发现ACF在滞后5阶后突然跳升。一开始以为是数据问题,后来才发现是每周的库存数据发布日造成的。所以,ACF/PACF的异常点往往藏着市场微观结构的线索,别轻易忽略。

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("结论:基差不平稳,需要差分或做协整处理")
避坑指南: 我曾经在分析某个商品期货的基差时,ADF检验显示p值为0.03,我以为是平稳的。但后来发现,那是因为我忘了设置autolag='AIC'参数,导致滞后阶数选择不当。所以我的建议是:一定要用信息准则自动选择滞后阶数,别用手动设置。另外,如果序列有明显的趋势,记得加上regression='ct'参数。

6.5 知识体系总览

说了这么多,我们来画一张图,把这一章的核心逻辑串起来:

基差统计分析知识体系 基差序列 描述性统计 正态性检验 自相关分析 平稳性检验 均值/标准差 偏度/峰度 极值分析 JB检验 Shapiro-Wilk Q-Q图辅助 ACF分析 PACF分析 周期识别 ADF检验 滞后阶数选择 差分处理 四步走完,基差性格全掌握

这张图把四个分析模块的关系理清楚了。你从基差序列出发,先做描述性统计了解基本特征,再做正态性检验判断分布形态,接着用ACF/PACF分析时间依赖结构,最后用ADF检验确认平稳性。四步走完,你对基差的“性格”基本就摸透了。

好了,这一章的内容就到这里。记住,统计分析不是目的,目的是为后面的套利策略打下基础。下一章我们会聊怎么用这些分析结果来构建具体的交易信号。


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