Lesson 02 · 6 min

Rates: the Swap Engine

Calculation periods, resets, payments, and day counts: the three date machines behind every swap leg.

The deal on the desk

Pershing Square pays Goldman Sachs 3.5% fixed on USD 10,000,000 for five years; Goldman pays back SOFR plus 50 basis points. Two interestRatePayout legs with mirrored payerReceiver, exactly as the protocol predicts. What Foundations skipped is the machinery inside each leg: how the model knows which days to accrue over, when to observe SOFR, and when cash actually moves. Three date machines, one engine.

effectiveDate2026-04-17terminationDate2031-04-173M3M3M3McalculationPeriodDatescarves the calendarresetDates: observe SOFRat each period startpaymentDates: cash movesat each period enddayCountFraction: ACT/360 turnseach period's days into a year fractionrollConvention: "17" means every period boundary lands on the 17th
Key ideas
  • calculationPeriodDates carves the calendar

    From effectiveDate to terminationDate, a calculationPeriodFrequency (here 3M) slices the life of the leg into accrual periods. Everything else hangs off these slices.

  • resetDates observes, paymentDates pays

    The floating leg needs a rate observation per period: resetDates says when to look. paymentDates says when cash moves, with payRelativeTo anchoring payments to period ends here. Observation and payment are separate machines on purpose.

  • dayCountFraction prices the slice

    A period is dates; interest needs a year fraction. ACT/360, 30/360, and friends are competing conventions for that conversion, so the model makes the choice explicit on the leg.

  • rateSpecification is the fixed-or-floating fork

    A three-way choice: fixed, floating, or inflation. Which branch is populated is what the swap qualifier reads to tell the legs apart.

Inside the floating leg

Here is Goldman's leg, trimmed from a payload that runs against the real qualifier. Note the RateSpecification choice picking its floating branch: rateOption names the index to observe, and spreadSchedule adds the 50 basis points on top.

{} interestRatePayout, floating leg, trimmed
{  "payerReceiver": {    "payer": "Party2",    "receiver": "Party1"  },  "rateSpecification": {    "floatingRateSpecification": {      "rateOption": {        "value": "USD-SOFR"      },      "spreadSchedule": {        "price": {          "value": 0.005        }      }    }  },  "dayCountFraction": "ACT/360",  "calculationPeriodDates": {    "effectiveDate": {      "adjustableDate": {        "unadjustedDate": "2026-04-17"      }    },    "terminationDate": {      "adjustableDate": {        "unadjustedDate": "2031-04-17"      }    },    "calculationPeriodFrequency": {      "periodMultiplier": 3,      "period": "M",      "rollConvention": "17"    }  },  "paymentDates": {    "paymentFrequency": {      "periodMultiplier": 3,      "period": "M"    },    "payRelativeTo": "CalculationPeriodEndDate"  },  "priceQuantity": {    "resolvedQuantity": {      "value": 10000000,      "unit": {        "currency": "USD"      }    }  }}
The fixed leg is the same leg type with the other branch: fixedRateSpecification carrying a rateSchedule priced at 0.035. Same dates, same day count, mirrored payerReceiver.

One subtlety worth respecting: real calendars fight back. Period boundaries can land on weekends, so calculationPeriodDatesAdjustments carries a business day convention like MODFOLLOWING and the business centers to check, and the roll convention pins the day each period turns over. Determinism is the goal: both parties can regenerate the exact same schedule from the same data.

From two legs to a name

Run the protocol: two interestRatePayout legs, one fixed branch, one floating branch, nothing else. Qualify_InterestRate_IRSwap_FixedFloat pattern-matches exactly that and the product earns its name. Siblings cover the variations: an overnight-indexed version, a zero coupon version, basis swaps for float-versus-float. Nobody declares "this is a swap"; the legs do.

Try itOpen Qualify_InterestRate_IRSwap_FixedFloat in the Playground and run its True path example: this lesson's swap, qualifying live. Then delete the floating leg and watch the qualifier say no.
◆ Checkpoint

01Which machine decides when cash actually moves?

1 / 3