Cross-rates matrix (CRM)
Table of Contents
This is the hub note for the FX cross-rates matrix. Each linked note is a single focused concept; start here and follow the links.
Summary
The cross-rates matrix (CRM) is the FX market-data structure that holds the
spot rate for every currency pair the system must value, price or report on.
Conceptually a square table indexed by currency on both axes, in practice it is
a graph (a spanning tree): a small set of directly-quoted driver rates is
set, and every other rate is derived from them by triangulation. It exists
to solve a consistency problem: EUR/GBP, EUR/USD and GBP/USD are bound
by a no-arbitrage (triangular) relationship, so storing every rate independently
would let one edit silently make the others inconsistent and open arbitrage. The
CRM enforces the relationship structurally — only a chosen acyclic subset may
be set directly; the rest are computed — so the matrix is always internally
consistent. It lives in ores.marketdata, which owns the rates, the derivation,
and the correlations/vol surfaces built on the same pattern.
Detail
Concept map
- What a spot rate is → FX spot date and settlement (it is really a forward to the spot date; T+2; max-of-two rule).
- Structure → CRM graph topology and spanning tree.
- Inputs → Driver and derived rates (the never-set-both-sides invariant).
- Computation → Triangulation and cross rates and the spot rate derivation mechanics (parity, forward points).
- Quoting → FX currency conventions (majors/minors, base/quote, reciprocals).
- Risk → CRM risk: recentering and artefacts.
- Operations → Spot rate governance (local/global, verification, approval).
- Volatility → Volatility surface driving and Correlation management reuse the driver/derived pattern for vol rather than spot.
Where it fits the market data architecture
The CRM is the consistency engine inside the ores.marketdata authority (see
Market Data Architecture). It refines the "subscribe → persist → remap" role:
- Producers (e.g. synthetic, vendors) feed driver rates only — the independent, most-liquid legs — onto their own channels.
ores.marketdataingests the drivers and, via the CRM, computes the derived rates by triangulation and enforces no-arbitrage, then publishes the official set (remapped drivers + computed crosses) on the tenant-scoped official stream.- Correlations and derived vol surfaces are owned and computed here too.
So producers stay simple (drivers); marketdata owns derivation, consistency and correlation. This validates the boundary in the architecture doc — "remap" generalises to "ingest drivers → derive the rest → publish".
A pair is identified by its ORE key (FX/RATE/<base>/<quote>); the
driver/derived/proxy relationship is the typed-variant case described in
Polymorphic types over NATS.
See also
- Market Data Architecture — where the CRM sits in the producer/authority model.
- Market data identifiers — ORE keys for the pairs the CRM holds.
- Polymorphic types over NATS — driver/derived/proxy as typed variants.
- Synthetic market data generation: approach — a producer of driver rates.