12、基差回归在商品期货中的应用:螺纹钢、铁矿石、豆粕等品种的实证分析
聊了这么多理论,咱们得真刀真枪干一场。
我个人习惯,做量化模型最怕的就是「纸上谈兵」。你想想看,回测曲线再漂亮,拿到实盘里一跑就变形,那才叫一个难受。所以这一章,我挑了几个我实际交易过的品种——螺纹钢、铁矿石、豆粕,带大家看看基差回归模型到底怎么用,有哪些坑。
12.1 为什么选这三个品种?
说白了,选品种有讲究。不是所有商品期货都适合做基差回归。
我选它们的理由很简单:
- 流动性好:进出方便,滑点可控。你做个冷门品种,一天成交几千手,基差信号出来了你进不去,那模型再牛也没用。
- 产业逻辑清晰:螺纹钢看地产和基建,铁矿石看钢厂补库,豆粕看生猪存栏和压榨利润。基差的波动背后有实实在在的供需驱动,不是纯资金博弈。
- 基差波动大:这三个品种的基差经常出现极端值,给回归模型提供了充足的交易机会。
核心观点:基差回归模型赚的是「情绪溢价」和「时间溢价」的钱。当市场因为恐慌或过度乐观把基差推到极端位置时,就是我们出手的时候。
12.2 螺纹钢:最经典的基差回归案例
螺纹钢是我做基差交易的启蒙品种。记得2017年那会儿,我刚开始研究这个模型,就被螺纹钢的基差走势上了一课。
12.2.1 数据特征
螺纹钢的基差有个明显规律:近月合约受现货影响大,远月合约更多反映预期。每年到了冬储季节(11月-次年1月),现货价格往往坚挺,而期货因为预期年后需求走弱,经常贴水。这时候基差会拉得很大。
我曾经统计过2015-2020年的数据,螺纹钢主力合约基差的均值在80元/吨左右,但标准差能达到150元/吨。什么意思?就是基差经常跑到±2倍标准差之外,然后慢慢回归。
12.2.2 模型构建
我个人习惯用滚动窗口的Z-score来捕捉回归机会。代码很简单,但效果不错:
import pandas as pd
import numpy as np
# 假设df包含日期、现货价、期货价
df['basis'] = df['spot'] - df['futures']
df['zscore'] = (df['basis'] - df['basis'].rolling(60).mean()) / df['basis'].rolling(60).std()
# 交易信号:Z-score超过2倍标准差做多基差(买现货卖期货),低于-2倍做空
df['signal'] = 0
df.loc[df['zscore'] > 2, 'signal'] = -1 # 基差过大,预期回归,做空基差
df.loc[df['zscore'] < -2, 'signal'] = 1 # 基差过小,预期走扩,做多基差
避坑指南:我曾经吃过一次大亏——2018年螺纹钢基差在-2倍标准差以下持续了整整两周,模型连续止损。后来我加了持仓量过滤:只有当持仓量也在历史低位时,才确认基差回归信号有效。因为持仓量低说明市场分歧小,回归概率更高。
12.3 铁矿石:外盘定价的复杂性
铁矿石跟螺纹钢不一样。它是个全球定价的品种,普氏指数、新加坡掉期、大商所期货,三者之间互相影响。基差回归模型在这里会遇到更多挑战。
12.3.1 基差结构
铁矿石的基差通常表现为近高远低的Back结构。为什么?因为铁矿石的储存成本高,而且钢厂更愿意用近月货来保证生产连续性。
我记得2021年有一波行情,铁矿石基差从150元/吨一路拉到400元/吨。当时很多做回归的人被打爆了。为什么?因为那波是结构性变化——巴西淡水河谷的矿区停产,导致现货供应极度紧张,基差就是回不来。
重要提醒:基差回归模型最怕的就是结构突变。遇到政策变化、矿山事故、贸易争端,模型必须暂停。我现在的做法是:在模型里加一个波动率阈值,当基差的20日波动率超过历史95%分位数时,自动停止交易。
12.3.2 改进方案
针对铁矿石,我建议用跨品种基差来辅助判断。比如:
- 铁矿石基差 + 螺纹钢基差:两者走势背离时,往往意味着产业链利润在重新分配
- 铁矿石基差 + 海运费:海运费暴涨时,外盘成本上升,国内基差容易走扩
12.4 豆粕:农产品基差的季节性
豆粕的基差回归,跟工业品完全是两码事。它的核心驱动是季节性和压榨利润。
12.4.1 季节性规律
豆粕的基差有明显的双峰结构:
| 时间段 | 基差特征 | 驱动因素 |
|---|---|---|
| 3月-5月 | 基差走强 | 南美大豆到港延迟,国内压榨厂挺价 |
| 7月-9月 | 基差走弱 | 美豆丰产预期,下游养殖需求淡季 |
| 10月-12月 | 基差再次走强 | 生猪补栏旺季,豆粕需求上升 |
你看,这个规律每年都在重复。我刚开始做豆粕时,就是靠这个季节性规律赚了第一桶金。
12.4.2 模型调整
对于豆粕,我不用固定窗口的Z-score,而是用同期对比法:
# 计算过去5年同一天的基差均值和标准差
df['seasonal_mean'] = df.groupby(df.index.dayofyear)['basis'].transform('mean')
df['seasonal_std'] = df.groupby(df.index.dayofyear)['basis'].transform('std')
df['adjusted_zscore'] = (df['basis'] - df['seasonal_mean']) / df['seasonal_std']
这样做的好处是:剔除了季节性因素,只捕捉异常偏离。比如今年3月的基差比过去5年同期都高,那才是真正的交易机会。
个人经验:豆粕的基差回归周期比工业品短。螺纹钢的基差回归可能需要2-4周,但豆粕往往在1周内就完成。所以持仓周期要相应缩短,止盈止损也要设得更紧。
12.5 三个品种的对比总结
嗯,到这里,我把三个品种的核心差异捋一捋:
| 维度 | 螺纹钢 | 铁矿石 | 豆粕 |
|---|---|---|---|
| 基差驱动 | 冬储、地产政策 | 矿山供应、海运费 | 季节性、压榨利润 |
| 回归周期 | 2-4周 | 1-3周 | 3-7天 |
| 主要风险 | 政策突变 | 结构性供应冲击 | 天气炒作 |
| 模型选择 | 滚动Z-score | 跨品种辅助 | 同期对比法 |
你想想看,这三个品种代表了三种不同的基差生态。螺纹钢是「国内定价+政策驱动」,铁矿石是「全球定价+供应冲击」,豆粕是「季节性+产业链利润」。做基差回归,不能一个模型打天下,得根据品种特性灵活调整。
12.6 核心知识体系
下面这张图,是我自己总结的基差回归模型在商品期货中的应用框架。每次做新品种之前,我都会对照着过一遍:
这张图我用了好几年,每次做新品种都会拿出来对照。你想想看,从品种选择到数据准备,再到模型选择和风控,每一步都不能少。尤其是风控那一步,我吃过太多亏了。
最后说一句:基差回归不是万能钥匙。它适合在震荡市和趋势初期使用。一旦进入单边暴涨暴跌行情,基差可能会持续偏离,这时候做回归就是接飞刀。我现在的做法是:结合趋势指标(比如20日均线)来判断市场状态,趋势明显时就暂停基差策略。
公众号:蓝海资料掘金营,微信 deep3321