4. 利率期限结构:即期利率、远期利率、收益率曲线构建(Nelson-Siegel模型)
做债券量化风控,绕不开一个核心问题:利率到底怎么变?
你想想看,债券定价、久期计算、风险敞口评估,哪一样离得开利率?但现实中的利率不是一条直线,它随着期限不同而变化。这就是我们今天要聊的——利率期限结构。
我个人习惯把期限结构比作「利率的年龄特征」。就像人一样,不同年龄段的性格不一样;不同期限的利率,行为模式也完全不同。短端受货币政策影响大,长端则更多反映经济预期。
4.1 即期利率与远期利率:从哪来,到哪去
先搞清楚两个基本概念。
即期利率,说白了就是你现在借钱,从现在开始到未来某个时点,一次性还本付息的年化收益率。比如你买一张1年期零息国债,到期收益率就是1年期即期利率。
远期利率呢?它是对未来某个时间段的利率预期。比如「1年后的1年期利率」,这就是一个远期利率。它不是现在能直接买到的,而是从即期利率推导出来的。
我记得刚入行时,有个同事把远期利率当成了未来的即期利率,结果做对冲策略时亏了不少。这里要提醒大家:远期利率是隐含的预期,不是承诺。它反映的是市场对未来利率的集体判断,但未来实际利率可能完全不同。
两者之间的关系,可以用一个简单的公式表达:
(1 + s₂)² = (1 + s₁) × (1 + f₁,₁)
其中 s₁ 是1年期即期利率,s₂ 是2年期即期利率,f₁,₁ 是1年后的1年期远期利率。
这个公式的逻辑很简单:投资2年期的总收益,应该等于先投1年、再续投1年的总收益。否则市场上就会出现套利机会。
核心要点:
- 即期利率:现在借钱,到期一次还本付息的利率
- 远期利率:未来某个时间段的利率预期
- 两者通过无套利条件相互推导
4.2 收益率曲线:债券市场的「心电图」
收益率曲线,就是把不同期限的即期利率连成一条线。它反映了市场对经济前景、通胀预期和货币政策的集体判断。
常见的曲线形态有三种:
- 正常向上倾斜:期限越长,利率越高。说明市场预期未来经济增长,通胀上升,需要更高的风险补偿。
- 平坦或倒挂:长端利率低于短端。这往往是经济衰退的前兆。我在2020年初就见过一次倒挂,当时很多同行还不以为然,结果...嗯,后来的事大家都知道了。
- 驼峰形:中期利率最高。这种情况比较少见,通常出现在货币政策紧缩周期中段。
做风控时,我特别关注曲线的斜率和曲率。斜率变化直接影响银行净息差,曲率变化则影响债券组合的凸性对冲效果。
实战经验:我曾经用收益率曲线斜率变化做利率方向性交易,效果不错。但要注意,斜率指标在极端行情下会失效——比如2020年3月流动性危机时,曲线斜率瞬间飙升,但方向完全反了。
4.3 Nelson-Siegel模型:用三个因子拟合整条曲线
实际市场中,我们只能观察到有限几个期限的利率。比如国债只有1年、2年、3年、5年、7年、10年这几个点。但做风控时,我们需要任意期限的利率——比如计算一个4.5年期债券的久期。
这时候就需要曲线拟合。Nelson-Siegel模型(简称NS模型)是业界最常用的方法之一。
NS模型的数学形式如下:
y(τ) = β₀ + β₁ × (1 - e^(-τ/λ)) / (τ/λ) + β₂ × [(1 - e^(-τ/λ)) / (τ/λ) - e^(-τ/λ)]
其中:
- y(τ) 是期限为 τ 的即期利率
- β₀ 是水平因子,控制曲线的整体水平
- β₁ 是斜率因子,控制曲线的倾斜程度
- β₂ 是曲率因子,控制曲线的弯曲程度
- λ 是衰减参数,控制因子的衰减速度
这三个因子各有各的「性格」:
| 因子 | 含义 | 对曲线的影响 | 经济解释 |
|---|---|---|---|
| β₀ | 水平 | 整体平移 | 长期利率预期 |
| β₁ | 斜率 | 短端 vs 长端 | 货币政策立场 |
| β₂ | 曲率 | 中期弯曲 | 经济周期位置 |
我建议你记住一个直观理解:β₀ 决定曲线「多高」,β₁ 决定「多陡」,β₂ 决定「多弯」。
注意:NS模型虽然好用,但也不是万能的。我曾经用它拟合一个流动性极差的市场数据,结果参数估计完全失真。后来我加了一个约束条件——β₀ 必须大于所有观测到的利率——才解决了问题。
4.4 实战:用Python实现Nelson-Siegel拟合
光说不练假把式。下面是我常用的拟合代码,你可以直接拿去用:
import numpy as np
from scipy.optimize import minimize
def ns_yield(tau, beta0, beta1, beta2, lam):
"""Nelson-Siegel模型计算即期利率"""
factor1 = (1 - np.exp(-tau/lam)) / (tau/lam)
factor2 = factor1 - np.exp(-tau/lam)
return beta0 + beta1 * factor1 + beta2 * factor2
def fit_ns(maturities, yields):
"""拟合NS模型参数"""
def objective(params):
beta0, beta1, beta2, lam = params
fitted = ns_yield(maturities, beta0, beta1, beta2, lam)
return np.sum((fitted - yields) ** 2)
# 初始参数设置
init_params = [np.mean(yields), -0.02, 0.01, 2.0]
result = minimize(objective, init_params, method='L-BFGS-B')
return result.x
# 示例数据
maturities = np.array([1, 2, 3, 5, 7, 10])
yields = np.array([0.025, 0.028, 0.030, 0.032, 0.033, 0.034])
beta0, beta1, beta2, lam = fit_ns(maturities, yields)
print(f"拟合参数: β₀={beta0:.4f}, β₁={beta1:.4f}, β₂={beta2:.4f}, λ={lam:.4f}")
这段代码的核心逻辑很简单:用最小二乘法,让NS模型生成的曲线尽可能贴近观测到的利率点。
拟合完成后,你就可以用 ns_yield() 函数计算任意期限的利率了。比如:
# 计算4.5年期利率
rate_4_5 = ns_yield(4.5, beta0, beta1, beta2, lam)
print(f"4.5年期即期利率: {rate_4_5:.4f}")
一个小技巧:我习惯在拟合时加入正则化项,防止参数过度波动。特别是当数据点较少时,不加约束的NS模型容易过拟合。
4.5 知识体系总览
下面这张图,把本章的核心逻辑串起来了:
从这张图可以看得很清楚:即期利率是基础,远期利率是衍生,收益率曲线是可视化表达,而NS模型是把这一切量化的工具。
做风控时,我每天都会盯着这三个因子的变化。β₀ 上升,说明长期通胀预期在升温;β₁ 变陡,可能央行要加息了;β₂ 出现异常弯曲,往往预示着经济拐点临近。
嗯,这就是利率期限结构的核心内容。下次当你看到一条收益率曲线时,希望你能读出它背后的故事——不只是数字,更是市场参与者的集体情绪和预期。
公众号:蓝海资料掘金营,微信deep3321