Strasmore Research
学习 Matt Connor作者: Matt Connor · 更新于 2026-08-26

隐含波动率如何计算和反推

了解隐含波动率为何没有闭式解,以及求解器如何通过迭代、Black-Scholes定价和Python搜索循环,从期权市场价格反推出波动率。

隐含波动率通过迭代计算,而不是直接套用公式。不存在能够将期权市场价格反推出波动率数值的闭式表达式。因此,求解器会先猜测一个波动率,再用 Black-Scholes 模型为期权定价,将模型价格与市场报价比较,并不断重复,直到两者精确到美分。下文将完整介绍这一方法:定价函数、使用标准库 Python 编写的搜索循环,以及不同数据供应商为何会为同一份合约发布不同数值。

为什么隐含波动率没有封闭形式公式

Black-Scholes模型只能单向计算。输入现货价格、行权价、到期时间、利率和波动率后,模型会返回理论价格。这六个量中有五个可以观察到。波动率无法直接观察。它表示从现在到到期日,股票价格可能变动多远。

交易者会反过来求解。市场价格已经显示在屏幕上,未知量变成了波动率。隐含波动率是使Black-Scholes价格等于期权市场价格的波动率输入值。波动率项Sigma在正态分布函数中出现两次,分别位于d1和d2中,无法通过代数变形将其单独移出。代数推导到此为止。接下来需要进行数值搜索。隐含波动率衡量什么介绍其含义;本页介绍具体计算机制。

模型的两个特性使搜索过程较为简单。看涨期权的模型价格会随着波动率上升而上升,没有例外,而且变化是平滑的。一个只会上升的量,可以通过不断收窄区间来锁定。

求解器按每份合约运行一次

输出结果是每份合约对应一个数值,而不是每只股票对应一个数值。同一股票、同一到期区间内的合约,求解结果也可能彼此不同。这些按合约得出的结果会以经纪商交易界面上的一列数据呈现,每个行权价对应一个数值:逐列读取期权链将介绍其相邻列显示的内容。2026年6月30日成交、剩余20至45天到期的所有苹果公司(AAPL)期权,按行权价占股价的比例分组:

查询每份合约一次求解:AAPL 按行权价区间划分的隐含波动率,2026年6月30日
行权价与现价隐含波动率(%)合约数
0.80-0.9035.524
0.90-0.952910
0.95-1.0028.118
1.00-1.0527.418
1.05-1.1027.416
1.10-1.2027.320
每个数字背后的完整 SQL
WITH toFloat64(strike_price) / toFloat64(underlying_close) AS moneyness
SELECT multiIf(moneyness < 0.90, '0.80-0.90',
               moneyness < 0.95, '0.90-0.95',
               moneyness < 1.00, '0.95-1.00',
               moneyness < 1.05, '1.00-1.05',
               moneyness < 1.10, '1.05-1.10',
                                 '1.10-1.20') AS strike_vs_spot,
       round(100 * avg(toFloat64(implied_volatility)), 1) AS implied_vol_pct,
       count() AS contract_count
FROM global_markets.options_greeks
WHERE underlying_symbol = 'AAPL'
  AND date = toDate('2026-06-30')
  AND days_to_expiry BETWEEN 20 AND 45
  AND iv_converged = 1
  AND volume > 0
  AND moneyness BETWEEN 0.80 AND 1.20
GROUP BY strike_vs_spot
ORDER BY min(moneyness)
自己运行这个查询

沿着行权价阶梯向上看,0.80-0.90区域的求解结果为35.5%,0.95-1.00区域的求解结果为28.1%,1.10-1.20区域的求解结果为27.3%。同一家公司、同一交易日,得出6个答案。这条曲线的弯曲部分有一个名称,即波动率偏斜;对每只股票设定一个单一波动率,无法描绘出这条曲线。

Black-Scholes定价:求解器需要匹配的目标价格

S表示股价,K表示行权价,T表示距离到期的年数,r表示无风险利率,N()表示标准正态累积分布函数,即标准正态随机变量低于给定值的概率。Python通过math.erf提供这一功能,因此仅使用解释器即可完成计算。

apt-get update && apt-get install -y python3

如果当前机器上的用户不是root,请在两条命令前加上sudo。然后将以下内容保存为iv.py

import math

def norm_cdf(x):
    return 0.5 * (1.0 + math.erf(x / math.sqrt(2.0)))

def bs_call(S, K, T, r, sigma):
    if T <= 0.0 or sigma <= 0.0:
        return max(S - K, 0.0)
    d1 = (math.log(S / K) + (r + 0.5 * sigma * sigma) * T) / (sigma * math.sqrt(T))
    d2 = d1 - sigma * math.sqrt(T)
    return S * norm_cdf(d1) - K * math.exp(-r * T) * norm_cdf(d2)

这就是完整的远期模型。输入波动率,即可得到价格。

隐含波动率的计算方法:分步说明

二分法是最适合先学习的方法。它不会发散,也不需要微积分。

  1. 将答案限定在0.01(年化1%)至5.0(年化500%)之间。所有有交易的期权都在这一范围内。
  2. 使用区间中点为期权定价。
  3. 如果模型价格高于市场报价,说明估计值过高:将区间上限下调至中点。如果模型价格低于市场报价,则将区间下限上调至中点。
  4. 当模型价格与市场报价的差距小于一美分时停止。
def implied_vol(price, S, K, T, r, lo=0.01, hi=5.0, tol=0.01):
    for _ in range(100):
        mid = 0.5 * (lo + hi)
        diff = bs_call(S, K, T, r, mid) - price
        if abs(diff) < tol:
            return mid
        if diff > 0.0:
            hi = mid
        else:
            lo = mid
    return 0.5 * (lo + hi)

# $100 stock, $100 strike, three months, 4% rates, $5.00 on the screen
print(round(implied_vol(5.00, 100.0, 100.0, 0.25, 0.04), 4))

运行python3 iv.py。结果约为0.226,意味着对于这一假设报价,年化隐含波动率接近22.6%。每次迭代都会将区间缩小一半。宽度为4.99的区间连续缩小二十次后,宽度将小于0.00001,因此100次迭代的上限不会成为限制。

为什么牛顿-拉夫逊法收敛更快,以及它在哪些情况下失效

二分法丢弃了模型已经掌握的信息。Vega表示波动率每变动一个单位,期权价格的变化幅度,Black-Scholes模型可以直接给出其封闭解。牛顿-拉夫逊法将其视为斜率:先衡量定价误差,再除以Vega,并据此调整估计值。

def bs_vega(S, K, T, r, sigma):
    d1 = (math.log(S / K) + (r + 0.5 * sigma * sigma) * T) / (sigma * math.sqrt(T))
    return S * math.sqrt(T) * math.exp(-0.5 * d1 * d1) / math.sqrt(2.0 * math.pi)

def implied_vol_newton(price, S, K, T, r, sigma=0.5):
    for _ in range(20):
        v = bs_vega(S, K, T, r, sigma)
        if v < 1e-8:
            return None          # no slope left, hand the job back to bisection
        step = (bs_call(S, K, T, r, sigma) - price) / v
        sigma -= step
        if sigma <= 0.0:
            return None          # the step overshot into nonsense
        if abs(step) < 1e-6:
            return sigma
    return None

对于平值附近的期权,牛顿-拉夫逊法通常三到四次迭代即可收敛,而二分法需要十几次。其失效点在于分母:当行权价偏离股价时,Vega会缩小。以下为同一组AAPL合约,各区域的平均Vega占平值期权Vega的比例:

查询牛顿步长失常处:AAPL 按行权价区间划分的 Vega,2026年6月30日
行权价与现价Vega占平值(%)合约数
0.80-0.9033.124
0.90-0.9562.410
0.95-1.0089.818
1.00-1.0598.518
1.05-1.1073.616
1.10-1.2031.620
每个数字背后的完整 SQL
WITH toFloat64(strike_price) / toFloat64(underlying_close) AS moneyness,
     (
         SELECT avg(toFloat64(vega))
         FROM global_markets.options_greeks
         WHERE underlying_symbol = 'AAPL'
           AND date = toDate('2026-06-30')
           AND days_to_expiry BETWEEN 20 AND 45
           AND iv_converged = 1
           AND volume > 0
           AND abs(toFloat64(strike_price) / toFloat64(underlying_close) - 1) < 0.025
     ) AS atm_vega
SELECT multiIf(moneyness < 0.90, '0.80-0.90',
               moneyness < 0.95, '0.90-0.95',
               moneyness < 1.00, '0.95-1.00',
               moneyness < 1.05, '1.00-1.05',
               moneyness < 1.10, '1.05-1.10',
                                 '1.10-1.20') AS strike_vs_spot,
       round(100 * avg(toFloat64(vega)) / atm_vega, 1) AS vega_pct_of_atm,
       count() AS contract_count
FROM global_markets.options_greeks
WHERE underlying_symbol = 'AAPL'
  AND date = toDate('2026-06-30')
  AND days_to_expiry BETWEEN 20 AND 45
  AND iv_converged = 1
  AND volume > 0
  AND moneyness BETWEEN 0.80 AND 1.20
GROUP BY strike_vs_spot
ORDER BY min(moneyness)
自己运行这个查询

两翼区域的敏感度只剩一小部分:在0.80-0.90区域为平值Vega的33.1%,在1.10-1.20区域为31.6%。用这么小的数去除定价误差,会产生极大的步长,导致估计值跌至零以下,而模型无法对该区域给出有效结果。生产环境中的求解器通常结合这两种方法:先用区间夹逼,再用牛顿法精调。Vega介绍了这一希腊字母指标本身。

为什么两个来源报告的隐含波动率不同

模型是公开的,计算方法也没有争议,因此差异来自输入数据。

  • 中间价与最新成交价。 求解器需要一个价格。某合约的买价为 2.00 美元、卖价为 2.20 美元时,中间价为 2.10 美元;但最新成交价可能是九十分钟前的 2.02 美元。对于这类合约,十美分的价格差异带来的影响可能超过一个波动率点。
  • 股息与持有成本。 上述函数计算的是不派息股票的欧式看涨期权价格。到期前派发股息会压低远期价格,而各交易台采用的调整方法和利率也可能不同。
  • 美式提前行权。 美国个股期权可以在任何交易日行权,这项权利具有价值,但欧式公式无法纳入。忽略提前行权权利的求解器会将这部分差异计入波动率。二叉树模型则直接为行权权利定价。
  • 过时报价。 某个行权价的期权即使上次成交是在周二,仍可能显示报价。求解器会将收到的报价视为真实数据。

收敛情况会让后两个问题更加明显。下表选取 2026 年 6 月 30 日的八只知名股票,统计剩余 20 至 45 天的已成交合约,并同时报告平值波动率以及求解收敛的合约占比:

查询平值隐含波动率与求解器收敛性,8只标的,2026年6月30日
代码平值隐含波动率(%)已解算(%)合约数
TSLA47.797.8364
MSFT39.695.5221
AMZN38.796.3163
NVDA38.293.8209
JNJ28.310053
AAPL27.889.6154
KO20.910079
SPY14.498.5739
每个数字背后的完整 SQL
WITH abs(toFloat64(strike_price) / toFloat64(underlying_close) - 1) AS distance_from_spot
SELECT underlying_symbol AS symbol,
       round(100 * avgIf(toFloat64(implied_volatility), iv_converged = 1 AND distance_from_spot < 0.05), 1) AS atm_iv_pct,
       round(100 * countIf(iv_converged = 1) / count(), 1) AS solved_pct,
       count() AS contract_count
FROM global_markets.options_greeks
WHERE date = toDate('2026-06-30')
  AND underlying_symbol IN ('AAPL', 'MSFT', 'NVDA', 'AMZN', 'TSLA', 'SPY', 'KO', 'JNJ')
  AND days_to_expiry BETWEEN 20 AND 45
  AND volume > 0
GROUP BY symbol
HAVING countIf(iv_converged = 1 AND distance_from_spot < 0.05) > 0
ORDER BY atm_iv_pct DESC
自己运行这个查询

47.7% 的 8 个名称中,TSLA 的平值波动率最高,为 14.4%;排名最低的 SPYTSLA。在 TSLA 的期权链中,97.8% 的已成交合约得出了收敛结果。其余合约的行权价对应的价格超出了任何波动率都能还原的范围,可能是低于内在价值的报价,也可能是交叉市场。这样的数值是否算高,是另一个问题:30%的隐含波动率算高吗对此进行了讨论,而预期波动幅度则将其换算成美元区间。

同一合约,每个交易日重新求解

隐含波动率不会被保存。系统会根据屏幕上显示的价格重新计算。下面列出的是到期日为2026年7月17日、交易最活跃的 AAPL 合约,并跟踪其从6月1日到到期日的变化。行权价和到期日均未改变:

查询一份 AAPL 合约:每个交易日重新求解至2026年7月17日到期
29 rows (showing 20)
date隐含波动率(%)到期天数
2026-06-0125.146
2026-06-0224.945
2026-06-0315.544
2026-06-0426.143
2026-06-0525.742
2026-06-0825.639
2026-06-0923.438
2026-06-1025.937
2026-06-1122.536
2026-06-1221.535
2026-06-1522.132
2026-06-1621.931
2026-06-1720.930
2026-06-182329
2026-06-2225.125
2026-06-2322.824
2026-06-2426.623
2026-06-2526.322
2026-06-2625.321
2026-06-2925.818
每个数字背后的完整 SQL
WITH (
         SELECT ticker
         FROM global_markets.options_greeks
         WHERE underlying_symbol = 'AAPL'
           AND date = toDate('2026-06-30')
           AND expiration_date = toDate('2026-07-17')
           AND iv_converged = 1
           AND volume > 0
         ORDER BY volume DESC
         LIMIT 1
     ) AS pinned_contract
SELECT date,
       round(100 * avg(toFloat64(implied_volatility)), 1) AS implied_vol_pct,
       round(avg(days_to_expiry)) AS days_to_expiry
FROM global_markets.options_greeks
WHERE ticker = pinned_contract
  AND date BETWEEN toDate('2026-06-01') AND toDate('2026-07-17')
  AND iv_converged = 1
  AND volume > 0
GROUP BY date
ORDER BY date
自己运行这个查询

29 个交易日中,求解结果开盘为 25.1%,当时距离到期还有 46 天;收盘为 26.6%,剩余 4 天。该曲线上的每一个点,都是根据当日行情运行上述循环后得到的一次结果。我们在每个 ticker 的页面上发布相同的计算结果:AAPL隐含波动率会对整个期权链每日运行该计算,因此读者可以使用本页代码复现其中的任何数值。

隐含波动率计算常见问题

隐含波动率有计算公式吗?

没有。Black-Scholes模型可以根据波动率计算期权价格,但这个映射没有初等反函数,因为sigma在正态分布函数中出现了两次。您看到的每一个隐含波动率数值,无论来自本文还是其他来源,都是通过迭代求解器计算得出的。

计算需要进行多少次迭代?

每次二分迭代都会将区间缩小一半。因此,0.01至5.0的区间经过二十次迭代后,会缩小到0.00001以下。要将结果匹配到报价的最接近分位,通常需要约十二次迭代。牛顿-拉夫森法在平值附近通常三至四次即可收敛,但当vega较小时,迭代步长可能失控。

为什么我的经纪商和数据供应商显示的隐含波动率不同?

因为它们向求解器输入了不同的数据。常见差异包括:中间价还是最近成交价、利率和股息假设,以及模型是否处理美式期权的提前行权。在成交清淡的执行价上,仅一个过时的报价就可能使结果相差几个百分点。

同一执行价的看涨期权和看跌期权会得出相同的隐含波动率吗?

理论上会。看跌-看涨平价关系将同一执行价和到期日的两类期权联系起来。实际中,两者的报价分别形成,因此计算出的数值会略有不同。这也是不同供应商计算出的整条期权链平均值存在差异的原因之一。

没有市场数据时,我可以计算隐含波动率吗?

可以,但只能针对假设报价。上面的代码允许您手动输入期权价格、执行价、现货价格、到期时间和利率。要匹配数据供应商的实时数值则更困难,因为必须使用供应商采用的同一组输入。


这里的每个面板都保存了对应的SQL语句。打开其中一个面板,然后在Strasmore终端上,对实时期权链运行相同的求解过程。

#implied volatility#期权#black-scholes#python#how-to