合约的最后十秒:我以为市场把波动算高了
我原本想验证一件事:美国经济数据都在整点公布,市场对那一刻的波动率定价准不准。直觉上应该定价不足 —— 大家知道要来,但不知道往哪边走,所以会低估。
结论分两半。事件那部分:市场确实低估了,幅度不小,但样本只有七个月,不足以撑起一个交易。顺着这条线查下去,撞到一个更普遍、样本大得多的偏差,方向还是反的 —— 在每一个五分钟周期的最后十秒,市场看上去都把剩余波动算高了三到四成。
v1.2 修订。那个「三到四成」是我自己的正态假设造出来的,不是市场的错。五分钟比特币收益的峰度是 28,尾巴极厚;市场把厚尾定进了报价,而我用正态去反推隐含波动,就把「正确定价一个厚尾分布」读成了「高估波动」。剥掉这一层之后,真实的偏差只剩下一件事:市场看好的那一边,实际赢的次数比报价多大约一个百分点。这个是真的、样本很大、区间不含零;但它比过路费还小。下面保留了原来的推导和修正过程。
先说我走错的一步
第一版我用的是 Deribit 的 30 天比特币波动率指数,拿它和实际波动比。这是个错误的工具。30 天的隐含波动是把未来一个月摊平的,单独一天的事件在里面只占三十分之一;要从中反推那一天的定价,得先假设其它 29 天的波动率是多少,而这个假设本身就决定了答案。用它做出来的「比值」有一个恒等式在背后,测不出任何东西。
正确的工具是期限正好覆盖事件的合约。Polymarket 的比特币涨跌合约每五分钟结一次,期限只有五分钟,不存在摊平问题。而且它的报价直接就是概率,不需要任何定价模型 —— 报 0.90 就是说九成会涨,九次里错一次才算定价正确。
数据
合约那边抓了两类周期。一类和经济数据发布相关,一类是同一 UTC 时刻、但当天没有任何日历事件的对照。每个周期记下结算结果,以及距结算 270、240、180、120、90、60、45、30、20、10、5 秒这些时刻的报价。日历用的是官方发布时间表,146 个事件,包括每周四的初请失业金、每月的消费者物价指数、非农就业、生产者物价、零售销售、两个采购经理人指数、职位空缺、个人消费支出、国内生产总值,以及联邦公开市场委员会的声明和纪要。
| 合约 | 结算撞上公布 | 公布后首个 | 对照 | 合计 |
|---|---|---|---|---|
| 5 分钟合约 | 364 | 180 | 1386 | 1930 |
| 15 分钟合约 | 300 | 151 | 1386 | 1837 |
价格那边用 Binance 的逐秒成交,覆盖每个五分钟边界前后各两分多钟,45,322 个边界。合约的结算价其实来自 Chainlink 的多所加权,但两者差不到三个基点,拿 Binance 当代理没问题。
抓取有个插曲:Polymarket 的接口从我这台机器现在返回 451,两天前还能用。改成从东京的服务器抓,那边正常。
事件周期:市场确实低估了
先看实际发生了什么。数据公布相关的周期,结算前最后 60 秒的价格变动中位数是 7.3 个万分之一,平常周期是 3.0;超过 20 个万分之一的比例,前者 19.8%,后者 1.7%。也就是实际波动是平常的两倍多,而尾部事件的频率高了十二倍。
再看市场怎么定价的。从报价和当时价格离 strike 的距离,可以反推市场认为剩下这段时间的波动有多大。
| 合约 | 周期类型 | n | 市场隐含 | 实际发生 | 实际 / 隐含 |
|---|---|---|---|---|---|
| 5 分钟合约 | 数据发布周期 | 116 | 8.7 | 15.8 | 3.21 [2.49, 3.97] |
| 5 分钟合约 | 平常周期 | 594 | 7.2 | 4.6 | 1.61 [1.41, 1.81] |
| 15 分钟合约 | 数据发布周期 | 120 | 12.2 | 15.1 | 2.53 [2.01, 3.11] |
| 15 分钟合约 | 平常周期 | 629 | 8.9 | 4.5 | 1.29 [1.13, 1.47] |
五分钟合约:平常周期实际是隐含的 1.6 倍,数据发布周期是 3.2 倍,两个区间不重叠。十五分钟合约同样,2.5 对 1.3。也就是说市场知道数据要来,把隐含波动调高了两成,但实际波动高了两倍多。这个方向和我一开始的猜测一致。
问题是它变不成钱。校准检验里,报价在 0.6 到 0.95 之间、也就是「还没定」的那些周期,买市场不看好的那一边,五分钟合约每份 +2.5%,平常周期是 −2.8%,差 5.3 个百分点,方向对;但 95% 区间从 −8% 到 +14%,而十五分钟合约直接反向。五分钟合约 2026 年 2 月 12 日才上线,七个月只有 146 个事件,拆到「还没定」的周期就剩 100 个。这个量分不开 5% 的边和噪音。
真正普遍的偏差在另一头
换个角度想。美国数据都在整点公布,那么 strike 定在公布瞬间、整段用来消化冲击的,是公布后的那个周期。冲击后的波动是突发再衰减的:前 30 秒极高,最后 30 秒已经回落。如果市场拿一个「平均波动」给整个周期定价,那么周期两头会各错一个方向。
把这个周期里每个时刻的隐含波动和实际波动逐点比出来,结果比我预想的干净。
| 距结算 | 公布后首个·实际 | 隐含 | 实际/隐含 | 平常·实际 | 隐含 | 实际/隐含 |
|---|---|---|---|---|---|---|
| 120 秒 | 11.2 | 11.1 | 1.01 [0.81, 1.19] | 7.5 | 5.7 | 1.30 [1.06, 1.55] |
| 90 秒 | 9.0 | 10.3 | 0.88 [0.67, 1.08] | 5.8 | 5.3 | 1.09 [0.93, 1.26] |
| 60 秒 | 7.7 | 9.3 | 0.82 [0.63, 1.02] | 4.6 | 4.6 | 1.00 [0.87, 1.12] |
| 45 秒 | 6.9 | 9.1 | 0.77 [0.55, 1.01] | 4.1 | 3.9 | 1.06 [0.93, 1.18] |
| 30 秒 | 6.5 | 7.7 | 0.85 [0.64, 1.05] | 3.6 | 3.2 | 1.11 [0.94, 1.29] |
| 20 秒 | 5.9 | 7.6 | 0.77 [0.54, 1.00] | 3.1 | 3.1 | 1.00 [0.85, 1.15] |
| 10 秒 | 4.1 | 7.5 | 0.54 [0.41, 0.67] | 2.6 | 2.7 | 0.96 [0.78, 1.15] |
| 5 秒 | 3.1 | 7.4 | 0.41 [0.30, 0.51] | 2.0 | 2.6 | 0.76 [0.60, 0.96] |
公布后首个周期 105 个,对照 693 个;区间为按交易日重抽的 95%。
实际波动确实在衰减,从 11.2 掉到 3.1,降了七成。市场隐含的却几乎不动,11.1 到 7.4,只降了三成。到距结算十秒时,实际波动是 4.1,市场还按 7.5 在算。
平常周期也有同样的形状,只是弱得多:实际从 7.5 掉到 2.0,隐含从 5.7 掉到 2.6,比值从 1.30 走到 0.76。
这个偏差不限于经济数据
如果这是市场的一个结构性习惯,那它不该只在经济数据上出现,任何刚经历一段高波动的周期都该有。于是我把事件标签扔掉,改用一个事前就能观察到的条件:上一个周期实际发生的波动。按它分成五档,看每档周期尾段的定价。
样本一下子从一百多个涨到 5,622 个五分钟周期。
| 档位 | 事前波动 | n | 距结算 60 秒 | 30 秒 | 10 秒 |
|---|---|---|---|---|---|
| 第 1 档 | 0.6 | 1125 | 1.45 | 1.22 | 0.96 [0.79, 1.14] |
| 第 2 档 | 1.5 | 1124 | 1.17 | 0.98 | 0.76 [0.64, 0.90] |
| 第 3 档 | 2.4 | 1123 | 1.27 | 0.88 | 0.62 [0.55, 0.69] |
| 第 4 档 | 3.7 | 1124 | 1.32 | 1.09 | 0.72 [0.58, 0.93] |
| 第 5 档 | 6.6 | 1125 | 1.00 | 0.94 | 0.66 [0.57, 0.77] |
5,622 个 5 分钟周期,2026 年 2 月 12 日至 9 月 7 日。三列都是「实际 / 隐含」。
五个档位、三个时刻,形状完全一致:距结算 60 秒时市场普遍低估剩余波动,到 10 秒时全部变成高估。中间三档在 10 秒处是 0.62 到 0.72,区间都不含 1。最低波动那一档是 0.96,基本正确 —— 也合理,那些周期本来就没什么波动可衰减。
我的理解是这样。二元合约的报价要回答「剩下这点时间够不够翻过去」,而剩余时间越短,答案越取决于此刻的波动率而不是平均波动率。市场在周期早段大致跟得上,越到后面越跟不上,把早些时候的高波动一直外推到结算。
这个「高估」是我的正态假设造出来的
上面所有的比值都来自同一个反推:报价是 p、当前价离 strike 的对数距离是 x,那么隐含波动 σ = |x| / |Φ⁻¹(p)|。这一步把正态分布焊死在了里面。
比特币五分钟收益不是正态的,而且差得很远。
| 分位 | 实际 |z| | 正态 |z| | 比值 |
|---|---|---|---|
| 90% | 1.42 | 1.64 | 0.86 |
| 95% | 1.97 | 1.96 | 1.00 |
| 99% | 3.68 | 2.58 | 1.43 |
45,504 个周期,标准差 14.5 bps,峰度 28.4(正态是 3),Jarque–Bera 检验 p < 1e−300。
峰度 28,正态是 3。99% 分位的 |z| 实际是 3.68,正态只有 2.58 —— 大跳比正态预测的频繁得多。这对二元合约的影响是直接的:你离 strike 很远、看上去稳赢的时候,厚尾分布给「被反超」留的概率比正态高。所以一个正确给厚尾定价的市场,报出来的赢面会低于 Φ(x/σ),而我拿正态去反推,就会得出「它用了一个更大的 σ」。
差多少,可以直接对账。
| 波动倍数 k | 正确概率 | 每份边 |
|---|---|---|
| 1.20 | 0.9746 | +0.0264 |
| 1.40 | 0.9886 | +0.0405 |
| 1.71 | 0.9973 | +0.0492 |
| 实测 | 0.9576 | +0.0095 |
实测的边只有 +0.0095,反推出来的 k 是 1.06 —— 不是表 3、表 4 里那个 1.4 到 1.7。差额被厚尾吃掉了:正态反推会把「正确定价一个厚尾分布」读成「高估波动」。
如果市场真按 1.71 倍的波动在报价,距结算十秒买它看好的那一边,每份该赚将近 5 分钱。实测只有 0.95 分。反推回去,真实的波动倍数是 1.06,不是 1.71。
也就是说:表 3、表 4、图 2、图 3 里那些 1.4 到 1.7 的比值,绝大部分是厚尾,不是错误定价。它们描述的是「市场的报价不符合正态模型」,这句话是对的,但它不等于「市场错了」。
剩下能站住的只有一件事,而且它本来就不需要任何模型:数报价说自己多有把握,再数它实际对了多少。这个差就是全部的边。
能不能赚钱
偏差的方向说明:在周期最后十秒,市场给「翻转」的定价偏贵,那么买它的反面 —— 也就是市场看好的那一边 —— 应该有正期望。
| 档位 | n | 买入价 | 实际胜率 | 毛收益 / 份 | 单边价差 | 扣价差后 |
|---|---|---|---|---|---|---|
| 第 1 档 | 1125 | 0.959 | 0.972 | +0.0131 [+0.0044, +0.0232] | 0.0095 | +0.0036 |
| 第 2 档 | 1124 | 0.955 | 0.964 | +0.0081 [-0.0030, +0.0187] | 0.0095 | -0.0015 |
| 第 3 档 | 1123 | 0.948 | 0.958 | +0.0100 [-0.0012, +0.0210] | 0.0095 | +0.0005 |
| 第 4 档 | 1124 | 0.947 | 0.954 | +0.0063 [-0.0033, +0.0163] | 0.0095 | -0.0033 |
| 第 5 档 | 1125 | 0.938 | 0.947 | +0.0091 [-0.0014, +0.0195] | 0.0095 | -0.0004 |
买入价即市场当时的报价(折成更可能那边);毛收益 = 实际胜率 − 买入价。区间为按交易日重抽的 95%。
五个档位都是正的,毛收益从 0.63% 到 1.31%,最低波动档显著。按日期分半,前半 +0.80%,后半 +1.01%,两半同号。
然后是成本。我用的报价是成交价,而真要买入得付卖一价,中间差一个价差。用 Roll 估计量从成交序列反推:
| 报价区间 | 有效价差 | 单边成本 |
|---|---|---|
| (0.0, 0.6] | 0.0206 | 0.0103 |
| (0.6, 0.8] | 0.0517 | 0.0259 |
| (0.8, 0.9] | 0.0212 | 0.0106 |
| (0.9, 0.95] | 0.0151 | 0.0075 |
| (0.95, 1.0] | 0.0111 | 0.0056 |
| 全部 | 0.0190 | 0.0095 |
249 个随机周期,每个周期取整段成交带(成交笔数中位 964)。
有效价差中位 1.9%,单边约 0.95%。而毛收益是 0.63% 到 1.31%。扣完之后,只有最低波动那一档还剩 0.36%,其余全部转负。
v1.2:这一段的成本是估的,后来测了,估错了将近一倍。Roll 估计量假设成交方向独立、价格没有趋势。这两条在结算前的周期里都不成立 —— 价格一路朝着结果走。我去实时抓了盘口。
换三种做法再试一次
上面那个检验用的是最笨的一种做法:剩余十秒吃单买进,持有到期。既然偏差在周期两头方向相反,自然该试试别的。
第一种,中途平仓:剩余六十秒买高置信那边,剩余十秒卖掉,不等结算。最高波动那一档每份 2.00%,区间 [0.91%, 3.10%],比持有到期高一倍。但这是两次成交,要付两次价差,一个完整价差就是 1.9%,刚好把它抹平。其余四档都在零附近。
第二种,两条腿:剩余六十秒买翻转(那时市场低估波动),剩余十秒平掉换成买不翻转持有到期。第一条腿五个档位全是负的 —— 六十秒时市场虽然低估了波动,但这没有变成「买翻转赚钱」。合计最好的一档 +1.26%,区间跨零。
第三种也是最狠的一种,严格样本外:用前半段样本挑出最好的那个组合,原封不动套到后半段。前半挑出来的是第 1 档、剩余十秒,样本内每份 3.55%。搬到后半段:0.76%,区间 [0.19%, 1.24%],n = 855。
后半段仍然显著为正,这说明偏差本身是真的、不是挑出来的。但样本内到样本外掉了将近八成,而剩下的 0.76% 对上单边价差 0.95%,净值 -0.19%。
所以吃单这条路是走不通的。三种做法都试过,结论一样:统计上的偏差是真的,交易上的边不够付过路费。
v1.2:上面这一节里的价差都是 Roll 估的 1.9%,已经作废。实测是一分钱。换成实测之后,中途平仓那条的两次过路费从 1.9% 降到 1%,结论会松动。但它同时还多了一项我原来没算的成本 —— 入场价站在盘口哪一侧。下面把两件事一起量出来。
成本:改成实测
两件事要量,一件是价差本身,一件是回测用的那个价到底站在盘口哪一侧。
| 报价区间 | 样本 | 落在买价 | 该补的成本 |
|---|---|---|---|
| 0.50–0.70 | 371 | 41.8% | 0.0042 |
| 0.70–0.85 | 361 | 36.8% | 0.0037 |
| 0.85–0.95 | 437 | 37.8% | 0.0038 |
| 0.95–1.00 | 1,625 | 68.8% | 0.0069 |
707 个周期 × 三个入场时刻,用成交记录自带的买卖方向与结果标的判定。盘口价差实测:9,980 条双边快照里 98.2% 恰好是 0.010,而最小跳只有 0.001。
价差没有悬念:近万条双边盘口快照里,98% 恰好是一分钱,而最小报价单位只有千分之一。做市商稳定挂一分,Roll 估出来的 1.9% 高了将近一倍,作废。
第二件事更要紧,也是我原来没想到的。回测里的「报价」是那一刻之前的最后一笔成交价。成交发生在买价或卖价上,不在中间。用成交记录自带的买卖方向和结果标的一判,在高置信那一档,成交有将近七成落在好的那一边的买价上。也就是说要真买到好的那一边,得往上付一个整价差,不是半个。
这个不对称本身就在说话:高置信档的成交,多数是有人在卖好的那一边。买冷门的人在付价差,收价差的是做市商。
| 入场 | 周期数 | 快照价 | 命中率 | 毛边 | 实测成本 | 净边 |
|---|---|---|---|---|---|---|
| T−60 | 5,847 | 0.866 | 0.876 | +0.0100 [+0.0031, +0.0166] | 0.0053 | +0.0047 [-0.0021, +0.0115] |
| T−30 | 5,895 | 0.916 | 0.923 | +0.0065 [+0.0004, +0.0125] | 0.0059 | +0.0006 [-0.0054, +0.0068] |
| T−10 | 5,899 | 0.948 | 0.958 | +0.0095 [+0.0051, +0.0141] | 0.0063 | +0.0032 [-0.0011, +0.0077] |
三个入场时刻的毛边区间都不含 0,净边区间全部跨 0。
| 入场 | 张数 | 入场价偏离 | 冲击成本 | 总成本 | 净边 |
|---|---|---|---|---|---|
| T−60 | 100 | -0.0012 | 0.0050 | 0.0038 | +0.0062 ($+0.62/周期) |
| T−60 | 300 | -0.0012 | 0.0064 | 0.0051 | +0.0049 ($+1.46/周期) |
| T−60 | 1,000 | -0.0012 | 0.0120 | 0.0107 | -0.0007 ($-0.74/周期) |
| T−60 | 3,000 | — | 三档吃不满 | — | — |
| T−10 | 100 | +0.0019 | 0.0050 | 0.0069 | +0.0026 ($+0.26/周期) |
| T−10 | 300 | +0.0019 | 0.0050 | 0.0069 | +0.0026 ($+0.78/周期) |
| T−10 | 1,000 | +0.0019 | 0.0071 | 0.0090 | +0.0005 ($+0.47/周期) |
| T−10 | 3,000 | +0.0019 | 0.0132 | 0.0151 | -0.0056 ($-16.79/周期) |
T−60 那一档的入场价偏离是负的 —— 在 0.85–0.95 这个报价区间,成交多数落在卖价一侧,快照价本来就高于中价,所以总成本比冲击成本还低一点。盘口三档实时采集。规模到 1,000 张(约 900 美元)时边就被吃光了。
规模也到头得很快。一百到三百张(一两百美元)时净边还在,到一千张就被冲击成本吃光。就算按最好的那一格算满,一天 288 个周期也就四百多美元 —— 而这是「假设边是真的」的上限,不是期望,因为净边的区间本来就跨零。
所以吃单这条路是走不通的,原因和我原来写的一样,只是数字换了一套更可信的。挂单是另一回事:不付价差反而收半个,同样的毛边变成每份一分半。但那已经是做市 —— 要排队、要扛库存、要被逆向选择,而上面那个七成的成交方向不对称说明,愿意站在这一侧的人已经在那里了。
不稳的地方
- 这条原来是「不稳的地方」,现在是主要结论。隐含波动是用正态假设反推的,而价格分布峰度 28。表 3、表 4、图 2、图 3 的比值里,绝大部分是厚尾而不是错误定价(表 7、表 8)。表 5、表 10 的交易检验不受影响,它们只数实际发生率。
- 报价取的是该时刻之前的最后一笔成交,不是盘口中间价。我原来以为它平均落在中间价上,实测不是 —— 高置信档七成落在买价那一侧(表 9)。成本已按实测比例逐档补回。
- 盘口只连续采了 43 个周期、约四小时,而交易检验跨七个月。一分钱的价差在这四小时里极其稳定(98%),但我没有证据说它在整个回测期都是这样。这是现在最弱的一环。
- 冲击成本只用了盘口前三档。要吃更大的量得看更深,我没有采。
- 事件那部分只有 146 个事件、七个月。五分钟合约 2026 年 2 月才上线,没法再往前拉。
- 分档用的「事前波动」是上一个周期的实际波动,事前可观察,但它和当前周期的波动相关性有限,分档因此是粗的。
- 结算价用 Binance 代理 Chainlink,两者差不到三个基点,但在贴近 strike 的周期里,这个差足以改变个别周期的结果判定。
- 2026 年 8 月 7 日起结算规则从瞬时快照改成 30 秒均价、8 月 14 日起改成 60 秒均价。均价规则本身会压低最后十秒的有效波动,这可能是「尾段被高估」的一部分成因,我没有把两个制度分开测 —— 样本不够。
最后
- 市场对经济数据发布时刻的波动率确实定价不足:实际波动是市场隐含的 3.2 倍,平常周期只有 1.6 倍。方向和我的猜测一致,但七个月的样本撑不起交易检验。
- 「周期尾段市场高估剩余波动 1.4 到 1.6 倍」这句话不成立,那是正态反推的产物。比特币五分钟收益峰度 28,市场把厚尾定进了报价。按实测校准反推,真实的波动倍数是 1.06。
- 剥掉模型之后剩下的是:市场看好的那一边,实际赢的次数比报价高约一个百分点。5,900 个周期,三个入场时刻的区间都不含零。这个不依赖任何分布假设。
- 成本是实测的,不是估的。盘口价差 98% 恰好一分钱(Roll 估的 1.9% 高了近一倍);而回测入场价在高置信档有七成落在买价一侧,要买好的那边得补一个整价差。扣完之后三个净边区间全部跨零。
- 规模到一千张就被冲击成本吃光。就算按最好的一格算满,一天 288 个周期也只有四百多美元,而这是上限不是期望。
- 唯一没被排除的还是挂单:不付价差反而收半个,同样的毛边变成每份一分半。但成交方向的不对称(高置信档七成是有人在卖好的那一边)说明,这一侧的位置已经有人占着了。
复现:抓取脚本跑在服务器上(本机接口被封),分析在本地。合并了这次抓的 2,268 个周期和之前那篇留下的 6,312 个,去重后 8,503 个,能配上逐秒价格的 5,622 个。
区间都是按交易日重抽的 95%。数字随方法修订会更新(v1.1,2026-09-09:补上中途平仓、两腿组合与严格样本外三项检验。v1.2,2026-09-11:发现「市场高估波动」是正态反推的产物,改用无模型校准;价差与入场价一侧改为实时盘口实测,替换掉 Roll 估计;补容量测算)。