← 返回编程题库
coding-implied-vol-bisection困难免费版2000ms未尝试

Black-Scholes 隐含波动率:严格递增定价曲线上的二分反演

Black-Scholes Implied Volatility on a Strictly Increasing Price Curve via Bisection

开始编码

实现 solution(market_price: float, S: float, K: float, T: float, r: float, is_call: int, tol: float) -> float。给定观测的期权 market_price、spot S、strike K、到期年数 T、连续复利无风险利率 ris_call 标志(1 看涨、0 看跌),以及对反推 vol 的绝对容差 tol,返回满足 BS_price(S, K, T, r, sigma, is_call) = market_price 的 **Black-Scholes 隐含波动率 sigma >= 0**。在闭区间 [0, 5.0] 上**对 sigma 二分**:BS 定价对看涨与看跌都在 sigma 上严格递增,二分是良定的。当 hi - lo <= tol 时停并返回 (hi + lo) / 2。用 math.erf 计算正态 CDF:N(x) = 0.5 * (1 + erf(x / sqrt(2)))sigma = 0 处 BS 价坍缩为折现内在价值的下界(看涨 -> max(0, S - K*exp(-r*T))、看跌 -> max(0, K*exp(-r*T) - S))。若 market_price < floor - 1e-9(不存在实数 IV——价格低于无套利下界)或 market_price > BS_price(sigma=5) + 1e-9(价格超过可搜索的上界),返回哨兵 -1.0

solution(10.450583572185565, 100.0, 100.0, 1.0, 0.05, 1, 1e-7) 返回约 0.20。spot S = 100、strike K = 100T = 1 年、rate r = 0.05,一只 ATM 1 年期看涨观测价 ~10.4506 对应 BS 隐含波动率 sigma ~= 0.20(反推到 1e-7 内)。solution(5.363275623326004, 100.0, 95.0, 0.5, 0.03, 0, 1e-7) 返回约 0.30:6 个月、K = 95 的 OTM 看跌报价 ~5.363 对应 sigma ~= 0.30solution(2.309250374972599, 100.0, 130.0, 0.25, 0.04, 1, 1e-7) 返回约 0.50:3 个月、K = 130 的深度 OTM 看涨报价 ~2.309 对应 sigma ~= 0.50——这正是 smile 翼上、Newton-Raphson 在近零 vega 上 stall 的那种 quote,desk 必须能稳定反推。如果价格低于无套利下界(如 solution(13.5, 100.0, 90.0, 1.0, 0.05, 1, 1e-7),该看涨的折现内在下界约 14.39),返回 -1.0——下界以下没有实数 IV 与之自洽。

关键形态是**在固定区间 [0, 5] 上对隐含波动率在严格递增的价格-vol 曲线上做二分**——与债券 YTM 画面(price 在 yield 上严格递减)和现金流 IRR 画面(NPV 的根可能没有全局单调性)根本不同。对 Black-Scholes,vega 在 (0, +infinity) 上严格为正,价格-vol 曲线从 sigma = 0 处的 floor = max(0, intrinsic*) 单调走到 sigma = 5 处的有限上界,区间由 spec 固定——没有自适应外推。两个 off-by-one 陷阱:(a) 把 BS 价当成 sigma 上的递减函数(于是选错半区间);(b) 看跌公式应是 K*exp(-r*T)*N(-d2)(而不是 K*N(-d2))——把折现因子 exp(-r*T)K 上拆出来时只对一个支(call/put)做修改,会引入静默错误。Newton-Raphson 替代法在良性 quote 上更快,但在 vega ~ 0(深度 OTM、近零 T)时会 stall 或在 [0, 5] 外振荡——二分用约 32 次额外迭代换无条件收敛。

函数骨架见 stubs/stub.py

实践背景

vol 曲面聚合台把原始 quote(期权中间价)喂给一个隐含 vol 反推器,使得下游的 skew、smile、期限结构都在无量纲的 sigma 上工作,而不是在依赖 SKTr 的美元价上。这个反推函数在每次刷新的每个 (strike, expiry) 对上都要被调一次——一次返回 NaN 或者跑到合法区间外的 solver 迭代就会污染下游 smile 拟合。这里二分胜过 Newton-Raphson 的唯一原因是:深度 OTM 与近零 vega 的 quote 是股指 smile 翼上的家常便饭,Newton 的 sigma_{n+1} = sigma_n - (price_n - market_price) / vega_n 要么 stall(vega ~ 0)要么跳到 [0, sigma_max] 之外——两种失效模式都是 smile 聚合器无法承受的。代价是 ~log2(5/tol) 次迭代(tol = 1e-9 时约 32 次);对单 quote 反推这是亚微秒级、可以忽略。生产系统有时把 Newton(快路径)与二分(安全路径)混合,以 |vega| < eps 切换——但纯二分 solver 才是所有其它 solver 的金标准参考实现。

约束条件

  • 1e-4 <= S, K <= 1e6(spot 与 strike 为正有限浮点);1e-4 <= T <= 30.0(年化到期,严格为正);-0.10 <= r <= 0.50(连续复利无风险利率);0 <= market_price <= 1e7;1e-9 <= tol <= 1e-2;is_call 取 {0, 1}(1 表示看涨、0 表示看跌)
  • BS 定价公式:令 `d1 = (ln(S/K) + (r + 0.5*sigma^2)*T) / (sigma*sqrt(T))`、`d2 = d1 - sigma*sqrt(T)`,看涨价为 `S*N(d1) - K*exp(-r*T)*N(d2)`、看跌价为 `K*exp(-r*T)*N(-d2) - S*N(-d1)`,其中 `N(x) = 0.5*(1 + erf(x/sqrt(2)))` 为标准正态 CDF(用 `math.erf`)
  • 二分区间固定为 `[0, 5.0]`;当 `hi - lo <= tol` 时停并返回 `(hi + lo) / 2`。`sigma = 0` 处取折现内在价值极限:看涨 -> `max(0, S - K*exp(-r*T))`、看跌 -> `max(0, K*exp(-r*T) - S)`
  • 哨兵返回:若 `market_price < floor - 1e-9`(价格低于该期权的无套利下界)返回 `-1.0`;若 `market_price > BS_price(sigma=5) + 1e-9`(价格超过可搜索的上界)返回 `-1.0`。1e-9 的 slack 用来吸收 forward-then-back 往返中的浮点噪声
  • 输出为单个 float;比较器为 float、`rel_tol = 1e-5`、`abs_tol = 1e-5`。函数名 `solution`。参考解复杂度时间 `O(log2(5/tol))`、空间 `O(1)`——每次二分迭代做一次 BS 评估

样例

Case 1 · statement-example: ATM 1y call sigma=20%

输入: [10.450583572185565,100,100,1,0.05,1,1e-7]

期望: 0.19999999552965164

ATM 1 年期看涨期权(sigma=0.20、r=0.05),由 BS 价反推 IV,得到 0.20

Case 2 · statement-example: 6m put K=95 sigma=30%

输入: [5.363275623326004,100,95,0.5,0.03,0,1e-7]

期望: 0.29999997466802597

6 个月、K=95 的 OTM 看跌(sigma=0.30),反推 IV ~ 0.30

Case 3 · statement-example: 3m deep-OTM call sigma=50%

输入: [2.309250374972599,100,130,0.25,0.04,1,1e-7]

期望: 0.5000000074505806

3 个月、K=130 的深度 OTM 看涨(sigma=0.50),反推 IV ~ 0.50

最近提交

还没有提交记录。

编码区

实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。

加载编辑器...
计时0:00

默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。

Case 1 · statement-example: ATM 1y call sigma=20%

输入: [10.450583572185565,100,100,1,0.05,1,1e-7]

期望: 0.19999999552965164

ATM 1 年期看涨期权(sigma=0.20、r=0.05),由 BS 价反推 IV,得到 0.20

Case 2 · statement-example: 6m put K=95 sigma=30%

输入: [5.363275623326004,100,95,0.5,0.03,0,1e-7]

期望: 0.29999997466802597

6 个月、K=95 的 OTM 看跌(sigma=0.30),反推 IV ~ 0.30

Case 3 · statement-example: 3m deep-OTM call sigma=50%

输入: [2.309250374972599,100,130,0.25,0.04,1,1e-7]

期望: 0.5000000074505806

3 个月、K=130 的深度 OTM 看涨(sigma=0.50),反推 IV ~ 0.50