套保压力假说:商品期货的风险溢价,是生产商付给投机者的过路费
商品期货多头为什么长期有正收益?凯恩斯的 normal backwardation 给出答案:生产商天然想做空对冲,逼投机者接盘做多,投机者要溢价才肯来。固定种子 20260801 受控模拟 24 个品种、10 年月度数据:把每个品种的结构性套保压力(净空头对冲,用 COT 式代理观测)作为横截面信号,做多高套保压力、做空低套保压力,因子 Sharpe 1.21 远超商品大盘等权 0.56,对大盘 β 仅 0.19、五分位实现收益单调递增(Q1 -0.3% → Q5 16.0%)、10/10 年为正。套保压力与展期收益强正相关(斜率 0.50),印证 backwardation 品种展期为正。四项对抗式检验全过:关掉套保压力(κ=0,50 次均值)因子 Sharpe 0.03、打乱套保压力标签置换 300 次 95 分位 0.71、COT 代理观测噪声越大因子越弱(std=0→1.16、std=3→0.25)。最刺眼的是 look-ahead 对照:用当月收益本身排序刷出荒诞的 Sharpe 22——任何回测出现这种数字必是偷看了未来。
问题:商品期货多头的钱,到底是谁付的?#
买入并长期持有商品期货多头,历史上能赚到正收益。但这笔钱从哪来?商品本身不像股票有分红、不像债券有票息,一桶原油放十年不会自己生出钱来。那么期货多头的正收益,必然来自别人愿意付给你的一笔钱。
凯恩斯(Keynes)在 1930 年代给出了一个至今仍是商品定价基石的答案——正常现货溢价(normal backwardation),其背后的机制叫套保压力假说(hedging pressure hypothesis):
- 生产商天然是净空头:一个种玉米的农民、一家开采原油的公司,最怕的是收获/开采时价格暴跌。他们会卖出期货锁定未来售价——这是天然的套保需求,方向是做空。
- 投机者被迫接盘做多:期货是零和的,有人卖就得有人买。生产商大量做空对冲,市场就需要投机者来做多接盘。
- 投机者要溢价才肯来:投机者承担价格风险,不是做慈善。他们要求期货价格系统性地低于预期的未来现货价,这样等期货到期收敛到现货时,多头就赚到了这段差价。
结论就是凯恩斯的洞见:期货价格 < 预期现货价,多头长期获得正的风险溢价。这笔溢价,本质上是生产商为了转移价格风险,付给投机者的”过路费”。
这个假说有个漂亮的可检验推论:套保压力越大的品种(生产商套保越重),多头风险溢价应该越高。 本文用固定种子 20260801 造一个 24 个商品品种、10 年月度数据的世界,检验:套保压力能不能横截面预测商品期货收益?它和展期收益什么关系?做成多空因子稳不稳?以及——如果偷看未来,这个因子会变成什么样的怪物?
一、套保压力越大,多头溢价越高#
我给每个品种设一个结构性套保压力:净空头对冲比例(生产商套保减去消费者套保)。这个值越大,说明生产商的套保需求越占主导,市场越需要投机者做多接盘——按凯恩斯理论,这个品种的多头风险溢价就该越高。能源和农产品的生产商套保通常很重(净空头压力大),工业金属相对轻一些。
真实的月度风险溢价我设成正比于套保压力(),然后在此之上叠加商品大盘共同因子和品种特异波动。注意:投机者观测到的套保压力不是真值——现实里我们用 CFTC 的 COT(持仓报告)来代理套保压力,它是带噪声的、时变的。

左图是核心证据:横轴是结构性套保压力,纵轴是各品种 10 年的年化实现收益,散点清晰地向右上方倾斜(拟合斜率 0.11)。套保压力越大的品种,多头确实赚得越多——这正是套保压力假说的横截面预言。
右图揭示了一个连接现货市场和期货曲线的关键事实:套保压力与展期收益(roll yield)强正相关(斜率 0.50)。展期收益是持有期货、不断把近月合约展期到远月时赚(或亏)的钱。当生产商大量做空、把近月压低,期货曲线呈现 backwardation(近高远低),此时展期是正收益——你不断卖出较贵的近月、买入较便宜的远月,赚取价差。套保压力、backwardation、正展期收益,是同一枚硬币的三个面。 这也是为什么商品因子研究里,“套保压力”和”展期收益/期限结构”两个信号高度相关——它们测的是同一个底层经济学。
二、做成多空因子:Sharpe 1.21,对大盘近乎中性#
有了横截面信号,构造因子就很直接:每月末按可观测的套保压力代理排序,做多套保压力最高的 6 个品种、做空最低的 6 个,等权,下月持有。信号严格用上月末的数据(因果,不偷看未来)。
import numpy as np
def long_short_portfolio(signal_t, returns, q=6):
"""每月按套保压力信号分组,做多高组、做空低组,等权
signal_t: (M, N) 因果信号(用上月末);returns: (M, N) 月度收益"""
M = returns.shape[0]
pnl = np.zeros(M)
for t in range(1, M):
order = np.argsort(signal_t[t-1]) # 关键:用上月末信号,不偷看当月
short_idx, long_idx = order[:q], order[-q:]
pnl[t] = returns[t, long_idx].mean() - returns[t, short_idx].mean()
return pnl
def sharpe_m(pnl):
p = pnl[1:]
return p.mean() / p.std() * np.sqrt(12) if p.std() > 0 else 0.0
# 陷阱对照:把 signal_t[t-1] 换成 returns[t](当月收益)就是 look-ahead,
# Sharpe 会从 1.21 飙到 22——任何这种数字都是偷看未来的铁证。python
左图对比套保压力多空因子和商品大盘等权买入持有:因子 Sharpe 1.21,远超大盘的 0.56。而且因子净值曲线明显更稳、回撤更浅——因为它是多空对冲的,剥离了商品大盘的方向性风险。
右图证实了这一点:因子月收益对大盘月收益的散点几乎是一团云,相关系数只有 0.24、β 仅 0.19。这个因子赚的不是”商品涨”的钱,而是”高套保压力品种相对跑赢低套保压力品种”的钱——一个真正的横截面 alpha,而非伪装成 alpha 的商品 beta。这个区分很重要:如果一个”商品因子”其实和大盘高度相关,那它在商品熊市里会和大盘一起趴下,根本不是分散化的收益源。
三、单调性与稳定性:因子的两块试金石#
一个横截面因子可信不可信,先看两件事:分组是否单调、收益是否稳定。

左图把品种按套保压力分成五组,看各组的年化实现收益:Q1(最低套保压力)-0.3%、Q2 4.7%、Q3 11.9%、Q4 12.3%、Q5(最高)16.0%——几乎完美单调递增。单调性是因子真实性的强证据:如果只有最高组和最低组有差异、中间乱成一团,那多半是尾部的少数极端品种在驱动,因子很脆。这里的干净单调说明套保压力和溢价之间是稳定的、连续的关系。
右图是因子的年度收益:10 年里 10 年为正。没有靠某一两年的暴利撑起整段业绩,收益分散在各个年份——这是一个健康因子该有的样子。当然,这是模拟世界里套保压力结构相对稳定的结果,真实市场的套保压力会随产业格局、投机者结构变化而波动,不会这么整齐。
四、对抗式检验:这 1.21 经得起拷问吗?#
一个 Sharpe 1.21、对大盘中性、单调、年年为正的因子,太完美了,完美到必须往死里查。四个对抗式检验直击要害。

图4a:关掉套保压力,因子还赚钱吗? 这是最根本的检验。我把风险溢价的来源彻底关掉(,即套保压力不再产生任何溢价,收益纯由大盘因子和噪声构成),重跑因子。为避免单次抽样的运气(单条 null 世界可能凑巧刷出高 Sharpe),我跑 50 次独立抽样取均值:因子 Sharpe 0.03,紧贴零。这证明因子的收益完全来自套保压力这个真实机制,而不是数据挖掘或排序本身的某种统计假象。注意:这个”多次取均值”的细节很关键——如果只跑一次 null 世界,你可能撞上一个 Sharpe 0.6 的幸运样本,误以为因子有问题;对抗式检验本身也需要防过拟合。
图4b:look-ahead 会造出什么怪物? 我把排序信号从”上月套保压力”换成”当月收益本身”(直接偷看本月哪些品种涨得好,做多它们、做空跌得差的),Sharpe 飙到 22。这是一个荒诞到一眼假的数字——任何回测里出现 Sharpe 十几、二十几,第一反应必须是”我一定在某处偷看了未来”,而不是”我发现了圣杯”。 这个对照的价值在于给你一把标尺:真因子的 Sharpe 是 1.21,look-ahead 版本是 22,两者差了一个数量级。当你的回测结果异常漂亮时,拿它和”故意 look-ahead”的版本比一比,就知道自己离作弊有多近。
图4c:置换检验。 我把品种的套保压力标签随机打乱(保留收益数据,只破坏”哪个品种对应哪个套保压力”的映射),跑 300 次,得到零假设下的 Sharpe 分布:95 分位 0.71,最大 1.09。真实因子的 1.21 超过了全部置换的 95 分位、也超过最大值——说明因子收益来自套保压力和收益之间真实的对应关系,而不是随便贴个标签也能刷出来的运气。
图4d:COT 代理噪声敏感性——因子的现实软肋。 现实里我们观测不到真实套保压力,只能用 COT 持仓报告来代理,而这个代理是带噪声的。我给套保压力信号叠加不同强度的观测噪声,看因子怎么衰减:噪声 std=0 时 Sharpe 1.16,std=1.0 时 0.64,std=3.0 时只剩 0.25——单调下降。这条曲线是套保压力因子在实盘里的命门:你的信号有多好,取决于你的 COT 代理有多干净。 COT 数据分类粗糙(商业 vs 非商业的划分并不完美对应真实套保 vs 投机)、公布有滞后、频率是周度,这些都是给信号注入噪声的渠道。因子理论上成立,实盘能吃到多少,取决于你能把套保压力测得多准。
三段式总结#
A. 实现细节#
- 数据生成:24 个商品品种、120 个月(10 年)月度收益。每个品种设一个结构性套保压力(净空头对冲比例),真实月度风险溢价正比于套保压力(),在此之上叠加商品大盘共同因子和品种特异波动(月度 4%~7%)。固定种子
20260801。 - 信号构造:投机者观测的是带噪声、时变的套保压力代理(模拟 COT 报告),严格用上月末信号排序(因果)。
- 因子构造:每月做多套保压力最高 6 个品种、做空最低 6 个,等权,多空对冲。收益与商品大盘等权买入持有对比。
- 对抗式检验:(1) 关掉套保压力()跑 50 次取均值;(2) 用当月收益 look-ahead 排序;(3) 打乱套保压力标签置换 300 次;(4) 给信号叠加不同强度观测噪声的敏感性扫描(每档 40 次取均值)。
B. 已知偏差#
- 套保压力是外生设定的:本文直接把”套保压力→溢价”的线性关系写进数据生成,而没有从生产商/投机者的最优对冲决策里内生推导。真实世界这个关系的强度、稳定性是经验问题,会随产业集中度、投机资本流入(商品指数化投资的兴起就显著改变了套保压力结构)而变化。
- COT 代理的现实缺陷未完全建模:本文用”真值+高斯噪声”近似 COT 代理,但真实 COT 的问题更复杂——商业/非商业分类不完美、掉期交易商归类模糊、周度公布且有滞后、部分品种持仓集中。图4d 的噪声敏感性只是一个方向性提示。
- 无交易成本与展期成本:商品期货多空、每月调仓、频繁展期都有真实成本(买卖价差、展期滑点、保证金占用),本文未建模。商品期货流动性差异大(原油 vs 小品种),冲击成本可能吃掉相当一部分因子收益。
- 品种同质假设:模拟里品种的特异波动同质、无极端跳跃。真实商品有剧烈的供给冲击(天气、地缘、减产),天然气这类品种的波动和肥尾远超模型设定,因子在这些冲击下的表现会更颠簸。
- 纯多头/纯空头的现实约束:做空部分商品期货在某些市场/合约上流动性不足或成本高,纯多空因子的空头腿实盘可能打折。
C. 结果解读#
- 商品期货溢价有坚实的经济学根基:套保压力假说不是数据挖掘出来的经验规律,而是有清晰因果机制的理论——生产商付过路费、投机者收过路费。本文在一个套保压力严格驱动溢价的世界里复现了它的全部预言(横截面单调、与展期收益正相关、多空 Sharpe 1.21),图4a 关掉机制后因子归零更是直接证明了收益来源。这种”机制可解释”的因子,比纯统计挖出来的因子稳健得多。
- 套保压力和展期收益是同一个东西的两面:斜率 0.50 的正相关说明,做商品因子时你不需要在”套保压力”和”期限结构/展期收益”之间纠结——它们高度相关,都在捕捉 backwardation 这个底层结构。实盘里展期收益(期货曲线斜率)通常比 COT 更容易、更及时地观测,可能是更实用的信号载体。
- look-ahead 的标尺价值:图4b 里 Sharpe 22 的怪物不是笑话,是工具。它告诉你”如果我偷看未来,这个策略能好到什么程度”,从而给真实结果一个上界参照。真因子 1.21 vs look-ahead 22,差一个数量级——当你的回测 Sharpe 逼近这个 look-ahead 上界时,几乎可以肯定你的因果性出了问题。
- 因子的实盘上限由信号质量决定:图4d 是这篇文章给实盘最重要的提醒。套保压力因子理论上成立,但你能吃到多少完全取决于 COT 代理有多干净——噪声从 0 加到 3,Sharpe 从 1.16 掉到 0.25。在商品因子上,胜负往往不在”用不用套保压力”,而在”你的套保压力测得比别人准多少”。 这也解释了为什么同样做商品 carry/套保压力的机构,业绩能差出一大截。
- 适用边界:套保压力因子适合能交易多品种商品期货、能承受展期成本、能获取并清洗 COT 数据的机构。它在套保压力结构稳定的常态市场里是稳健的横截面收益源,但在商品指数化资金大进大出、或供给端剧烈冲击(如能源危机)时,套保压力结构会被打乱,因子会失灵甚至反向。先确认你的信号源(COT/期限结构)的质量,再决定这个因子在你的组合里配多重。