3. 收益率曲线构建

在固定收益组合估值中,收益率曲线是折现因子的“母体”。曲线一旦失真,后续现金流贴现、利差计算、风险因子映射都会系统性偏移。本节聚焦曲线构建的完整链路:先明确曲线类型,再选择拟合方法,随后进行数据清洗,最后落地为可复用的曲线对象。

一、核心原理:曲线类型决定估值语义

收益率曲线并非只有一条。不同曲线对应不同的市场语义与估值用途,混用会导致折现结果不可解释。常见类型包括:

  • 国债即期曲线(Spot Curve):由零息债券或剥离国债推导,直接用于无风险折现,是估值基准。
  • 国债远期曲线(Forward Curve):由即期曲线推导,反映市场对未来利率的预期,用于远期定价与套保。
  • 互换曲线(Swap Curve):以利率互换报价构建,反映银行间无风险利率,常用于衍生品与浮息债估值。
  • 信用曲线(Credit Curve):在基准曲线上叠加信用利差,用于公司债、金融债估值。

曲线类型的选择取决于估值对象的现金流特征与折现要求。例如,对国债组合应优先使用国债即期曲线;对利率互换组合则应使用互换曲线。曲线类型一旦确定,后续拟合方法与数据源必须与之匹配。

二、拟合方法:样条与 Nelson-Siegel 的取舍

拟合方法决定曲线的平滑度、灵活性与经济含义。实务中主流方法分为两类:

方法 核心思想 优点 局限 适用场景
样条法(Spline) 分段多项式拼接,节点处保证连续性与光滑性 拟合精度高,可贴合复杂期限结构 节点选择敏感,远端易震荡,经济含义弱 流动性好、报价密集的市场
Nelson-Siegel 用水平、斜率、曲率三因子刻画曲线 参数少、经济含义清晰、远端稳定 对复杂形态拟合能力有限 报价稀疏、需稳健外推的场景
Nelson-Siegel-Svensson 在 NS 基础上增加第二曲率因子 兼顾灵活性与稳定性 参数估计更复杂,可能过拟合 中长端形态复杂的市场

选择方法时,应优先考虑曲线的经济可解释性与外推稳定性。若市场报价充足且期限覆盖完整,样条法可提供更高精度;若报价稀疏或需向远端外推,Nelson-Siegel 系列更稳健。

实务建议:先用 Nelson-Siegel 拟合得到基准形态,再用样条法对局部期限进行微调,兼顾稳健性与精度。

三、数据清洗:曲线质量的隐形防线

原始报价常包含异常值、缺失值与期限错配。数据清洗的目标是让输入曲线拟合的数据“干净且一致”。关键步骤包括:

  1. 期限对齐:将不同来源的报价统一到标准期限节点(如 1M、3M、6M、1Y、2Y、3Y、5Y、7Y、10Y、30Y)。
  2. 异常值识别:用中位数绝对偏差(MAD)或分位数法识别偏离过大的报价,避免其主导拟合。
  3. 缺失值处理:优先用相邻期限线性插值;若缺失段过长,应引入外部基准或改用参数法拟合。
  4. 报价一致性检查:确保即期、远期、互换报价之间无套利矛盾,必要时进行三角校验。
切勿直接删除异常值而不记录。异常值可能反映真实的市场分割或流动性溢价,应保留日志并在曲线报告中标注。

四、实战构建:从报价到曲线对象

以下以 Python 为例,展示从原始报价到 Nelson-Siegel 曲线拟合的完整流程。假设已获得一组国债到期收益率报价,期限单位为年。

import numpy as np
from scipy.optimize import minimize

# 原始报价:期限(年)与到期收益率
tenors = np.array([0.25, 0.5, 1, 2, 3, 5, 7, 10, 30])
yields = np.array([0.021, 0.023, 0.026, 0.029, 0.031, 0.034, 0.036, 0.038, 0.042])

# Nelson-Siegel 模型
def ns_curve(t, beta0, beta1, beta2, tau):
    factor = (1 - np.exp(-t / tau)) / (t / tau)
    return beta0 + beta1 * factor + beta2 * (factor - np.exp(-t / tau))

# 目标函数:最小化拟合误差
def loss(params):
    beta0, beta1, beta2, tau = params
    fitted = ns_curve(tenors, beta0, beta1, beta2, tau)
    return np.sum((fitted - yields) ** 2)

# 初始参数与约束
x0 = [0.04, -0.02, 0.01, 2.0]
bounds = [(0, 0.2), (-0.2, 0.2), (-0.2, 0.2), (0.1, 10)]
result = minimize(loss, x0, bounds=bounds, method='L-BFGS-B')

beta0, beta1, beta2, tau = result.x
print(f"beta0={beta0:.4f}, beta1={beta1:.4f}, beta2={beta2:.4f}, tau={tau:.4f}")

# 生成标准期限曲线
std_tenors = np.array([0.25, 0.5, 1, 2, 3, 5, 7, 10, 30])
curve = ns_curve(std_tenors, beta0, beta1, beta2, tau)
for t, y in zip(std_tenors, curve):
    print(f"{t:>5.2f}Y  {y:.4%}")

运行后得到参数与曲线值,即可用于折现因子计算。若需更高精度,可在 NS 基础上叠加样条残差修正。

收益率曲线构建:从报价到曲线对象 原始报价 国债/互换/信用 数据清洗 对齐/去异常/补缺 拟合方法 样条 / NS / NSS 曲线对象 折现因子 曲线类型选择 即期曲线(Spot) 远期曲线(Forward) 互换曲线(Swap) 信用曲线(Credit) 样条法 高精度、贴合复杂形态 节点敏感、远端易震荡 Nelson-Siegel 参数少、经济含义清晰 远端稳定、适合外推

五、误区与复盘

曲线构建中最常见的误区有三类:

  • 曲线类型混用:用互换曲线折现国债现金流,导致无风险利率被信用利差污染。复盘时应核对估值对象与曲线语义是否一致。
  • 过度拟合:样条节点过多导致曲线在远端剧烈震荡,折现因子出现负值。应限制节点数量并加入平滑惩罚项。
  • 清洗不记录:异常值被静默删除,后续无法复现曲线。应保留清洗日志,记录每个被调整的报价及原因。
复盘清单:曲线类型是否匹配估值对象?拟合方法是否与数据密度匹配?清洗步骤是否可复现?曲线远端是否稳定?折现因子是否为正?

完成曲线构建后,应将其封装为可复用的曲线对象,支持按任意期限插值折现因子,并保留参数与清洗记录。这样,后续组合估值与风险计算才能建立在一致、可审计的曲线基础之上。