Resource Contracts

A runtime resource is identified by a canonical key and a contract. The key selects the stream; the contract tells a client how to decode, merge, replay, and query it. Fetch both from the running resource catalog before integrating with Forge or Terminal.

Canonical keys

Resource

Key shape

In-process payload

Bar

bar://{venue}/{symbol}@{interval}

Tick<schema::BarRow>

Book

book://{venue}/{symbol}@{depth}

Tick<schema::BookRow>

Market trade

order://{venue}/{symbol}/trade

Tick<schema::OrderRow>

Factor

factor://{factor}/{symbol}.{venue}@{source}:{param}

Tick<double>

Application scalar

scalar://{producer}/{resource}

Tick<double>

At the C++ authoring boundary, a literal such as bar://okx/BTCUSDT@1m selects its type at compile time. The runtime normalizes concrete keys for discovery, so a catalog may return bar://okx/btcusdt@1m. External clients use the returned key verbatim.

Bar keys default to @1m and book keys default to @full when a C++ literal omits the parameter. Write the parameter explicitly in strategy code and always use the fully normalized catalog key outside the process.

Contract fields

Each catalog entry contains identifying fields such as model, key, venue, symbol, and param, plus a contract:

Field

Meaning

model

Product value represented by the resource, such as market_bar or factor_sample.

payloadSchema

Physical in-process payload family.

deliveryModel

Latest values, snapshot plus deltas, append events, or a query snapshot.

historyModel

Durable backing, runtime-only state, live-only data, or no history.

replayPolicy

Initial state available to a new subscriber.

mergeModel

How multiple frames form the current client view.

dropPolicy

Whether values can coalesce, require resynchronization, or must be lossless.

visibility

Public market, private account, derived, or internal data.

Forge uses lower camel case in protobuf JSON. Runtime query data can expose the same values with snake-case names. Treat the values, not the casing of the container field, as the contract.

Bars

schema::BarRow contains:

Field

Meaning

open, high, low, close

Exact decimal prices.

volume

Total traded quantity in the interval.

buy_volume

Buyer-initiated traded quantity.

open_timestamp

Interval start in nanoseconds.

close_timestamp

Interval close in nanoseconds, or zero while the venue reports an unconfirmed interval.

The released bar contract is:

model          market_bar
payload        bar_row
delivery       latest_value_stream
history        clickhouse_market_bars
replay         latest_wire
merge          time_upsert
drop           latest_wins
visibility     public_market

In the browser WebSocket, bars use type: "market/bar". Timestamps are in milliseconds and decimal values are strings.

Books

schema::BookRow is one price-level change:

Field

Meaning

px

Exact decimal level price.

qty

New quantity; zero removes the level.

side

Bid or ask side.

markers

Encoded source action and flags.

The released book contract is:

model          market_book
payload        book_row
delivery       snapshot_delta_stream
history        clickhouse_market_orderbook_rows
replay         projected_snapshot
merge          book_projection
drop           display_resync_allowed
visibility     public_market

WebSocket consumers receive market/book.snapshot followed by sequenced market/book.update frames. A snapshot contains complete bid and ask level arrays. An update contains changed levels. Apply frames in sequence order; on a gap, stop applying updates and request RESYNC.

Persisted order-book rows are historical source evidence. They do not permit a client to substitute the latest single row for a projected snapshot.

Market trades

schema::OrderRow represents public trade tape in this resource family:

Field

Meaning

px and qty

Exact decimal trade price and quantity.

order_id

Venue trade or order identifier when supplied, otherwise zero.

side

Aggressor side when known.

markers

Encoded domain, action, and flags.

The released market-trade contract is:

model          market_trade
payload        order_row
delivery       append_event_stream
history        live_only
replay         latest_event
merge          append_dedupe
drop           latest_wins
visibility     public_market

The WebSocket type is market/trade. Public market trades are not the strategy’s private fills; use account and history APIs for execution state.

Factors and scalars

Generated factors publish a double value on a semantic key such as:

factor://spread_mean/btcusdt.okx@bar:1m

The factor contract is:

model          factor_sample
payload        scalar_value
delivery       latest_value_stream
history        clickhouse_factors
replay         latest_wire
merge          scalar_time_upsert
drop           latest_wins
visibility     derived

Both factor and application scalar streams use type: "market/scalar" in the WebSocket. The frame contains key, millisecond ts, and numeric value.

Account and portfolio state

Orders, fills, balances, positions, portfolios, performance, attribution, and risk are runtime read models or history models rather than public market topic rows. Discover their availability through runtime capabilities, then use the documented query or history endpoint.

Private order events require lossless handling. A current account or portfolio view is a replaceable query snapshot; it is not a bar series and must not be merged as one.

Venue matrix

The current released venue factories declare these resources:

Package

Factory

Catalog key example

History

OKX

Bar("BTC-USDT", "1m")

bar://okx/btcusdt@1m

Bars

OKX

Books("BTC-USDT")

book://okx/btcusdt@full

Book rows

OKX

Books5("BTC-USDT")

book://okx/btcusdt@5

Book rows

OKX

BboTbt("BTC-USDT")

book://okx/btcusdt@bbo-tbt

Book rows

OKX

Trades("BTC-USDT")

order://okx/btcusdt/trade

Live only

Binance

Bar("BTCUSDT", "1m")

bar://binance/btcusdt@1m

Bars

Binance

Orderbook("BTCUSDT")

book://binance/btcusdt@full

Book rows

Binance

Depth5 / Depth10 / Depth20

book://binance/btcusdt@{5|10|20}

Book rows

Binance

BookTicker("BTCUSDT")

book://binance/btcusdt@ticker

Book rows

Binance

AggTrades / Trades

order://binance/btcusdt/trade

Live only

History and runs

History is scoped by instance_id and run_id. A live catalog entry does not prove that historical rows exist. Check historyModel, select an exact run, and use the corresponding Forge history endpoint.

The states declared, active, and persisted answer different questions. A resource can be declared without publishing a value, active but live-only, or persisted for an earlier run while the current process is stopped.

See Resources, Live Data, and History for the model, Runtime WebSocket for frame handling, and REST API for history endpoints.