Skip to main content

Data Model: CDM Instruments

Instrument record (served by reference-data)​

Flat record; the CDM Asset β†’ Instrument β†’ Security choice tree is taxonomy documentation, not a runtime discriminated union.

FieldTypeNotes
instrumentKeystringThe transactional key everywhere; engine symbol, DB Security columns, subjects. Equities/funds: the ticker. Treasuries: UST-<yyyymmdd> maturity-keyed. No surrogate ids.
displayNamestringHuman name on the CDM view. The same attribute travels as companyName on /stocks and both control snapshots (TD-CDM01).
shortDisplayNamestring?Treasuries only (UST 2Y … UST 30Y).
assetClassStock | ETF | US_TREASURYCoarse display/filter classification.
currencystringUSD throughout this state.
securityTypeSecurityTypeEnumEquity, Fund or Debt here.
equityTypeEquityType?Present iff securityType = Equity. Wrapping type: { equityType: EquityTypeEnum, depositaryReceipt?: DepositaryReceiptTypeEnum }.
fundTypeFundProductTypeEnum?Present iff securityType = Fund. Enum directly; the CDM asymmetry is preserved.
debtEconomicsDebtEconomics?Present iff securityType = Debt.
maturedbooleanTreasuries: maturityDate ≀ now (UTC midnight, inclusive; honors TRADERX_FIXED_UTC_INSTANT). Always false for equities/funds.
observedAtISO instantWhen the record was assembled.
identifiersAssetIdentifier[]Min 1. See identifier rules below.

CDM enums (literals quoted from finos/common-domain-model rosetta source): AssetIdTypeEnum: BBGID, BBGTICKER, CUSIP, FIGI, ISDACRP, ISIN, Name, REDID, RIC, Other, Sicovam, SEDOL, UPI, Valoren, Wertpapier, CurrencyCode, ExchangeCode, ClearingCode. SecurityTypeEnum: Debt, Equity, Fund, Warrant, Certificate. EquityTypeEnum: Ordinary, NonConvertiblePreference, DepositaryReceipt, ConvertiblePreference. DepositaryReceiptTypeEnum: ADR, GDR, IDR, EDR. FundProductTypeEnum: MoneyMarketFund, ExchangeTradedFund, MutualFund, OtherFund. There is no TICKER member; Bloomberg ticker symbology is BBGTICKER.

Identifier rules (asserted at seed load; violation throws):

  • Equity/Fund: BBGTICKER equal to instrumentKey, plus FIGI where baked; a row with no resolvable FIGI keeps BBGTICKER only and logs a warning.
  • Debt: FIGI plus Other equal to instrumentKey; a Debt record claiming BBGTICKER throws.
  • Exactly one sub-type discriminator, agreeing with securityType.

Seed classification map (OpenFIGI securityType β†’ CDM): Common Stock β†’ Equity/Ordinary; REIT β†’ Equity/Ordinary (logged); ETP β†’ Fund/ExchangeTradedFund; ADR β†’ Equity/DepositaryReceipt/ADR; Preference β†’ Equity/NonConvertiblePreference; unknown β†’ default Equity/Ordinary with a warning, never silently dropped. Classification keys off securityType, not securityType2 (which reports "Mutual Fund" for SPY).

DebtEconomics​

FieldTypeNotes
debtTypeUS_TREASURY_NOTE | US_TREASURY_BOND
issuerstringUnited States Department of the Treasury
fixedInterestobject{ rateType: 'Fixed', couponRatePercent, couponFrequency: 'Semiannual' }
principalRepaymentobject{ style: 'Bullet', parAmount: 100 }
issueDate, maturityDateISO date
originalTermYears2 | 5 | 10 | 20 | 30
priceProvenanceobject{ sourceType: 'US_TREASURY_AUCTION_RESULT', sourceUrl, officialCleanPrice, runtimeSeedCleanPrice, simulated: true }; clean prices in provenance are quoted percent-of-par, as the auction PDFs state them; everything the runtime stores is fraction of par.

Seed universe additions​

Five ETFs (Fund / ExchangeTradedFund):

instrumentKeydisplayNameFIGI
SPYSPDR S&P 500 ETF TrustBBG000BDTBL9
QQQInvesco QQQ TrustBBG000BSWKH7
IWMiShares Russell 2000 ETFBBG000CGC9C4
VTIVanguard Total Stock Market ETFBBG000HR9779
GLDSPDR Gold SharesBBG000CRF6Q8

Five Treasuries (Debt; quoted clean % of par from the TreasuryDirect auction results, and the fraction the runtime stores):

instrumentKeyshortcoupon %maturitytermquoted clean %stored fractionFIGI
UST-20280630UST 2Y4.1252028-06-30299.8780.998780BBG022ZR1Z79
UST-20310630UST 5Y4.1252031-06-30599.6650.996650BBG022ZR1Z51
UST-20360515UST 10Y4.3752036-05-151099.2570.992570BBG0221YLR31
UST-20460515UST 20Y5.0002046-05-152098.4810.984810BBG0226BZH97
UST-20560515UST 30Y5.0002056-05-153099.2930.992930BBG0221YLR40

Issue dates: 2026-06-30, 2026-06-30, 2026-05-15, 2026-06-01, 2026-05-15 respectively. Official (unrounded) auction prices are carried in priceProvenance.officialCleanPrice (99.878432 / 99.664909 / 99.256552 / 98.481099 / 99.292811).

Price representation; the fraction-of-par convention​

SurfaceRepresentationExample (UST-20280630)
TreasuryDirect auction PDF / provenancepercent of par99.878
price-publisher walk state + payload cleanPrice/pricefraction of par, 6 dp0.998780
binary tick (pricing-tick-bin.*) and engine ticksround(fraction Γ— 1e6)998,780
SQL Trades.Price, Positions.AverageCostBasisfraction of par, DECIMAL(18,6)0.998780
extract costBasis/closingMarkfraction of par, 6 dp0.998780
UI displayfraction Γ— 100, % sign, no $99.878%

Contract multiplier for a Treasury is 1; notional is face Γ— fraction-ticks Γ— 1 through the unchanged risk gate. Valuation identities: costValue = face Γ— avgFraction, marketValue = face Γ— currentFraction, pnl = marketValue βˆ’ costValue. Face-weighted average on a buy: (oldAvg Γ— oldFace + price Γ— buyFace) Γ· newFace; a sell preserves the average; a flat position resets it to zero.

Treasury pricing model (price-publisher)​

Term profiles (per-step ceiling and total band, in percent-of-par space; the walk runs in percent space and converts to fraction at emission):

termmaxStepmaxDistance
20.0050.15
50.0100.30
100.0200.50
200.0350.75
300.0501.00

Step: change = maxStep Γ— (0.8 Γ— sharedRoll + 0.2 Γ— localRoll) + 0.02 Γ— (seed βˆ’ current), then clamp to seed Β± maxDistance, round to 3 dp in percent space (= 5 dp in fraction space, inside the 6-dp budget). One shared roll per publish batch correlates the curve; the local roll breaks lockstep. Approximate YTM (percent space, per 100 par): ((coupon + (100 βˆ’ clean)/years) / ((100 + clean)/2)) Γ— 100, years = (maturity βˆ’ quote) / 365.25d, null at or after maturity.

SQL schema delta (MariaDB database-init-configmap.yaml, this state's layer)​

  • Trades: state check gains 'Rejected'; + RejectionReason VARCHAR(255), + SourceOrderId VARCHAR(50); Price widens DECIMAL(18,3) β†’ DECIMAL(18,6).
  • Positions: AverageCostBasis widens DECIMAL(18,3) β†’ DECIMAL(18,6).
  • Seeds: account 17017 ("U.S. Treasury Trading Account"), users user02/user08/user10, five settled trades SEED-17017-<maturity> and five positions at face 100,000; prices stored as fractions (0.998780 …), never percentages.
  • No new tables. No OrderBook Pending* columns (dropped machinery). Security columns already hold OCC-width strings (YU15 FR-RXT16), which covers UST-<yyyymmdd> at 12 chars.

Extract fixture (schema 3)​

Header comment gains the bond and accrual conventions; column list becomes:

accountId,security,instrumentType,quantity,contractMultiplier,costBasis,closingMark,markSource,
markQuality,marketValue,unrealizedPnl,currency,counterpartyId,nettingSetId,coupon,maturityDate,
lastCouponDate,accruedInterestFraction
  • instrumentType: EQUITY | OPTION | TREASURY; options by OCC shape as before; TREASURY by join against the instrument static (never by prefix-parsing inside the cut).
  • coupon, maturityDate (schema 2): populated for Treasury rows from the joined static; empty for equities and options.
  • lastCouponDate, accruedInterestFraction (schema 3, ADR-061): Treasury rows only, derived from the joined static plus sessionDate rather than joined; the static is unchanged by this bump. Schedule is generated backwards from maturityDate in 6-month steps measured from the maturity anchor (so no issue date is needed, and no short/long first coupon is modelled); day count is ACT/ACT (ICMA); accrual runs to sessionDate, not to a settlement date.
  • Bond costBasis/closingMark/marketValue are fractions of par at 6 dp; quantity is face. accruedInterestFraction is in that same unit, so closingMark + accruedInterestFraction is the dirty price. marketValue/unrealizedPnl remain clean.
  • accruedInterestFraction is the only value in the fixture that rounds (HALF_EVEN at 6 dp); elapsed/period does not terminate, so the exact-or-abort rule cannot cover it. Deterministic, so byte-identical-across-members is unaffected.
  • The .cut sidecar is unchanged at #cut schema=1; the cut is engine state and the engine did not change; only the rendered CSV (a join product) bumps.

Instrument static (reference-data/instruments.csv, rendered into order-matcher resources)​

Base columns unchanged from YU15; gains securityType, figi, couponRatePercent, maturityDate so the extract join can classify and decorate without a service call. Rows added for the five ETFs and five Treasuries.

Read, not written​

  • The engine's snapshot records: format 4, untouched; no instrument-type field exists or is added (instrumentType stays derived/joined downstream).
  • The control-feed delta payload: {ticker, companyName}; Treasuries flow through it unchanged in shape.
  • counterparties.csv: inherited from YU15 verbatim.