Strasmore Research
学习 Matt Connor作者: Matt Connor

哪里可以获取历史隐含波动率数据

了解历史隐含波动率数据的获取渠道,解析两个30天IV序列为何不同,并比较免费与付费来源,掌握可自行运行的查询方法。

历史隐含波动率数据是推导出来的,而非直接记录的。这一点解释了为什么它比价格历史更难获取。隐含波动率是将期权的市场价格代入定价模型,反复反推,直到模型计算值与屏幕上的市场价格相匹配后得到的数值。交易所不会在行情带上公布这一数据。因此,任何公开的隐含波动率历史都包含对模型、报价、合约选择和插值方法的取舍。正是这些取舍,造成了两个声称衡量同一指标的序列之间的全部差异。

如果您希望先了解定义,可参阅什么是隐含波动率如何计算隐含波动率,其中介绍了相关机制。下文将说明历史数据存储在哪里,以及如何区分不同版本的数据。

为什么历史隐含波动率数据比价格数据更难获取?

每日收盘价是可以直接观察到的:它已经成交,所有数据供应商报告的数值也相同。隐含波动率则是计算得出的,其计算涉及四项输入,而这些输入会因数据来源不同而变化。

  • 模型:欧洲式 Black-Scholes 求解模型、包含离散股息的美式二叉树模型,或采用自身利率和融券假设的数据供应商变体。
  • 输入价格:买价、卖价、中间价、最新成交价,或交易所结算价。
  • 纳入哪些合约:一个平值行权价、一个价内外程度区间,或设置成交量、未平仓量筛选条件。
  • 如何换算到固定期限:在跨越30天的两个到期日之间进行插值,或对到期日落在指定剩余天数区间内的所有合约取平均值。

改变一项输入,隐含波动率水平就会发生变化。四项全部改变时,即使是同一交易日,两个严谨的数据来源也可能相差几个波动率百分点,但两者都没有算错。

这种差异首先会出现在单只股票内部。下方图表以AAPL为例,覆盖2026年6月,只保留行权价与现货价格相差不超过5%的合约,并按距离到期的时间分组。

查询单只股票,单个月份:按到期时间划分的隐含波动率(AAPL,2026年6月)
每个数字背后的完整 SQL
SELECT
    dte_band,
    round(100 * quantileDeterministic(0.25)(iv, contract_hash), 1) AS iv_p25_pct,
    round(100 * quantileDeterministic(0.50)(iv, contract_hash), 1) AS iv_median_pct,
    round(100 * quantileDeterministic(0.75)(iv, contract_hash), 1) AS iv_p75_pct,
    count()                                                        AS contract_day_count
FROM
(
    SELECT
        multiIf(days_to_expiry <=   7, '01-07d',
                days_to_expiry <=  21, '08-21d',
                days_to_expiry <=  45, '22-45d',
                days_to_expiry <=  90, '46-90d',
                days_to_expiry <= 180, '91-180d',
                                       '181d+')  AS dte_band,
        toFloat64(implied_volatility)             AS iv,
        cityHash64(ticker)                        AS contract_hash,
        days_to_expiry                            AS dte
    FROM global_markets.options_greeks
    WHERE underlying_symbol = 'AAPL'
      AND date >= '2026-06-01'
      AND date <  '2026-07-01'
      AND iv_converged = 1
      AND volume > 0
      AND days_to_expiry > 0
      AND underlying_close > 0
      AND abs(toFloat64(strike_price) / toFloat64(underlying_close) - 1) < 0.05
)
GROUP BY dte_band
ORDER BY min(dte)
Run this yourself

标的相同,月份相同,只保留接近平值的行权价。图中最短的区间01-07d,隐含波动率中位数为29.6%。最长的区间181d+,数值为28.1%。仅在第一个区间内,第25和第75百分位数就分别为24.9%和35.8%。不同到期日之间的形态称为期限结构,不同行权价之间的对应概念则是波动率偏斜。这里不存在一个唯一的隐含波动率。实际呈现的是一张波动率曲面,任何公布的AAPL隐含波动率数据都只是这张曲面的一个概括,这正是我们的AAPL隐含波动率页面所跟踪的内容。

为什么两张30天IV图表显示的数字不同?

选取一个流动性较高的标的和一年的交易日数据,用相同的数据行以三种方式构建30天IV。第一列仅保留行权价与现货价格偏离不超过1%、到期时间为25至35天的合约,读数最为严格。第二列将范围扩大至现货价格的5%,到期时间扩大至20至45天。这是需要为每个交易日填入数据时的实际默认设置。第三列按照合约成交量对这一扩大后的样本加权,使平均值更接近实际发生交易的行权价。

查询用同一组数据行计算 SPY 30天隐含波动率的三种方法
每个数字背后的完整 SQL
WITH
    near_money AS
    (
        SELECT
            toMonday(date)                                                 AS week_start,
            toFloat64(implied_volatility)                                  AS iv,
            days_to_expiry                                                 AS dte,
            volume                                                         AS vol,
            abs(toFloat64(strike_price) / toFloat64(underlying_close) - 1) AS moneyness
        FROM global_markets.options_greeks
        WHERE underlying_symbol = 'SPY'
          AND date >= '2025-08-01'
          AND date <  '2026-08-01'
          AND iv_converged = 1
          AND volume > 0
          AND underlying_close > 0
          AND days_to_expiry BETWEEN 20 AND 45
          AND abs(toFloat64(strike_price) / toFloat64(underlying_close) - 1) < 0.05
    ),
    weekly AS
    (
        SELECT
            week_start,
            avgIf(iv, dte BETWEEN 25 AND 35 AND moneyness < 0.01) AS tight_atm,
            avg(iv)                                               AS wide_atm,
            sum(iv * vol) / sum(vol)                              AS volume_weighted
        FROM near_money
        GROUP BY week_start
        HAVING countIf(dte BETWEEN 25 AND 35 AND moneyness < 0.01) > 0
    )
SELECT
    toString(week_start) AS week,
    concat(monthName(week_start), ' ', toString(toDayOfMonth(week_start)), ', ', toString(toYear(week_start))) AS week_label,
    round(100 * tight_atm, 1)       AS tight_atm_pct,
    round(100 * wide_atm, 1)        AS wide_atm_pct,
    round(100 * volume_weighted, 1) AS volume_weighted_pct,
    round(100 * (greatest(tight_atm, wide_atm, volume_weighted)
               - least(tight_atm, wide_atm, volume_weighted)), 1) AS spread_pp
FROM weekly
ORDER BY week_start
Run this yourself

在所示的第一周,即July 28, 2025,三种方法的读数分别为16.6%、16.4%和16.7%。其中最高值与最低值相差0.2个百分点;spread列则跟踪这一下差在全部53周中的变化。三者都不是该基金真正的30天IV。它们回答的是略有不同的问题,而供应商图表只是采用了其中一种方法,却没有在标签中说明具体算法。

单份合约的隐含波动率历史可以追溯多久?

这些面板基于 global_markets.options_greeks:每个交易日、每份合约一行数据。数据将隐含波动率与 delta、gamma、vega、theta 和 rho,以及行权价、到期日、到期剩余天数、标的代码和标的收盘价放在一起。这是日终数据,不是实时期权链快照。下方面板统计了每个季度内至少有一条收敛隐含波动率记录的不同标的名称数量。

查询按季度统计:每日隐含波动率已收敛的标的
每个数字背后的完整 SQL
SELECT
    concat(toString(toYear(date)), '-Q', toString(toQuarter(date))) AS quarter,
    uniqExact(underlying_symbol)                                    AS underlyings_covered
FROM global_markets.options_greeks
WHERE iv_converged = 1
  AND volume > 0
  AND underlying_symbol NOT IN ('SPCX')
  AND date < '2026-07-01'
GROUP BY quarter
ORDER BY min(date)
Run this yourself

数据覆盖 2014-Q22026-Q2,共 49 个季度。最后一个完整季度中,有 5799 个标的名称具备收敛的每日隐含波动率数据。

查询这类数据集时,四个筛选条件最为关键。

  • 保留 iv_converged = 1。求解器并不总能收敛;未收敛记录代表拟合失败,而不是隐含波动率较低。
  • 保留 volume > 0。从未成交的合约,其隐含波动率是根据过时报价求解的。
  • underlying_symbol 分组。ticker 列存放 OCC 合约代码,因此按该列分组会返回每个行权价和到期日一行,而不是每家公司一行。
  • 有针对性地选择合约,优先选择接近平值且到期剩余天数处于指定区间内的合约。跳过这一步,会将波动率偏斜和期限结构平均成一个数值。

是否存在免费的隐含波动率 API?

免费来源确实存在,但每种来源都有特定限制。

  • 券商平台会根据自身的期权链计算隐含波动率,并实时显示。可下载的历史数据通常较短,甚至完全没有;而且该数值来自券商自己的模型,并非统一标准。
  • 交易所发布的波动率指数可追溯数十年,且无需付费。但每个指数都是针对某一篮子资产计算的单一综合数值,因此适合回答整体市场问题,不适用于单一股票。
  • 通用市场数据 API 大多只提供价格。几乎所有平台都会将逐合约希腊值作为单独产品提供;包含这类数据的免费套餐通常只返回实时快照,不提供历史存档。我们的免费股票市场数据 API盘点介绍了开放套餐实际提供的内容。
  • 按供应商定价的逐合约历史数据,才是长期单一股票历史档案的主要来源。这类数据通常按月或按年以日终文件形式出售,实时期权链的价格则远高于历史数据。实时市场数据的成本介绍了这类价格清单的基本结构。

实时快照与日终数据的区别,与价格本身同样重要。美国东部时间下午 4:00 获取的快照,使用的是该时刻的报价。根据结算价生成的文件则完全采用另一套输入数据;在波动最快的交易日,两者的差异通常最大。

综合指数波动率与单一股票波动率也不能混为一谈。指数期权反映的是一篮子资产的整体变动,成分股之间相互抵消的走势会降低总波动。单一股票期权反映的则是一家公司自身的价格路径。下表采用相同筛选条件,将一个月内的知名股票并列比较。

查询近到期平值隐含波动率中位数,距到期20至45天(2026年6月)
每个数字背后的完整 SQL
SELECT
    underlying_symbol                                              AS symbol,
    round(100 * quantileDeterministic(0.50)(iv, contract_hash), 1) AS median_iv_pct,
    count()                                                        AS contract_day_count
FROM
(
    SELECT
        underlying_symbol,
        toFloat64(implied_volatility) AS iv,
        cityHash64(ticker)            AS contract_hash
    FROM global_markets.options_greeks
    WHERE underlying_symbol IN ('SPY', 'AAPL', 'MSFT', 'NVDA', 'AMZN', 'KO', 'XOM', 'TLT')
      AND date >= '2026-06-01'
      AND date <  '2026-07-01'
      AND iv_converged = 1
      AND volume > 0
      AND underlying_close > 0
      AND days_to_expiry BETWEEN 20 AND 45
      AND abs(toFloat64(strike_price) / toFloat64(underlying_close) - 1) < 0.05
)
GROUP BY symbol
ORDER BY median_iv_pct DESC
Run this yourself

在 2026 年 6 月期间,20 至 45 天窗口内、平值附近的隐含波动率中位数从 38.5% 的 NVDA 降至 10.4% 的 TLT,覆盖 8 只股票。窗口、筛选条件和计算方法均相同。只有对所有股票始终采用同一套方法,这样的排名才具有可比性。

IV rank 和 IV percentile 的数据来源重要吗?

它决定了答案。IV rank 将今日隐含波动率与回溯期内的最高值和最低值进行比较,回溯期通常为一年;IV percentile 则计算该回溯期内隐含波动率低于今日水平的天数占比。两者都需要连续读取同一组数据,因此只要数据序列发生变化,评分就会改变,即使市场本身完全没有变化。若将券商的中间报价隐含波动率接到供应商基于结算价的历史数据上,回溯期中间就会出现一个永久性跳变,所有跨越该位置计算的 rank 都会受到影响。IV rank 与 IV percentile详细介绍了两种计算方法。比较隐含波动率与实际波动幅度时,也必须遵循同样的要求:历史波动率与隐含波动率介绍了这种比较。

实际操作中的标准是遵循数据来源规则。应选定一个数据来源、一套模型、一套合约筛选方法和一种期限口径,并在整个回溯期内保持四者不变。一组内部一致、但与其他来源略有差异的数据,价值高于一组拼接数据;后者可能只在不同区间分别与各家供应商一致。

常见问题

哪里可以获取历史隐含波动率数据?

较长的个股历史数据来自出售逐合约日终希腊值的期权数据供应商,通常以月度或年度文件提供。交易所会免费发布指数层面的波动率历史数据。券商平台会在期权链中显示实时隐含波动率,但可下载的历史数据很少。上方图表使用逐合约日度数据集,覆盖所有已上市合约,并采用收敛后的拟合结果。

是否有免费的隐含波动率API?

提供逐合约希腊值的免费版本很少。即使有,通常也只返回实时快照,而不是历史存档。指数波动率历史数据是目前真正免费且时间跨度较长的序列。较深度的个股历史数据通常属于付费产品。

为什么两个来源显示的同一只股票隐含波动率不同?

原因可能包括定价模型不同、输入报价不同、合约选择不同,以及到期日插值方法不同。上方图表使用同一组数据行构建三个30日序列,仅在第一周内,它们就相差0.2个百分点。因此,不同供应商之间存在差异属于预期情况,并不一定是错误。

隐含波动率数据可以追溯多久?

这取决于数据来源,而且无论在哪里,逐合约历史存档的时间跨度都短于价格存档。本页面所用数据集始于2014-Q2,此后为每个收敛合约提供每日数据行。


这里的每个图表都附带生成该图表的SQL。展开其中一个,即可准确查看纳入计算的合约。若要为另一只股票、另一段时间窗口或另一种计算方法构建相同序列,请在Strasmore终端中用日常语言提出请求。