Skip to main content
DB
Back homeUse case

Market data & trading analytics

Your trade feed, the latest state per instrument and the live analytics over both, in one place, with no cache to keep in sync with the store.

The problem

Where the usual stack breaks

  1. 01

    Your trading stack splits one workflow across four systems: a tick store for history, a cache for the current book, a stream processor for signals and a warehouse for backtests. Every hop serializes the data again, and every copy is a chance for the cache to disagree with the store.

  2. 02

    The disagreement surfaces exactly when it hurts: a strategy reads state that a fill just changed. In trading, a stale read against a fresh write is not a rounding error. It is a wrong decision.

  3. 03

    What you want is one place where every trade is durable, the current state per instrument is kept from it continuously, and every consumer follows both live without polling.

Architecture

How NYXDB does it

Trades land in one durable table. The engine publishes every committed write once, to the transformations that keep per-instrument state and to every STREAM SELECT that follows the feed.

  1. 01

    Ingest

    Every trade is on disk before you get the acknowledgement: the node’s write-ahead log persists it first.

  2. 02

    Route (PSI)

    Readers never slow the writer: each committed batch is published once, and every subscriber keeps its own durable cursor over the relation and key it selected.

  3. 03

    Current state

    The latest state per instrument is always ready to read: a transformation folds the trade feed into an UPSERT table keyed by instrument, with COUNT, SUM, MIN, MAX and AVG lanes.

  4. 04

    Read

    Follow one instrument or a grouped total live with STREAM SELECT; dashboards and backtests run ordinary SELECTs over the same tables.

Examples

In practice

The transfer feed, as an append-only table
CREATE TABLE transfers (
chain_id UINT16 NOT NULL,
token STRING NOT NULL,
sender STRING NOT NULL,
recipient STRING NOT NULL,
amount UINT256 NOT NULL,
transferred_at DATETIME64(3, 'UTC') NOT NULL,
_index UINT128 NOT NULL,
INDEX transfers_ts (transferred_at) USING MINMAX SCOPE HISTORY GRANULE 8192
)
MODE APPEND
SHARD BY (token) SHARDS AUTO
PARTITION BY MONTH(transferred_at)
ORDER BY (chain_id, token, _index)
STORAGE PROFILE COLUMNAR;
Live volume per token, as a query that stays open
STREAM SELECT chain_id, token, SUM(amount) AS volume, COUNT(*) AS transfers
FROM transfers
GROUP BY chain_id, token;

The examples use the same two tables on every page. See the SQL reference for full syntax.

Capabilities

What you get out of the box

Keyed current state

The latest row per instrument is always ready, maintained from the trade feed by transformations.

Maintained aggregates

Counts, sums, minimums, maximums and averages stay current, with arithmetic over them for VWAP-style prices.

Streaming reads

One snapshot, then every change as commits land, with STREAM SELECT.

Per-table layout

Choose ROW, COLUMNAR or HYBRID storage per table, to match how you read it.

One engine

Tick store, keyed state and stream fan-out run in one node process.

Durable before ack

A write is acknowledged only after the write-ahead log persisted it.

Learn more

Run your trade feed and your state on one engine

Start a node and follow your first market feed live.