第五章:价差序列构建

好,咱们进入正题。价差序列,说白了就是套利交易的核心原料。你策略再花哨,如果价差算错了,后面全是白搭。我见过太多新手,上来就搞机器学习,结果价差计算的基础逻辑都没搞对——嗯,咱们先把地基打牢。

5.1 价差的计算方法

价差,就是两个品种价格之间的差值。但怎么算,其实有讲究。

最简单的做法:

价差 = 价格A - 价格B

但实际交易中,很少有人这么干。为什么?因为两个品种的合约乘数、报价单位可能不一样。比如螺纹钢和热卷,一个10吨/手,一个也是10吨/手,但价格差几百块,直接减没问题。可你要是拿铜和铝去减,那就不对了——铜5吨/手,铝5吨/手,但价格差好几万,直接减出来的价差波动巨大,没法用。

我个人习惯用两种方式:

  1. 简单价差:适用于同品种、同市场的近远月合约。比如螺纹钢RB2401和RB2405,直接减就行。
  2. 比例价差:适用于跨品种,或者合约乘数不同的情况。公式是:
价差 = 价格A - 系数 × 价格B

这个系数怎么定?我一般用两种方法:

  • 回归系数法:用历史数据跑一个线性回归,把系数算出来。我在做螺纹钢和热卷的套利时,发现系数长期在1.02附近波动。
  • 固定比例法:比如按合约乘数比例来。铜和铝,铜5吨/手,铝5吨/手,那就1:1。但说实话,这个方法比较粗糙,我很少用。
我的经验: 如果你做的是同品种跨期套利,简单价差就够了。跨品种的话,建议用回归系数法。我曾经在沥青和燃料油上吃过亏,直接减出来的价差,回测曲线漂亮得不行,实盘一跑就崩——后来发现是系数没调对。

5.2 标准化价差(Z-score)

价差算出来了,但问题来了:不同时间点的价差,绝对值不一样,怎么判断它是不是「极端」?

举个例子。螺纹钢的价差,平时在50-100之间波动,突然到了150,你觉得该进场了。但过了一个月,价差中枢上移到了100-150,这时候150还算极端吗?

所以我们需要标准化。Z-score就是干这个的:

Z-score = (当前价差 - 价差均值) / 价差标准差

Z-score告诉你:当前价差偏离均值多少个标准差。一般我们设阈值±2,超过就认为价差「异常」,可以开仓。

代码实现:

import pandas as pd
import numpy as np

def calculate_zscore(spread, window=20):
    mean = spread.rolling(window=window).mean()
    std = spread.rolling(window=window).std()
    zscore = (spread - mean) / std
    return zscore

注意: Z-score依赖滚动窗口。窗口太小,信号太多假突破;窗口太大,反应太慢。我一般从20开始试,然后根据品种波动特性调整。

5.3 滚动窗口参数设置

窗口参数,是价差交易里最让人头疼的事。没有标准答案,只有经验法则。

我常用的窗口设置:

品种类型 推荐窗口(日线) 推荐窗口(小时线) 说明
股指期货 20-30 40-60 波动相对稳定
商品期货(黑色系) 15-25 30-50 波动大,窗口不宜太长
商品期货(农产品) 30-50 60-80 季节性明显,窗口要长
跨品种套利 40-60 80-120 价差回归慢,需要大窗口

你可能会问:为什么跨品种的窗口要这么大?

原因很简单。同品种跨期,价差受持仓成本影响,回归快。跨品种呢?受供需、政策、季节性等多重因素影响,回归周期长。窗口设小了,你看到的全是噪音。

避坑指南: 我曾经在豆粕和菜粕的跨品种套利上,用了20日窗口,结果Z-score频繁触发信号,手续费都亏掉了。后来改成60日窗口,信号质量明显提升。记住:窗口参数不是越大越好,也不是越小越好,要跟品种的「记忆长度」匹配。

5.4 价差序列的平稳性验证

这是最容易被忽略的一步。很多人算完价差,直接跑Z-score,然后开干。结果呢?价差序列不平稳,均值一直在漂移,Z-score的阈值形同虚设。

什么是平稳性?

简单说,就是价差的均值和方差,在时间上保持稳定。如果价差一路向上,或者一路向下,那就不平稳。不平稳的价差,做均值回归套利就是找死。

验证方法:ADF检验

from statsmodels.tsa.stattools import adfuller

def check_stationarity(spread):
    result = adfuller(spread.dropna())
    p_value = result[1]
    if p_value < 0.05:
        print(f"价差序列平稳(p值={p_value:.4f})")
    else:
        print(f"价差序列不平稳(p值={p_value:.4f}),建议差分或换品种")
    return p_value

p值小于0.05,说明序列平稳。大于0.05,你就得小心了。

如果价差不平稳怎么办?

  • 一阶差分:把价差变成价差的变化量。但这样做,你交易的就是「价差的变动」,而不是「价差本身」,逻辑上变了。
  • 换品种对:有些品种天生就不适合做价差交易。比如螺纹钢和铁矿石,虽然产业链相关,但价差长期趋势太强,很难回归。
  • 调整系数:有时候是系数没选对。试试不同的回归系数,看能不能让价差变平稳。
我的习惯: 每次构建新的价差组合,第一件事就是跑ADF检验。不平稳的,直接pass。别浪费时间在垃圾序列上。我记得有一次,一个实习生拿了一组数据给我看,回测收益曲线漂亮得不行。我让他先跑ADF,p值0.8——嗯,那曲线纯粹是运气。

知识体系总览

下面这张图,把价差序列构建的完整流程串起来了。你可以把它当作一个检查清单:

价差序列构建流程 选择品种对 计算价差 简单价差 比例价差 平稳性检验(ADF) 不平稳 平稳 差分/换品种/调系数 计算Z-score 设置阈值,生成交易信号

这张图里,最关键的节点就是「平稳性检验」。很多人跳过了这一步,直接去算Z-score,结果就是反复止损。记住:不平稳的价差,再漂亮的Z-score也是假的。

好了,价差序列构建的核心内容就这些。下一节我们会聊到如何用这些价差信号,构建完整的交易策略——包括开仓、止损、资金管理。但那是后话了,先把今天的内容消化掉。


公众号:蓝海数据掘金营,微信deep3321