4. Strata 核心数据模型

在 OpenGamma Strata 中,定价与风险计算并不是从公式开始的,而是从一组稳定的基础抽象开始的。Currency、DayCount、BusinessDayAdjustment、Schedule、Period、Notional 这些类型构成了整个固定收益建模的“骨架”。理解它们之间的依赖关系,比记住某个 API 的调用方式更重要,因为几乎所有后续的曲线构建、现金流折现和敏感度计算,都建立在这些抽象的正确组合之上。

核心原理:为什么需要这些抽象

固定收益产品的本质是“未来一系列现金流”。要描述这笔现金流,必须回答六个问题:用什么货币、计息天数怎么算、遇到节假日怎么调整、日期序列如何生成、每期多长、名义本金是多少。Strata 用六个不可变对象分别回答这六个问题,并让它们可以自由组合。

  • Currency:标识货币及其最小精度,决定金额舍入和展示格式。
  • DayCount:定义应计利息的天数计算规则,如 ACT/360、30/360、ACT/ACT。
  • BusinessDayAdjustment:定义节假日日历与调整规则,如 Following、ModifiedFollowing。
  • Period:表示一个时间长度,如 3M、6M、1Y,是生成日期的步长。
  • Schedule:由起止日期、频率、调整规则和滚动约定生成完整日期序列。
  • Notional:名义本金,可以是固定值,也可以是随日期变化的阶梯或摊销结构。

这些抽象的共同设计哲学是“不可变 + 可组合”。一旦创建,对象不会被修改;需要变化时,通过工厂方法生成新对象。这保证了定价过程中不会因为共享状态而产生难以追踪的副作用。

方法流程:从参数到现金流日期

实际建模时,这些抽象通常按以下顺序协作。以一笔 5 年期、每半年付息、ACT/360、ModifiedFollowing 的美元债券为例:

  1. 选择 Currency.USD,确定货币精度为 2 位小数。
  2. 选择 DayCounts.ACT_360,用于计算每期应计利息。
  3. 选择 BusinessDayAdjustment.of(ModifiedFollowing, HolidayCalendarIds.USNY),处理纽约节假日。
  4. 用 Period.ofMonths(6) 表示付息频率。
  5. 用 Schedule.builder() 设置起止日期、频率、调整规则和滚动约定,生成日期序列。
  6. 用 Notional.of(1_000_000) 或摊销结构绑定到每期现金流。

下面是一段典型的 Strata 代码片段,展示这些抽象如何组合:

Schedule schedule = Schedule.builder()
    .startDate(LocalDate.of(2024, 1, 15))
    .endDate(LocalDate.of(2029, 1, 15))
    .frequency(Frequency.P6M)
    .businessDayAdjustment(
        BusinessDayAdjustment.of(
            BusinessDayAdjustments.MODIFIED_FOLLOWING,
            HolidayCalendarIds.USNY))
    .rollConvention(RollConventions.DAY_15)
    .build();

DayCount dayCount = DayCounts.ACT_360;
Notional notional = Notional.of(1_000_000);
Currency currency = Currency.USD;

执行后,schedule 会生成 10 个付息期,每期日期都经过节假日调整。若某期落在周末,ModifiedFollowing 会将其顺延到下一个工作日,但不会跨月。

可视化:抽象之间的依赖关系

下图展示了这些核心抽象在 Strata 中的组合关系。Currency 和 DayCount 是基础层,Period 与 BusinessDayAdjustment 共同驱动 Schedule 生成日期序列,Notional 则与 Schedule 一起构成现金流描述。

Currency 货币与精度 DayCount 计息天数规则 Period 时间步长 3M/6M/1Y BusinessDay Adjustment 节假日调整 Schedule 日期序列生成器 Notional 名义本金/摊销 Cashflow 现金流描述 货币精度 计息规则 频率 调整规则

案例场景:一笔浮动利率债券的建模

假设我们要为一只 3 年期浮动利率债券建模,票面利率为 3M SOFR + 50bp,季度付息,ACT/360,ModifiedFollowing,名义本金 500 万美元。在 Strata 中,这些参数会映射为:

业务参数 Strata 抽象 具体取值
货币 Currency Currency.USD
计息规则 DayCount DayCounts.ACT_360
付息频率 Period Period.ofMonths(3)
节假日调整 BusinessDayAdjustment ModifiedFollowing + USNY
日期序列 Schedule 2024-01-15 至 2027-01-15
名义本金 Notional 5,000,000 USD

建模时,Schedule 会生成 12 个季度日期。每个日期经过 USNY 日历调整后,可能比原始滚动日期提前或延后 1 到 2 天。DayCount 则决定每期应计利息的天数,ACT/360 意味着实际天数除以 360。Notional 在整个存续期内保持不变,但若换成摊销结构,每期本金会递减。

提示:Strata 的 Schedule 支持 stubConvention 参数,用于处理首期或末期不是完整周期的情况。例如债券发行日到第一个付息日只有 2 个月,就需要设置 ShortInitial 或 LongInitial。

误区与复盘

初学者在使用这些抽象时,最常见的误区有三个。

  • 误区一:把 Period 当成日期。Period 是长度,不是具体日期。Schedule 才是日期序列。混淆两者会导致日期计算错误。
  • 误区二:忽略 BusinessDayAdjustment 的日历。只设置 ModifiedFollowing 而不指定 HolidayCalendar,调整结果可能不符合目标市场惯例。
  • 误区三:认为 Notional 一定是常数。Strata 的 Notional 支持阶梯和摊销,若业务是摊还债券,必须使用对应的工厂方法。
注意:DayCount 和 BusinessDayAdjustment 是两个独立维度。DayCount 只影响利息计算的天数,BusinessDayAdjustment 只影响日期落在哪一天。不要因为调整了日期就认为计息天数会自动变化,两者需要分别配置。

复盘时,建议用一个小例子验证:取一笔 6 个月、ACT/360、ModifiedFollowing 的美元贷款,手动计算应计天数,再与 Strata 的 dayCount.yearFraction(start, end) 结果对比。如果一致,说明抽象组合正确;如果不一致,优先检查 DayCount 类型和日期调整顺序。

掌握这些基础抽象后,后续的曲线构建、定价函数和风险敏感度都会变得有迹可循。它们不是孤立的工具类,而是一套描述固定收益产品的通用语言。