Skip to main content

Data Model: YU17-otc-rates

Everything inherited from YU16-cdm-instruments is unchanged. This state adds two command types, one replicated store, one snapshot record, one cut section and one artifact.

1. The booking command; TYPE_SWAP_BOOK (12)​

Rides the inherited InputEventMessage (SBE template 1) on the unchanged 64-byte record. AeronReplicationCodec copies commandType through without interpreting it.

FieldSlotTypeMeaning
booking accountaccountIdintunchanged
directionsidebyte0 = receive fixed, 1 = pay fixed
notionalqtyintwhole currency units, 1..2147483647
fixed ratelimitPxlongannual decimal fraction Γ— 1e6 (0.042 β†’ 42000)
idempotency keypriceTickslongclientOrderKey; 0 = no key
conventionssecurityIdintindex into the convention table, NOT a symbol id
effective dateorderRef bits 0-15uint16epoch day
maturity dateorderRef bits 16-31uint16epoch day

Epoch day 65535 is 2149-06-06. The gateway refuses a date outside that range before sequencing; InputEvent.setSwapDates masks, so an out-of-range day would otherwise wrap into a plausible date.

1b. The swaption command; TYPE_SWAPTION_BOOK (13)​

Every slot above keeps its meaning, because a swaption's underlying IS a swap: fixedRate is the strike, side is the direction of the underlying's fixed leg (1 = a payer swaption), qty is the underlying notional. The option wrapper replaces the plain convention index in securityId:

FieldSlotTypeMeaning
conventionssecurityId bits 0-7uint8index into the convention table
exercise stylesecurityId bits 8-15uint8index into the exercise-style table
expiry datesecurityId bits 16-31uint16epoch day, refused past 2149-06-06

A swap sets only the low byte, so both products read the convention index the same way and no branch is needed. Expiry 0 is therefore what a swap carries; which is exactly why the product is the command type and never "is the expiry set".

2. The convention table​

Compiled into the binary, addressed by index, stored nowhere. Append only: an index that has been journaled keeps its meaning permanently.

IndexNameFloat indexFrequencyDay countCurrency
0USD-SOFR-1Y-ACT360USD-SOFR1YACT/360USD
1USD-SOFR-3M-ACT360USD-SOFR3MACT/360USD
2EUR-ESTR-1Y-ACT360EUR-ESTR1YACT/360EUR
3GBP-SONIA-1Y-ACT365FGBP-SONIA1YACT/365FGBP
4JPY-TONA-1Y-ACT365FJPY-TONA1YACT/365FJPY

An index outside the table aborts the render, naming the index and the range this build knows.

Exercise style​

The second index-addressed table, under the same append-only rule.

IndexStyle
0EUROPEAN
1BERMUDAN
2AMERICAN

A style is a TERM, not lifecycle: no exercise event is modelled, but two swaptions identical in every other column are different instruments if their styles differ.

3. The contract store (replicated state)​

Held in MatchingEngineClusteredService, beside the symbol table. Capacity MAX_CONTRACTS = 4096; at capacity a booking is refused with RiskReason.CAPACITY. Nothing removes a contract.

ColumnTypeMeaning
contractIdlongthe consensus sequence the booking landed at
accountIdlongbooking account
payFixedlong0 = receives fixed, 1 = pays fixed
notionallongwhole currency units
fixedRateTickslongannual decimal fraction Γ— 1e6
conventionIndexlongindex into the table above
effectiveEpochDaylongof the underlying swap
maturityEpochDaylongof the underlying swap
productTypelong0 = SWAP, 1 = SWAPTION
expiryEpochDaylong0 for a swap
exerciseStylelong0 for a swap

Order is booking order, which is ascending contractId. That order is load-bearing twice: the cut iterates it, and the idempotency table remembers a contract by its INDEX in this list.

4. Snapshot; T_CONTRACT (12), format 6​

One record per contract, written after T_IDEMPOTENCY (which stores the index into this list) and carrying the eleven columns above as longs, in booking order.

Restore fails closed on a contractId that is not a sequence at or below the restored applied sequence, and on records out of ascending id order.

Width is read from the FORMAT, not the record. onSnapshotRecord receives a buffer and an offset and no length, so nothing in the record says how wide it is. A format-5 record carries eight columns and restores as a SWAP with an empty wrapper; reading it at eleven would take the following record's bytes as an expiry and a style; a silently wrong contract rather than a failure.

SNAPSHOT_FORMAT = 6; MIN_READABLE_SNAPSHOT_FORMAT = 3, unchanged.

5. The cut; schema 3​

#cut schema=3 seq=<N> sessionDateEpochDay=<D> priceVersion=<V> rows=<R> contracts=<C>
accountId,security,quantity,avgCostTicks,contractMultiplier,lastTradePxTicks
… R position rows …
#contracts
contractId,accountId,payFixed,notional,fixedRateTicks,conventionIndex,effectiveEpochDay,maturityEpochDay,productType,expiryEpochDay,exerciseStyle
… C contract rows …

The #contracts section is present even at contracts=0. Position rows are sorted (accountId, securityId); contract rows are in ascending contractId.

6. The contracts artifact; seq-<N>-contracts.csv, schema 2​

Preamble lines carry consensusSequence, sessionDate, priceSnapshotVersion, cutSha256, contracts, and the conventions that state what the file does and does not contain.

ColumnSource
contractIdSW-<contractId> for a swap, SWPT-<contractId> for a swaption
accountIdcut
payReceivePAY_FIXED / RECEIVE_FIXED from payFixed
notionalcut, whole currency units
fixedRatecut ticks rendered at six decimals
floatIndexconvention table
effectiveDatecut epoch day as ISO date
maturityDatecut epoch day as ISO date
paymentFrequencyconvention table
dayCountconvention table
currencyconvention table; the CONTRACT's currency, not the account's base currency
counterpartyIdcounterparties.csv by account
nettingSetIdcounterparties.csv by account
productTypeSWAP or SWAPTION
expiryDatethe swaption's expiry; empty for a swap
exerciseStyleEUROPEAN / BERMUDAN / AMERICAN; empty for a swap

Every column left of productType describes the UNDERLYING swap, which is why a swaption row and a swap row share them: for a swaption, fixedRate is the strike.

No valuation column exists. No NPV, mark, discount factor, curve, par rate or sensitivity.

7. The netted position extract; schema 3, unchanged​

Every column keeps its name, position and meaning. The reader stops at the first #-prefixed line after the position rows, so the contracts section is never parsed as positions and no swap row can appear in this file.