Skip to main content

Data Model: EOD Risk Extract

Sequenced marker (SBE RiskExtractMessage, template 8, block length 24)​

The only new wire message. It carries the extract's stamp and no state.

FieldTypeNotes
requestIduint64Correlates the egress ack; the producer increments it per marker.
sessionDateEpochDayint64The EOD session the extract names, from the trigger event.
priceVersionuint32The closing-price snapshot version the extract marks against.
reserveduint32Zero.

Egress ack (24 bytes, the inherited layout): consensus sequence at offset 0, cut row count at 8, kind KIND_RISK_EXTRACT_MARKED (101) at 12, requestId at 13.

Position cut (risk.extract.cut, US-ASCII text, schema 1)​

Rendered on every member by RiskExtractCut, published by the leader. Header line, then a column header, then one row per position sorted by (accountId, securityId).

#cut schema=1 seq=<N> sessionDateEpochDay=<d> priceVersion=<v> rows=<n>
accountId,security,quantity,avgCostTicks,contractMultiplier,lastTradePxTicks
ColumnTypeNotes
accountIdintThe real account id, as it appears in counterparties.csv.
securityasciiTicker or unpadded OCC symbol, from the cluster's symbol table.
quantitylongSigned net position. Flat positions are emitted, not dropped.
avgCostTickslongWeighted average trade price, Px.SCALE = 1e6 ticks.
contractMultiplierlongYU14 replicated state; 100 for OCC options, 1 otherwise.
lastTradePxTickslongEngine last trade at seq; 0 when the security has never traded.

A position whose security has no registered ticker aborts the render; a risk extract that silently omits a position is worse than no extract.

Extract fixture (the delivered object, schema 1)​

#-prefixed metadata preamble, then a CSV header, then one row per (accountId, security). Every preamble value is derived from the stamp, so the file is a pure function of the cut plus immutable reference data.

Preamble keys: schema, consensusSequence, sessionDate, priceSnapshotVersion, cutSha256, rows, plus the fixed convention lines (cutConsistency, netting, quantityConvention, costBasisConvention, marketValueConvention, unrealizedPnlConvention, markSourceLegend, optionIdentity).

ColumnTypeNotes
accountIdintUn-netted grain, together with security.
securityasciiOCC symbol for options; strike, expiry and call/put derive from it.
instrumentTypeenumEQUITY or OPTION, from OccSymbol.isOption.
quantitylongSigned net position in contracts or shares.
contractMultiplierlongFrom the cut, i.e. from cluster state.
costBasisdecimal(6)Per contract or share; excludes fees and the multiplier.
closingMarkdecimal(6)The mark actually used for this row.
markSourceenumEOD_SNAPSHOT or CLUSTER_LAST_TRADE_AT_N (ADR-056).
markQualityenumYU06's OK/STALE/SPIKE/OVERRIDDEN, or LAST_TRADE.
marketValuedecimal(6)quantity Γ— closingMark Γ— contractMultiplier.
unrealizedPnldecimal(6)(closingMark βˆ’ costBasis) Γ— quantity Γ— contractMultiplier.
currencyasciiUSD throughout; a field, not a conversion.
counterpartyIdasciiFrom counterparties.csv by accountId.
nettingSetIdasciiFrom counterparties.csv; an attribute, never applied here.

All decimal columns are BigDecimal at scale 6 over integer ticks; exact, and free of the overflow quantity Γ— priceTicks Γ— multiplier would hit in a long.

Delivery record (risk.extract.ready)​

{ "schema": 1, "uri": "...", "consensusSequence": 1544685, "sessionDate": "2026-07-22",
"priceSnapshotVersion": 1, "rows": 14, "sha256": "...", "cutSha256": "...",
"quiesceWitnessSequence": 1544686 }

quiesceWitnessSequence is the sequence the second marker landed at; it must equal consensusSequence + 1. It belongs here rather than in the fixture precisely so the fixture stays a function of the cut alone and can be rebuilt from it.

Object layout​

<sink>/<sessionDate>/v<priceVersion>/seq-<consensusSequence>.csv the fixture
<sink>/<sessionDate>/v<priceVersion>/seq-<consensusSequence>.cut the cut it was built from

Write-once: CREATE_NEW on a filesystem sink, x-goog-if-generation-match: 0 on GCS.

Reference data (inherited from YU14, unchanged)​

counterparties.csv; accountId,counterpartyId,nettingSetId,currency for the seven real accounts. instruments.csv; the instrument universe. Rendered into the runtime image so the producer reads them from the classpath directory rather than a mounted volume.

Instrument-identifier column widths (changed)​

YU14 made listed options tradeable, but every instrument-identifier column in the SQL schema was sized for an equity ticker. An unpadded OCC symbol is 19 characters, so MariaDB's strict mode rejected the insert and every option fill the ADR-048 trade bridge published was dropped by trade-processor; the blotter, the positions read model, and the YU06 price chain silently excluded every option. All of them are VARCHAR(32) here:

TableColumnWasNow
positionssecurityVARCHAR(15)VARCHAR(32)
tradessecurityVARCHAR(15)VARCHAR(32)
orderbooksecurityVARCHAR(16)VARCHAR(32)
eod_price_snapshotsecurityVARCHAR(16)VARCHAR(32)
eod_position_pnlsecurityVARCHAR(16)VARCHAR(32)
stockstickerVARCHAR(16)VARCHAR(32)
stocks_control_outboxtickerVARCHAR(16)VARCHAR(32)

The JPA entities already declared @Column(length = 50) on Trade.security and Position.security, so the schema was the only constraint and no Java changed.

900-migrations.sql carries seven matching ALTER TABLE ... MODIFY COLUMN statements. That block is what the database Deployment's schema-migrate initContainer applies to an already-populated PVC on every start, and CREATE TABLE IF NOT EXISTS is a no-op against a table that already exists; so widening the CREATE statements alone would fix only freshly created databases. This is the first migration in the lineage that modifies rather than only adds; re-running a MODIFY against an already-widened column is a no-op.

Option quote inputs (market data)​

An option's quote is derived, not stored: everything but the model inputs comes from the OCC symbol and the underlying's current tick.

InputSourceDefault
underlying spot / open / closethe underlying's live tick;
strike, expiry, call/putderived from the OCC symbol (ADR-052);
implied volatilityPRICE_OPTION_IV0.25 (flat across all contracts)
risk-free ratePRICE_OPTION_RATE0.04
premium floorPRICE_OPTION_MIN_PREMIUM0.01

The vol and rate are reported on price-publisher's /health so a consumer can reproduce our marks exactly. Quotes are floored at intrinsic value, so a quote can never imply a free arbitrage.

Read, not written​

eod_price_snapshot and eod_price_session (YU06) are read for the stamped (session_date, version) where status = 'PUBLISHED'. Rows with quality MISSING or a null price are ignored, so those securities fall through to the cut's last trade. No table is written by this state.