3. 即期利率曲线自举法构建
任务说明
给定一组不同期限的附息债券价格(面值100,年付息),用自举法(Bootstrap)逐段推导零息即期利率曲线。核心思路:短端债券直接反推即期利率;长端债券的现金流中,早期现金流用已求出的即期利率贴现,剩余部分反推该期限的即期利率。
自举流程
完整代码
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 的关键。
- 若债券价格不含应计利息(清洁价格),需先转为全价再自举;本例假设价格已为全价。