2. 利率基础概念

在 QuantLib 中做利率衍生品定价,第一步不是写代码,而是把五个基础量之间的关系彻底理清:即期利率、远期利率、贴现因子、计息方式与 DayCount 约定。它们共同构成利率曲线的“坐标系”,任何一次定价错误,追根溯源往往都落在其中某一环。

一、核心原理:五个量其实是一件事的五种表达

贴现因子 DF(t) 是利率世界最底层的量:它表示今天投入 1 元、在 t 时刻收回的现值系数。即期利率 z(t) 是把 DF 用“年化复利”语言翻译出来的结果;远期利率 f(t1,t2) 则是两个即期利率之间的边际利率,描述未来某段区间的资金价格。三者关系可写成:

DF(t) = 1 / (1 + z(t) * τ)^(1/τ)      // 一般复利形式
DF(t) = exp(-z(t) * t)                  // 连续复利形式
f(t1,t2) = (z(t2)*t2 - z(t1)*t1) / (t2 - t1)   // 连续复利下的远期利率
DF(t1,t2) = DF(t2) / DF(t1)             // 远期贴现因子

其中 τ 是计息期长度,由 DayCount 约定决定。也就是说,DayCount 不是“格式问题”,而是直接进入公式的乘数因子。QuantLib 把这一层抽象为 DayCounter 类,把利率曲线抽象为 YieldTermStructure,二者组合才能给出可用的 DF。

二、方法流程:从市场报价到可用曲线

  1. 确定计息方式:货币市场常用单利,互换与债券常用复利,OIS 常用连续复利或日复利。
  2. 选择 DayCounter:如 Actual360、Actual365Fixed、Thirty360、ActualActual(ISDA)。
  3. 由报价反推 DF:存款用单利公式,FRA 用远期利率公式,互换用 bootstrap 逐段剥离。
  4. 构建曲线对象:在 QuantLib 中通常用 PiecewiseYieldCurve 配合 DepositRateHelper、SwapRateHelper 等。
  5. 校验:用曲线重算报价,误差应在 1e-8 量级以内。

关键认知:曲线不是“数据”,而是“由报价和约定共同定义的函数”。换一个 DayCounter,同一条报价会得到不同的 DF 和远期利率。

三、可视化:即期、远期与贴现因子的联动关系

即期利率 · 远期利率 · 贴现因子 的联动 期限 t 利率 / DF 即期利率 z(t) 远期利率 f(t) 贴现因子 DF(t) 同一 t 点:DF 与 z 一一对应

图中三条曲线共享同一横轴:即期利率随期限上升,远期利率通常高于即期(正向曲线),而贴现因子单调下降。任意一点 t 上,DF 与 z 一一对应;任意两点之间,远期利率由两点的即期利率差决定。

四、案例与场景:一次互换定价中的 DayCount 陷阱

假设 3 个月美元存款报价 5.25%,使用 Actual360;而 2 年互换报价 4.80%,使用 Thirty360。若在 QuantLib 中统一用 Actual365Fixed 构建曲线,虽然代码能跑通,但 bootstrap 出的 DF 会系统性偏移,导致互换 NPV 出现几个基点的误差。正确做法是:

DayCounter depoDC = Actual360();
DayCounter swapDC = Thirty360(Thirty360::USA);
auto depo = MakeDepositRateHelper(0.0525, 3*Months, 2, calendar, depoDC);
auto swap = MakeSwapRateHelper(0.0480, 2*Years, ... , swapDC);
// 每个 helper 携带自己的 DayCounter,曲线自动处理

QuantLib 的 RateHelper 设计哲学:报价与约定绑定在 helper 上,曲线只负责求解。不要试图在曲线层面“统一” DayCounter。

五、误区与复盘

误区后果正确做法
把即期利率当远期利率用远期定价偏差随期限放大用 DF 比值或即期差公式推导远期
忽略 DayCount 差异曲线 bootstrap 系统性偏移每个报价绑定其市场约定
用单利处理长期互换长期 DF 被高估互换段用复利或连续复利
直接对利率做线性插值远期利率出现锯齿对 log(DF) 插值或使用单调凸插值

复盘要点:任何“利率曲线看起来不对”的问题,先检查三件事——报价是否与 helper 匹配、DayCounter 是否与市场一致、插值是否作用在正确的量上。这三步能解决 80% 以上的曲线异常。