寻找使误差为零的数
债券价格很容易由收益率算出,反过来由价格求收益率则不容易。你通过搜索解 f(y)=P(y)-市场价格=0。牛顿法沿切线前进:从猜测值 y 跳到 y-f(y)/f'(y),在解附近每一步正确位数大约翻倍,所以几次迭代就够,但它需要导数,起点不好时可能走偏。二分法只需要 f 变号的区间 [lo,hi]:反复把区间减半,所以不会失败,但每步只多一位二进制数字,要把宽 65 的区间缩到 10⁻¹⁰ 以下需要 40 步。布伦特法 scipy.optimize.brentq 保留区间的安全性并加入插值步,函数调用次数通常只相当于几次二分。用 full_output=True 时它还返回一条记录,其 function_calls 字段说明它调用了多少次你的函数。
同一工具还能反推布莱克–斯科尔斯公式。看涨期权价格随波动率上升,所以对每个报价,你让 brentq 在 [10⁻⁴,5] 中找出能还原它的 σ。只有价格严格位于内在价值 max(S-Ke^(-rT),0) 与股价 S 之间才可行;在此之外不存在波动率,正确的答案是 NaN 而不是异常,这样一个坏报价不会让整条微笑曲线中断。2026 年 10 月 9 日 10 年期美债收益率为 5.24%,所以年息 5% 的 10 年期债券价格为 97.121。牛顿法 4 次迭代、布伦特法 10 次函数调用、二分法 40 次找回收益率。10%、20%、40%、80% 的隐含波动率还原精度优于 10⁻⁶。知道每种方法的代价和何时会失败,才能为整条债券曲线或期权链选对方法。
- 牛顿法快,但需要导数和不错的起点:这里用了 4 步。
- 二分法不会失败但很慢:宽 65 的区间要 40 步。
- 使用
brentq并处理不可能的情形:区间加插值,无解时返回 NaN。
实验:评分内容
- 债券价格10 分
- 手写牛顿法20 分
- 手写二分法15 分
- scipy 的布伦特法15 分
- 三个求解器并排10 分
- 隐含波动率15 分
- 真实数据研究15 分