2. 固定收益基础

在进入 QuantLib 的定价与曲线构建之前,必须先建立一套“市场语言”与“现金流语言”的映射。固定收益产品的复杂性,往往不在于公式本身,而在于要素定义、计息惯例与报价方式之间的细微差异。同一只债券,在不同市场、不同计息基准下,现金流日期与金额可能完全不同,进而导致收益率与价格出现系统性偏差。

一、债券的核心要素:从合同到现金流

一只标准债券可以拆解为以下要素:面值(Notional)、票息率(Coupon Rate)、付息频率(Frequency)、起息日(Issue Date)、到期日(Maturity Date)、计息基准(Day Count)、付息日调整规则(Business Day Convention)以及是否含期权条款。QuantLib 中对应为 FaceAmount、CouponRate、Tenor、IssueDate、MaturityDate、DayCounter、Calendar 与 BusinessDayConvention。

其中最容易出错的是“计息基准”与“付息日调整规则”的组合。例如,一只按 Actual/Actual (ICMA) 计息、付息日为 Modified Following 的国债,其每个付息周期的应计利息天数并非简单等于日历天数,而是依据付息周期实际天数计算。若忽略这一点,在 QuantLib 中直接使用 Actual/365 构建,价格会出现明显偏差。

核心原则:债券定价的本质是“将未来每一笔现金流按对应期限的贴现因子折现”。因此,任何影响现金流日期或金额的要素,都会直接改变定价结果。

二、计息规则与市场惯例:Day Count 与 Business Day

计息规则决定了两个日期之间的“时间分数”(Year Fraction)。常见基准包括:

  • Actual/Actual (ICMA):按付息周期实际天数计算,适用于多数国债与市政债。
  • Actual/360:货币市场工具常用,如美国短期国债、商业票据。
  • Actual/365 Fixed:部分欧洲债券与掉期使用。
  • 30/360:公司债与部分机构债常用,假设每月30天、每年360天。
  • Actual/Actual (ISDA):掉期与衍生品常用,按实际天数与年度天数比例计算。

付息日调整规则则决定当付息日落在非营业日时如何移动。常见规则有 Following、Modified Following、Preceding、Modified Preceding 与 Unadjusted。QuantLib 中通过 Calendar 与 BusinessDayConvention 联合控制。若调整规则与市场惯例不一致,会导致现金流日期整体偏移,进而影响贴现因子取值。

三、收益率与价格关系:从 YTM 到曲线

收益率与价格呈反向关系,但并非线性。对于固定利率债券,价格对收益率的敏感度由久期(Duration)与凸性(Convexity)刻画。到期收益率(YTM)是使债券未来现金流现值等于当前价格的单一贴现率,隐含了“收益率曲线平坦”与“再投资收益率等于YTM”两个假设。

在 QuantLib 中,常用 FixedRateBond 与 DiscountingBondEngine 计算净价与全价。全价 = 净价 + 应计利息。应计利息由 DayCounter 与 IssueDate、SettlementDate 共同决定。以下代码片段展示如何构建一只债券并计算其净价:

import QuantLib as ql

today = ql.Date(15, 1, 2025)
ql.Settings.instance().evaluationDate = today

calendar = ql.UnitedStates(ql.UnitedStates.GovernmentBond)
day_counter = ql.ActualActual(ql.ActualActual.ISDA)
settlement_days = 1
settlement_date = calendar.advance(today, settlement_days, ql.Days)

issue_date = ql.Date(15, 1, 2020)
maturity_date = ql.Date(15, 1, 2030)
coupon_rate = 0.03
frequency = ql.Semiannual

schedule = ql.Schedule(issue_date, maturity_date,
                       ql.Period(frequency),
                       calendar,
                       ql.ModifiedFollowing,
                       ql.ModifiedFollowing,
                       ql.DateGeneration.Backward,
                       False)

bond = ql.FixedRateBond(settlement_days, 100.0, schedule,
                        [coupon_rate], day_counter)

flat_curve = ql.FlatForward(settlement_date, 0.035, day_counter)
bond_engine = ql.DiscountingBondEngine(
    ql.YieldTermStructureHandle(flat_curve))
bond.setPricingEngine(bond_engine)

print("Clean Price:", bond.cleanPrice())
print("Accrued Amount:", bond.accruedAmount())
print("Dirty Price:", bond.dirtyPrice())

运行后可得净价、应计利息与全价。若将 day_counter 改为 ql.Thirty360(),净价会发生变化,这正是计息规则对定价影响的直接体现。

四、常见品种与市场惯例对照

不同债券品种在计息、付息与报价上存在显著差异。下表汇总了主要品种的典型惯例,便于在 QuantLib 中快速选择对应参数:

品种 计息基准 付息频率 报价方式 典型市场
美国国债 Actual/Actual (ICMA) 半年 净价 + 应计 美国
德国国债 Actual/Actual (ICMA) 年 净价 + 应计 欧洲
中国国债 Actual/Actual 年或半年 净价 + 应计 中国
美国公司债 30/360 半年 净价 + 应计 美国
欧洲商业票据 Actual/360 贴现 贴现率 欧洲
利率掉期 Actual/360 或 30/360 季度或半年 互换利率 全球
在 QuantLib 中构建债券时,建议先确认三个参数:DayCounter、BusinessDayConvention 与 DateGeneration。这三者共同决定现金流日期与金额,是定价准确性的基石。

五、误区与复盘:常见陷阱

初学者常犯的错误包括:将净价直接当作全价输入定价引擎;忽略结算日与起息日之间的应计利息;在非营业日调整规则上使用 Unadjusted 导致现金流日期偏移;以及将不同市场的计息基准混用。以下是一个典型复盘场景:

  • 问题:某学员用 Actual/365 对一只美国国债定价,结果净价偏高约 0.3%。
  • 原因:美国国债使用 Actual/Actual (ICMA),付息周期内天数计算方式不同,导致应计利息与贴现因子均出现偏差。
  • 修正:将 DayCounter 改为 ql.ActualActual(ql.ActualActual.ISDA),并确认 Schedule 的 DateGeneration 为 Backward。
  • 验证:对比 Bloomberg 或 Reuters 的净价与应计利息,误差应小于 0.01%。
QuantLib 的 FixedRateBond 默认使用面值 100,若实际面值为 1000 或 10000,需在构造时显式传入 FaceAmount,否则价格与应计利息会按 100 面值计算,导致数量级错误。

掌握上述要素、计息规则与市场惯例后,才能在后续章节中正确构建收益率曲线、校准贴现因子,并进一步完成利率互换、债券期权等复杂产品的定价。固定收益的“基础”并非简单概念,而是贯穿整个定价流程的约束条件。

债券要素 → 现金流 → 定价关系 债券要素 面值 / 票息率 付息频率 / 到期日 计息基准 / 调整规则 起息日 / 结算日 现金流序列 C1, C2, C3, ..., Cn 付息日 + 到期本金 应计利息 全价 = 净价 + 应计 收益率与价格 YTM / 贴现因子 久期 / 凸性 价格 ↑ 收益率 ↓ 曲线构建基础 计息基准与市场惯例对照 品种 计息基准 付息频率 报价方式 市场 美国国债 Actual/Actual (ICMA) 半年 净价 + 应计 美国 德国国债 Actual/Actual (ICMA) 年 净价 + 应计 欧洲 美国公司债 30/360 半年 净价 + 应计 美国 利率掉期 Actual/360 或 30/360 季度/半年 互换利率 全球 关键:DayCounter + BusinessDayConvention + DateGeneration 共同决定现金流日期与金额