Unified quotes
@symmio/trading-core folds every source of quote-ish data — on-chain positions and pending quotes, pending instant-opens, pending instant-closes, and solver notifications — into one stable, de-duplicated, lifecycle-tagged shape: the UnifiedQuote. It is the primary abstraction consumers build quote and position UIs against.
The rest of the SDK returns raw records from each source. This module is the reconciliation engine that merges them. reconcileQuotes performs a pure, deterministic merge of one snapshot of every source into a de-duplicated row list; applyNotificationToQuotes advances a row’s lifecycle as solver notifications arrive; resolveQuoteAccounts works out which on-chain accounts (a sub-account plus its Virtual Accounts) hold the picture; and the shouldAccelerate* predicates tell a poll scheduler when to tighten its interval.
Every function here is a pure transform — no config, no clock, no network — except resolveQuoteAccounts, which reads Virtual Account addresses on-chain. The merge is stable across ticks: a temp (off-chain) row keeps its identity as it anchors on-chain, so React lists never flicker. The React layer’s useManagedQuotes composes all of it into a live quote list; framework-agnostic consumers call these functions directly.
Each type and function has its own page with the full signature, fields or parameters, return shape, and examples.
Types
One quote/position row merged from every source into a stable, de-duplicated shape. The primary abstraction.
QuoteOriginWhere a row was sourced from before reconciliation — "onchain" or "offchain".
The merged lifecycle stage of a row across the on-chain and off-chain sources.
OrderTypeContract order types: limit, market, and the close-only market best-effort mode.
QuoteNotificationActionKindWhich quote flow a notification’s action belongs to — "open", "close", or "other".
Reconciliation
Merge one snapshot of every quote source into a de-duplicated, lifecycle-tagged UnifiedQuote[]. Pure and
stateless.
Apply one solver notification to the row list — links temp ↔ on-chain ids, fills prices, advances lifecycle.
resolveQuoteAccountsResolve the full set of on-chain accounts (sub-account + Virtual Accounts + predicted VAs) that hold a sub-account’s quotes.
classifyQuoteNotificationActionClassify a notification’s lastSeenAction into the quote flow it belongs to.
Polling
Whether the on-chain reads specifically should poll faster — true while a row awaits on-chain confirmation.
Whether quote polling should run at the accelerated interval — true while any row is mid-transition.
Grouped positions
Several quotes in the same market and on the same side fold into one row: a QuoteGroup. The aggregate* functions roll a group’s children into one figure each. aggregateGroupMetrics is price-independent and runs inside groupQuotes; the other two take the inputs they need explicitly, because a mark price and a subgraph read are not the reconciler’s to fetch.
Grouping is a MARKET_DIRECTION-only feature — the one isolation where a market + side cohort is a real on-chain unit. groupQuotes throws for any other isolation type; check first with supportsQuoteGrouping, or pass an explicit { keyOf } to fold on a dimension of your own.
Fold reconciled quotes into one row per market + side, or under a custom key function.
supportsQuoteGroupingWhether an isolation type has grouped positions at all — the guard to run before folding.
partitionQuotesSplit rows into active positions and resting orders — the grouped-view-vs-orders-tab split.
aggregateGroupMetricsPrice-independent aggregations over a group’s children: size, weighted open price, notional, locked legs, leverage.
aggregateGroupFundingFold the group’s settled-to-date funding from subgraph rows. netReceived = received − paid, so positive means the
group earned funding.
Fold the group’s unrealized PnL at a mark price. Positive means in profit — the same polarity as funding’s
netReceived.
One grouped position: its identity, children, and aggregated metrics.
QuoteGroupMetricsThe price-independent aggregations carried on every group.
QuoteGroupFundingThe folded funding totals, with isComplete guarding a partial subgraph read.
The folded unrealized PnL, with isComplete guarding a missing price or unsettled fill.
Closing a group
Narrow a group’s children to the quotes that can actually be closed, with each one’s dust floor attached.
planGroupCloseAllocate a target close size across those candidates, or explain exactly why it cannot be met.
Adapters
Fold a pending instant-open record into an optimistic UnifiedQuote without merging.
Fold a pending instant-close record into a WRITE_ONCHAIN_CLOSE UnifiedQuote without merging.
Fold an on-chain quote/position struct into a UnifiedQuote without merging.
Related
- Notifications stream — the source
applyNotificationToQuotesandclassifyQuoteNotificationActionfold in. getSubAccountQuotes— the convenience read that runsresolveQuoteAccounts+ the source reads +reconcileQuotesin one call.- Solvers —
PendingInstantOpen/PendingInstantClosefromgetInstantOpens/getInstantClosesfeed the reconciler. - React
useManagedQuotes— the hook composed on top of everything here. - Margin & risk —
calculateMarginRiskturns a group’s uPnL plus its account balance into equity and distance to liquidation.