卖认沽期权:Kelly 仓位要不要加一个“暴跌下限”?
数据:六个 A 股指数(上证50、沪深300、中证500、中证1000、创业板指、科创50)的日收盘价,从 2005-01-04(或指数的第一个收盘价)到 2026-09-30(新浪,通过 AKShare 获取),以及 50ETF 和 300ETF 期权的 QVIX 隐含波动率指数。模型一侧:本站为每个期权标的保存的平值隐含波动率在 2024–2026 年的中位数。仓位回放:本站记录的 2026-09-24 收盘期权链(10 条期权链,17 笔裸卖认沽)。
不加暴跌下限。本站的 Kelly 仓位已经包含了大跌历史频率的大部分;差距集中在平静、低波动的标的上,而大跌并不从那里开始;卖认沽的仓位由各项上限决定,而不是由 Kelly 比例决定。本站没有任何改动。
- 1.24 %:六个 A 股指数中,某个指数在 21 个交易日后收盘下跌 20 % 或更多的交易日占比(2005–2026 年,95 % 区间 0.68–2.08 %,14 段独立行情)。
- 0.79 %:在今天的典型隐含波动率下,本站 Kelly 所用的波动率区间给出的同一概率,约为历史频率的三分之二。同样波动率下的单一对数正态分布只给出 0.35 %。
- 上证50 和沪深300 只有约十分之一:波动率区间给出 0.064 % 和 0.11 %,历史是 0.72 % 和 1.01 %(11 倍和 9 倍)。它们今天的隐含波动率很低(约 19–20 %)。
- 2016 年以来为 0:2015 年以后,上证50 和沪深300 没有一次 21 天内下跌 20 %。合并计算,模型比 2016 年以来的历史更肥(0.96 % 对 0.17 %)。
- 300 天中有 264 天:发生大跌的交易日里,开始时市场已实现波动率已经在 30 % 或以上的天数。从 20 % 以下开始,随后出现 20 % 下跌的交易日只有 0.039 %。
- 0–0.31:按本站的方式定仓位,样本期权链上虚值 5–10 % 的裸卖认沽的 Kelly 比例。不是上限 1;决定仓位的是 5 % 上限和最少一张合约。
- 是开关,不是旋钮:暴跌下限对高波动率的期权链毫无作用,却会让所有低波动率的 50ETF / 300ETF 卖认沽变成不交易。
- 事先定好:数据、度量、下限规则和三项通过检验都在计算任何频率之前提交。三项检验全部未通过。
什么是暴跌下限,为什么它对卖认沽的人重要
本站用 Kelly criterion(凯利公式)定仓位:选出投入资金的比例,使财富长期增长最快;它在到期价格的概率分布上计算(本站的做法)。本站建议取这个比例的一半,且每笔不超过组合的 5 %。
naked short put(裸卖认沽)是最难的情况。你收一点权利金;如果标的跌到零,你亏掉行权价减去权利金。一张以 0.05 卖出的 50ETF 3.0 认沽,赚 ¥500,最多可能亏 ¥29,500。所以仓位最主要取决于一件事:模型认为大跌有多大可能。如果模型的左尾太薄,Kelly 就会在恰好会被暴跌摧毁的交易上下注过多。
暴跌下限就是针对这一点的补丁:不论模型怎么说,都至少给大跌一个来自历史的固定概率。这里的规则按事先定好的方法从数据中得出:在 21 天期限上,只要模型在下跌 20 % 以下的概率不足 1.2 %,就在下跌 25 % 的位置补足到 1.2 %(按到期天数成比例缩放,其余部分平移,使分布的均值不变)。
加这个补丁之前,要先回答三个问题:大跌实际发生得有多频繁?比本站模型说的频繁多少?这个补丁会不会改变你实际的交易量?
我们怎么检验
- 下跌。 对六个指数中的每一个、2005-01-04 以来的每个交易日(“起始日”)、以及 10、21、42 个交易日三个期限:窗口结束时,指数收盘是否比起始日低至少 10、15、20、30 或 40 %?主要问题是 21 天、下跌 20 % 或更多:大约一个近月合约的期限,也是模型认为非常罕见的跌幅。每个指数代表一个期权标的(上证50 → 50ETF,沪深300 → 300ETF,中证500 → 500ETF,中证1000 → 中证1000股指期权,创业板指 → 创业板ETF,科创50 → 科创50ETF)。
- 按行情计,而不是按天计。 一次暴跌会连续产生很多个命中日,它们并不独立。与前一个命中日相隔不超过期限的命中日算同一段行情,95 % 区间按行情数计算。六个指数合并时,一次全市场暴跌算一段行情,而不是六段。第二种区间按整个日历年重新抽样。
- 模型。 在每个标的的典型波动率下,本站模型给出同一跌幅的概率:本站的预测是 0.95 × at-the-money(ATM,平值)implied volatility(IV,隐含波动率)(为什么是 0.95),这里取 2024–2026 年保存的平值隐含波动率的中位数。两个版本:该波动率下的单一 lognormal(对数正态分布),以及 Kelly 实际使用的波动率区间:它对波动率预测本身的不确定性取平均(高波动率一侧有意加重)。
- 仓位回放。 用本站自己的 Kelly 仓位计算,在 2026-09-24 收盘记录的期权链上:17 笔虚值约 5 % 和 10 % 的裸卖认沽(另外 3 笔因期权链上远端行权价太少而无法构建),分别计算加与不加暴跌下限。
- 采用下限的三项检验,必须全部通过:
- (a) 模型太薄:合并历史区间的下端至少是波动率区间概率的 10 倍;
- (b) 它改变仓位:至少一半的裸卖认沽,仓位下降至少 20 %;
- (c) 它稳健:只看 2016 年以后,以及分别去掉三段最大的行情时,(a) 仍然成立。
数据、期限、度量、下限的计算方法和三项检验,都在计算任何频率或加下限后的比例之前写下并提交。执行这些检验的代码与结果一起提交,与书面规则逐字一致。检验 (b) 设定时已知道一项输入:样本期权链上今天的仓位,其中大多数已经在 5 % 上限。下面按已实现波动率的拆分是在结论之后加入的,出现处都有标注。

21 个交易日内下跌 X 或更多:2005–2026 年的历史,对比本站模型在各指数典型隐含波动率下的结果。
大跌发生得有多频繁
21 个交易日结束时下跌 20 % 或更多,起始日从 2005-01-04 到窗口结束于 2026-09-30 的那一天。“典型波动率” = 0.95 × 2024–2026 年保存的平值隐含波动率中位数。
| 指数 | 典型波动率 | 起始日 | 命中日 | 行情数 | 历史 [95 % 区间] | 单一对数正态 | 波动率区间(Kelly) | 历史 ÷ 波动率区间 |
|---|---|---|---|---|---|---|---|---|
| 合并(6 个) | — | 24,233 | 301 | 14 | 1.24 % [0.68 %, 2.08 %] | 0.35 % | 0.79 % | 1.6 倍 |
| 上证50 | 17.8 % | 5,261 | 38 | 8 | 0.72 % [0.31 %, 1.42 %] | 0.0008 % | 0.064 % | 11 倍 |
| 沪深300 | 19.3 % | 5,261 | 53 | 9 | 1.01 % [0.46 %, 1.91 %] | 0.0035 % | 0.11 % | 9 倍 |
| 中证500 | 27.8 % | 5,261 | 98 | 8 | 1.86 % [0.80 %, 3.67 %] | 0.31 % | 0.92 % | 2 倍 |
| 中证1000 | 27.7 % | 2,888 | 49 | 6 | 1.70 % [0.62 %, 3.69 %] | 0.30 % | 0.91 % | 1.9 倍 |
| 创业板指 | 30.7 % | 3,947 | 53 | 7 | 1.34 % [0.54 %, 2.77 %] | 0.67 % | 1.5 % | 0.91 倍 |
| 科创50 | 37.1 % | 1,615 | 10 | 3 | 0.62 % [0.13 %, 1.81 %] | 2.1 % | 3.1 % | 0.2 倍 |
(合并的模型概率是六个指数的概率按起始日数加权。)
- 合并计算,模型包含了约三分之二的历史频率(0.79 % 对 1.24 %)。区间下端 0.68 % 甚至低于模型的 0.79 %,所以要求它达到模型 10 倍的检验 (a) 远远没有通过。
- 结果取决于标的。 上证50 和沪深300 的历史是波动率区间的 11 倍和 9 倍:在今天的低隐含波动率下,模型在这两个指数上太薄。即使是它们区间的下端,也是模型的 4.9 倍和 4.1 倍。中证500、中证1000 和创业板指为 0.91–2 倍。波动率最高的科创50,模型比历史更肥(0.2 倍)。
- 较小的跌幅吻合得更好。 下跌 15 % 或更多:合并历史 2.99 %,波动率区间 2.6 %(1.1 倍);上证50 5.2 倍,沪深300 3.9 倍。
区间比看上去更宽。 主区间把每段行情的命中日数当作固定,只让行情数变化。最大的一段行情(2015-05-28 至 2015-08-20)占了 301 个命中日中的 102 个。如果改为按整个日历年重新抽样(bootstrap,自助法),合并的下界是 0.11 %(而不是 0.68 %),上证50 是 0.00 %,沪深300 是 0.04 %。
2016 年以来,以及去掉最大的几次暴跌
| 样本 | 命中日 / 起始日 | 行情数 | 历史 [95 % 区间] | 波动率区间 |
|---|---|---|---|---|
| 全部历史 | 301 / 24,233 | 14 | 1.24 % [0.68 %, 2.08 %] | 0.79 % |
| 起始日从 2016-01-04 起 | 25 / 14,565 | 5 | 0.17 % [0.06 %, 0.40 %] | 0.96 % |
| 去掉 2015-05-28 → 2015-08-20(102 个命中日) | 199 / 23,933 | 13 | 0.83 % [0.44 %, 1.42 %] | 0.79 % |
| 去掉 2015-12-10 → 2016-01-04(51 个命中日) | 250 / 24,148 | 13 | 1.04 % [0.55 %, 1.77 %] | 0.79 % |
| 去掉 2008-05-12 → 2008-06-04(45 个命中日) | 256 / 24,179 | 13 | 1.06 % [0.56 %, 1.81 %] | 0.79 % |
- 2016 年以来,模型比历史更肥(0.96 % 对 0.17 %,5 段行情),主要在高波动率的指数上。全部历史的 301 个命中日中,有 276 个的起始日在 2016 年之前,其中 265 个在 2008 年和 2015 年。
- 2016 年以来,上证50 和沪深300 没有一次 20 % 的下跌,这既不能证实也不能否定它们 0.06–0.11 % 的模型概率。2016 年以来下跌 15 % 或更多:上证50 没有;沪深300 在一段行情中有 2 天(2016-01-05 和 01-06)。
- (去掉单段行情的几行与全部历史的模型概率比较;按每个样本保留的起始日重新计算,变化最多 0.0012 个百分点。)
其他期限。 频率的增长快于期限的增长:下跌 20 %,10 天为 0.42 %,21 天 1.24 %,42 天 2.91 %。按到期天数成比例缩放的下限,会在短期合约上放太多权重,在长期合约上放太少。路径也很重要:在 21 天内任何一天收盘比起始日低 20 % 或更多的情况,出现在 2.17 % 的交易日上;只看窗口结束时是 1.24 %。持有到期的认沽只看结束时;追加保证金看的是路径。

按起始日,六个指数中 21 天后最差的涨跌幅。20 % 以上的下跌集中在 2008 年和 2015 年。
各压力时期 21 天内最大的下跌
起始日在各时期之内;“—” = 指数当时尚未存在。
| 时期 | 上证50 | 沪深300 | 中证500 | 中证1000 | 创业板指 | 科创50 |
|---|---|---|---|---|---|---|
| 2008 | −26.9 % | −27.8 % | −32.6 % | — | — | — |
| 2015(6–9 月) | −24.9 % | −31.6 % | −40.1 % | −42.4 % | −39.5 % | — |
| 2016-01 | −14.8 % | −15.7 % | −20.0 % | −21.9 % | −16.7 % | — |
| 2018 | −12.3 % | −13.1 % | −16.5 % | −18.8 % | −18.9 % | — |
| 2020-02 | −13.8 % | −14.9 % | −13.6 % | −13.5 % | −17.9 % | −22.8 % |
| 2022 | −12.9 % | −12.5 % | −17.5 % | −23.7 % | −20.5 % | −23.5 % |
| 2024-02 | −2.2 % | −5.0 % | −15.6 % | −24.4 % | −15.2 % | −18.5 % |
大跌开始于剧烈波动的市场
上面的表格拿历史上的每一天与模型在今天隐含波动率下的结果比较,而上证50 和沪深300 今天的隐含波动率很低。但暴跌很少从平静的市场开始。为了看清这一点,我们按每个起始日之前 21 个交易日的 realised volatility(RV,已实现波动率;可以追溯到 2005 年的隐含波动率替代指标)拆分了 21 天的频率。这个拆分是在结论之后加入的,不改变结论。
| 起始时的已实现波动率 | 21 天内下跌 ≥ 20 % | 行情数 | 起始日 | 下跌 ≥ 15 % |
|---|---|---|---|---|
| 低于 20 % | 0.04 % | 2 | 10,357 | 0.59 % |
| 20–30 % | 0.41 % | 6 | 7,784 | 1.70 % |
| 30 % 或以上 | 4.43 % | 10 | 5,966 | 8.85 % |
(六个指数合并)
- 在能测出已实现波动率的 300 个命中日中,264 天开始时已实现波动率在 30 % 或以上,只有 4 天低于 20 %。从 20 % 以下开始,随后出现 20 % 下跌的交易日只有 0.039 %(10,357 个起始日中 2 段行情)。
- 用 QVIX 逐日检验(30 天隐含波动率指数;50ETF 从 2015 年起,300ETF 从 2019-12 起):在上证50 上,按每天自己的隐含波动率计算的模型,在 15 % 下跌(0.99 % 对 0.93 %)和 20 % 下跌(0.26 % 对 0.25 %)上都与历史吻合,基于 3 段行情。沪深300 自 2019-12 以来没有 15 % 的下跌;在 10 % 上,模型给出 3.14 %,历史是 0.99 %。
- 这与“尾部随隐含波动率变厚”一致,而模型本来就是这样:波动率上升时,它的尾部随之变厚。但 3 段行情太少,不足以证明。

按起始前的已实现波动率,21 天内大跌的频率,六个指数合并,2005–2026 年。
暴跌下限会对仓位做什么
这个想法源于一个担心:只要期望值为正,裸卖认沽的 Kelly 比例就会停在上限,仓位因此忽视了尾部。这个担心已经过时。 打开波动率区间时(本站的看板和推荐都是这样定仓位的),2026-09-24 期权链上的 17 笔裸卖认沽,比例从 0 到 0.31,从未到达上限。只有不带区间的单一波动率版本才可能停在上限(17 笔中有 8 笔)。
而且比例很少决定仓位。17 笔中有 9 笔比例在 0.10 或以上,半 Kelly 已到或超过 5 % 上限,所以由上限定仓位。5 笔比例为正的中证1000股指认沽,跌到零时每张亏 ¥635,660–¥714,660:¥100 万的 5 % 一张也买不了,本站“最少一张合约”的规则给出一张,并标注为超过 Kelly。
加入暴跌下限(21 天期限,在下跌 25 % 处放 1.2 %)后:
| 认沽(到期,行权价) | 到期交易日 | 今天的 Kelly | 加下限后的 Kelly | 仓位:今天 → 加下限 |
|---|---|---|---|---|
| 50ETF 2026-11,2.8 | 38 | 0.016 | 0 | 0.80 % → 0 |
| 300ETF 2026-10,4.3 | 18 | 0.273 | 0 | 5 % → 0 |
| 300ETF 2026-11,4.3 | 38 | 0.314 | 0 | 5 % → 0 |
| 中证1000 2026-10,7200 | 10 | 0.256 | 0.106 | 5 % → 5 % |
| 500ETF、科创50ETF、其他中证1000(10 笔) | 38–120 | 0–0.255 | 不变 | 不变 |
| 50ETF 2026-10 2.8、300ETF 2026-10 4.1、中证1000 2026-10 6800(3 笔) | 10–18 | 0 | 0 | 0 → 0 |
- 在高波动率的期权链上(17 笔中的 10 笔),它毫无作用:这些模型在下跌 20 % 以下已有至少等于下限的概率。
- 在低波动率的 50ETF / 300ETF 认沽上,它是一个开关:它让这些交易的期望值变为负、比例变为 0。它只改变了 17 笔中 3 笔的仓位,而检验 (b) 需要一半。
- 下限并没有让仓位更精细;它只是用一个取自 2008 和 2015 年的常数,决定做还是不做。

每笔裸卖认沽的仓位,今天对比加下限后(2026-09-24 期权链)。下限把低波动率的几笔清零,其余不变。
结论
| 检验 | 结果 | 是否通过 |
|---|---|---|
| (a) 合并历史下界 ≥ 10 × 波动率区间(21 天,下跌 20 %) | 0.68 % 对 10 × 0.79 % = 7.93 % | 否 |
| (b) 至少一半裸卖认沽的仓位下降 ≥ 20 % | 17 笔中 3 笔 | 否 |
| (c) 2016 年以来、以及分别去掉三段最大行情时,(a) 仍成立 | 否、否、否、否 | 否 |
三项全部未通过,所以不采用暴跌下限。
这对本站意味着什么
- 不改动。 Kelly 继续像今天这样在波动率区间上定仓位。净卖认沽保留它自己的“下行风险大”评级,仓位由半 Kelly、每笔 5 % 上限和最少一张合约决定:一张以 0.05 卖出的 50ETF 3.0 认沽跌到零亏 ¥29,500,所以每 ¥100 万一张;中证1000股指认沽为一张,超过 Kelly。
- 什么会改变结论。 如果你想给一次从平静市场开始的 2008 或 2015 年规模的下跌定价,按这些常数设的下限会让今天平值隐含波动率 15.6–18.1 % 下所有虚值 5 % 的 50ETF / 300ETF 认沽都不交易(4 笔中 4 笔)。这是一种看法,不是测量结果:这段历史中,从已实现波动率低于 20 % 开始的命中日只有 4 天。
- 何时再看:在上证50 或沪深300 出现 21 天内下跌 15 % 或更多之后,或在 2027 年 11 月,用保存的隐含波动率历史做一次按起始波动率分组的检验。
- 对你自己的交易:持有到期的卖认沽仍然承担跌到零的全部亏损。本站的上限让这笔亏损只占组合的一小部分;请按这个最坏情况定仓位,而不是按比例。
本研究不能说明什么
- 从平静中开始的暴跌。 样本包含 2008 年、2015 年、2016-01 的熔断下跌和 2024 年初的小盘股下跌;它们 300 个命中日中有 264 个开始时已实现波动率在 30 % 或以上。像美国 1987 年 10 月那样从低波动中出现的单日暴跌,不在样本中。平静组只有 2 段行情,它的 95 % 上界(0.14 %)很宽。
- 样本小。 主要问题上合并只有 14 段行情,每个指数 3–9 段。各指数同涨同跌,所以六个指数并不是六个样本。按年重新抽样的区间下界远低于主区间(合并 0.11 %,上证50 0.00 %,沪深300 0.04 %)。
- 隐含波动率历史。 “典型波动率”是本站保存的平值隐含波动率在 2024–2026 年的中位数。QVIX 只覆盖 2015 年以来的 50ETF 和 2019-12 以来的 300ETF。按已实现波动率的拆分在每个日期都用已实现波动率,而它通常低于隐含波动率。
- 科创50 的历史。 科创50 指数在 2020-07-23 发布之前的数据由中证指数公司回溯计算;它的 3 段行情中有一段(2020-02-18 至 2020-02-24)在这一时期。
- 指数,不是 ETF。 用的是不含分红的价格指数;ETF 的跟踪误差、费用,以及中证1000股指期权的期货基差都没有建模。
- 只有一天的期权链。 仓位回放只用了一个收盘(2026-09-24,对 50ETF / 300ETF 是平静的一天),期权链上远端认沽很少,所以 20 笔裸卖认沽中有 3 笔无法构建。中证1000 2027 年 3 月的期权链(120 个交易日)把 2027 年的节假日算作交易日,因为当时节假日安排尚未公布。
- Kelly 不是盈亏。 本研究测量的是 Kelly 所用分布的尾部,而不是卖认沽有没有赚钱;那个问题请看提前止盈还是持有到期。
自己复现
脚本 crash_floor.py(下方下载)用公开数据重建本页除仓位回放外的各个表格和检验,不需要账号或密钥。只有一个输入固定写在脚本里。
数据(免费,通过 AKShare):
| 内容 | AKShare 函数 | 起始 |
|---|---|---|
| 指数日收盘价(新浪) | stock_zh_index_daily("sh000016")、sh000300、sh000905、sh000852、sz399006、sh000688 | 2005-01-04,或指数的第一个收盘价 |
| QVIX 日收盘 | index_option_50etf_qvix()、index_option_300etf_qvix() | 2015-02-09 / 2019-12-23 |
唯一的固定输入。 每个期权标的的典型平值隐含波动率,是本站从自己的期权链保存的平值隐含波动率在 2024-01 至 2026-10 的中位数。它不公开,所以脚本把它写成 TYPICAL_ATM_IV:50ETF 18.74 %、300ETF 20.32 %、500ETF 29.25 %、中证1000股指期权 29.17 %、创业板ETF 32.34 %、科创50ETF 39.03 %。预测是它的 0.95 倍(FORECAST_RATIO)。
下跌与行情:
term = close[t + h] / close[t] - 1 # 窗口结束时
path = min(close[t+1 : t+h+1]) / close[t] - 1 # 窗口内任一收盘
hit = term <= -x
# 行情:相隔超过 h 个交易日的命中起始日开始一段新行情
# 合并:六个指数的命中日期放在同一个日历上(一次暴跌 = 一段行情)
rate = hits / start_days
lo, hi = garwood_95(episodes) # 行情数的精确泊松区间
interval = rate * [lo, hi] / episodes # 零段行情:[0, 3.689 * h / n]
模型给出的同一跌幅概率,均值 = 今天的水平,T = h / 252:
def p_lognormal(sigma, h, x):
sd = sigma * sqrt(h / 252)
return norm.cdf((log(1 - x) + sd * sd / 2) / sd)
sigmas, w = forecast_range(0.95 * atm_iv) # 32 个点:对数标准差 0.253,高侧 × 1.143
p_vol_range = w @ p_lognormal(sigmas, h, x)
波动率区间与波动率区间页面上 Kelly 脚本中的相同。第二种区间有放回地重新抽取日历年(2,000 次,种子 7)。起始日的已实现波动率是它之前 21 个日对数收益的标准差 × √252。
运行:
pip install -r requirements.txt
python crash_floor.py --cache-dir data # 只下载一次,之后几秒钟
python crash_floor.py --end none # 包含发布之后的收盘价
你应该看到什么,以及如何核对。 脚本默认截止到 2026-09-30,即本页使用的数据。在研究自己保存的这些 AKShare 数据上,以及 2026-11-04 重新下载的数据上(输出逐行相同),它都精确重现本页:主表的每个指数行、两种区间、15 % 的各行、2016 年以来和去掉单段行情的样本、各期限和路径的频率、各时期最大的下跌、QVIX 逐日检验和按已实现波动率的拆分。它的窗口与研究的完全相同,模型概率与本站自己的代码相同。一个自动测试会重新检查这些。仓位回放不在脚本中:它需要记录的期权链,这些数据来自商业数据供应商,不能再分发。
下载脚本
独立的 Python 脚本,只使用公开数据(AKShare)。先安装 requirements.txt 中的依赖,再运行脚本。