3. 即期利率曲线自举法构建

即期利率曲线自举法构建 学习卡片

任务说明

给定一组不同期限的附息债券价格(面值100,年付息),用自举法(Bootstrap)逐段推导零息即期利率曲线。核心思路:短端债券直接反推即期利率;长端债券的现金流中,早期现金流用已求出的即期利率贴现,剩余部分反推该期限的即期利率。

自举流程

输入:债券价格 (期限, 票息, 价格) 按期限升序排序 t=1,2,3,... 对每个期限 t 用已知 r₁..r_{t-1} 贴现 反推 r_t 存入曲线 自举公式(期限 t) P_t = Σ_{i=1}^{t-1} C/(1+r_i)^i + (C+100)/(1+r_t)^t ⇒ r_t = [(C+100)/(P_t − Σ_{i<t} C/(1+r_i)^i)]^{1/t} − 1 C = 票息,P_t = 债券市场价格

完整代码

import numpy as np

# 输入:附息债券 (期限年, 年票息, 市场价格),面值100
bonds = [
    (1, 3.0, 100.50),
    (2, 3.5, 101.20),
    (3, 4.0, 102.00),
    (4, 4.5, 102.80),
    (5, 5.0, 103.50),
]

def bootstrap(bonds, face=100.0):
    bonds = sorted(bonds, key=lambda x: x[0])
    spot = {}  # 期限 -> 即期利率
    for t, coupon, price in bonds:
        pv_coupons = sum(coupon / (1 + spot[i])**i for i in range(1, t))
        residual = price - pv_coupons
        # 最后一年现金流 = 票息 + 面值
        r_t = ((coupon + face) / residual) ** (1.0 / t) - 1.0
        spot[t] = r_t
    return spot

spot_curve = bootstrap(bonds)
for t in sorted(spot_curve):
    print(f"t={t}年  即期利率={spot_curve[t]*100:.4f}%")

# 验证:用求得的即期利率重新贴现每只债券,应还原市场价格
print("\n验证(贴现价格 vs 市场价):")
for t, coupon, price in sorted(bonds):
    pv = sum(coupon / (1 + spot_curve[i])**i for i in range(1, t))
    pv += (coupon + 100.0) / (1 + spot_curve[t])**t
    print(f"t={t}  贴现={pv:.4f}  市场={price:.4f}  误差={abs(pv-price):.2e}")

运行方式

python bootstrap.py

验证与通过条件

  • 脚本输出各期限即期利率,且利率随期限变化(曲线非平坦)。
  • 验证段中每只债券的贴现价格与市场价格的误差应接近 0(浮点精度范围内,通常 < 1e-10)。若误差显著大于 0,说明自举公式或现金流处理有误。
  • 可手动检查:t=1 时 residual = price − 0 = price,r₁ = (103/100.5) − 1 ≈ 2.4876%,与代码输出一致。

关键点

  • 债券必须按期限升序处理,否则早期即期利率尚未求出。
  • 最后一年现金流为票息加面值,这是反推 r_t 的关键。
  • 若债券价格不含应计利息(清洁价格),需先转为全价再自举;本例假设价格已为全价。