The rates terminal · how it works

How the swap is calculated

A swap looks complicated and is not. It is two streams of payments, each one worked out, each one discounted back to today, and then subtracted. Everything else is convention.

Below is the whole calculation in eight steps, in the order our engine runs them — so any number on the terminal traces back to the code that produced it.

8 steps 6 minutes Written for treasurers & CFOs No maths beyond arithmetic

01

Two legs

swap.ts · indexes.ts

You receive one leg and pay the other. Each carries a currency, a notional, and a rate that is either fixed or tied to an index.

The index is the part people gloss over, and it is where the money is. On the BRL side there are three genuinely different products:

BRL — three products, not three labels
ProductYou are paidQuoted as
Préa fixed rate13.79%
CDI + spreadCDI, plus a marginCDI + 1.50%
% do CDIa percentage of CDI108% do CDI

The last two are not the same thing, and do not convert cleanly into each other — see step 04. The terminal now quotes all three, plus the equivalent local convention in sixteen other currencies: TIIE-28 in Mexico, CD-91 in Korea, HIBOR in Hong Kong, the overnight index everywhere else.

02

Build the dates

schedule.ts · calendars.ts

Start date to maturity, cut into periods by the payment frequency, with every date rolled onto a business day on the right calendar — ANBIMA for BRL, and so on. A zero-coupon swap is simply this with one period.

03

Build the curve

curve.ts

Take today's traded instruments — B3 DI1 futures for BRL, Treasury yields for USD, government par yields elsewhere — and turn them into discount factors.

today  R$1.000

in 1Y  R$0.879

A discount factor answers one question: what is R$1 on that future date worth today? At a one-year discount factor of 0.879, R$1 in a year is 87.9 centavos now.

The engine bootstraps these properly: a par bond yield is not a zero rate, and treating it as one is a real and common error.

04

Work out each period's interest

swap.ts — fixedInterest, floatInterest

Fixed leg. Either simple interest, or — on BUS/252, the Brazilian Pré convention — compounded:

I = N × r × τ    or    I = N × ((1 + r)τ − 1)

Floating leg. The curve already implies what the index will do. That implied growth over a period is:

G = DF(start) / DF(end)      I = N × (G − 1)

with the spread added on top (SOFR style) or multiplied in (CDI style).

The one that surprises people

108% do CDI does not mean “take the CDI interest and multiply by 1.08.” It means each business day accrues at 108% of that day's CDI factor, and those daily factors compound:

G = ∏ over business days ( 1 + 1.08 × (Fd − 1) )

Because the compounding cross-terms pick up 1.082 rather than 1.08, this comes out slightly above 1.08 × the plain CDI interest — a few basis points over a year at a typical BRL rate. Small, and exactly the kind of thing worth checking against your bank's number. Our terminal computes it day by day rather than approximating.

05

Add the principal

swap.ts · amortization.ts

Initial exchange, amortization payments, final exchange — each optional, and each landing on its own date rather than being folded into a coupon.

06

Discount everything back

swap.ts — priceLeg

Multiply each cash flow by the discount factor for its payment date.

For a cross-currency swap, flows convert at the covered-interest-parity forward:

F = S × DFleg / DFreporting

Usefully, discounting in the leg currency and converting at spot gives the identical answer — so the ledger shows the forward, which is the number a treasurer recognises, without changing the maths.

07

Add the legs up

swap.ts — priceSwap

NPV = PV(receive) PV(pay)

In the reporting currency. That is the trade's mark-to-market.

08

Solve for the fair rate

swap.ts — solvePar, dv01

Leave one leg's rate blank and the terminal finds the number that makes NPV exactly zero. That is the fair mid — the rate at which neither side is ahead, before anyone's spread. It is the number a bank quote should be measured against.

There is no closed-form formula for this in the general case, so it is found by root-search: try a rate, price the swap, adjust, repeat until the NPV is zero to ten decimal places.

DV01 is the same trade repriced with every curve shifted up one basis point and down one basis point — the value change per basis point.

Provenance

What is a market number, and what is an assumption

This line matters more than any of the maths above, and the terminal is built so it is always visible on screen. A tool that hides which half is which is not measuring anything.

Real, live, traded

  • Discount curvesBRL, USD, EUR, GBP, JPY, CAD, AUD, HKD, CHF — bootstrapped from traded instruments, never surveys or forecasts.
  • Spot FXAll sixteen quoted pairs.
  • CDI and HIBORFor these two the curve is the index — nothing is being stood in for.

Assumptions, marked on screen

  • An index marked with an asteriskis projected off a government curve, not the named index — no free traded term curve for it exists.
  • Term indexesTerm SOFR, EURIBOR, TIIE, BBSW, CD 91 carry a fixed basis in basis points, set in source and editable per leg. An estimate.
  • Eight currencies have no live curveMXN, COP, PEN, CLP, CNY, SGD, INR and KRW run on one flat policy rate, flagged as degraded.
  • Forwards are parity-impliednot traded forward points. For BRL the onshore market prices the cupom cambial, and a dealer's mark will differ.
  • Inflation legs are listed, not pricedIPCA, IGP-M, CPI, HICP, RPI, UDI and UF need a real-rate curve and none is wired. Greying them out is deliberate — the alternative is a number nobody can stand behind.

Educational material on how swap pricing is constructed. Rates and curves are sourced from public central-bank and exchange feeds and are illustrative, not a quotation. Not tax advice, investment advice, or a recommendation to transact.

Price one yourself.

The terminal is open — pick two legs, a maturity and a notional, and it solves the fair mid on today's curves. Every intermediate is on screen, down to the discount factor.