- Exchange Order Gateway:
ws://127.0.0.1:9001 - Exchange Internal Event Stream (infrastructure):
ws://127.0.0.1:9002 - Market Data Broadcast Feed:
ws://127.0.0.1:9010
- Encoding: JSON
- Timestamps: Unix epoch milliseconds (
timestamp) - Prices: numeric (
floatsemantics) - Quantity: integer shares/contracts in current implementation (
qty)
{
"type": "order",
"trader_id": "maker_1",
"side": "buy",
"order_type": "limit",
"price": 100.05,
"qty": 2,
"client_order_id": "maker_1-001"
}Field definitions:
type: must be"order"trader_id: logical trader identity stringside:"buy"or"sell"order_type:"limit"or"market"price: required for limit, must be null/omitted for marketqty: positive integer quantityclient_order_id: optional client correlation id
If a developer uses this shape:
{
"type": "place_order",
"trader_id": "...",
"side": "BUY",
"price": 100.05,
"quantity": 2
}Map it to canonical:
type: "place_order"->"order"side: "BUY"/"SELL"->"buy"/"sell"quantity->qty- add
order_type("limit"ifpriceprovided, else"market")
{
"type": "order_accepted",
"order_id": 42,
"trader_id": "maker_1",
"client_order_id": "maker_1-001",
"timestamp": 1739980000000
}{
"type": "order_rejected",
"reason": "initial_margin_insufficient",
"details": {
"equity": 9500.0,
"required_margin": 10000.0
},
"trader_id": "maker_1",
"client_order_id": "maker_1-001",
"timestamp": 1739980000001
}Common reason values:
invalid_jsoninvalid_messageinitial_margin_insufficientinvalid_price_referenceno_liquidity
{
"type": "book_update",
"best_bid": 100.0,
"best_ask": 100.1,
"bids": [[100.0, 5], [99.95, 3]],
"asks": [[100.1, 4], [100.15, 2]],
"timestamp": 1739980000100
}Field definitions:
best_bid/best_ask: top-of-book prices ornullbids/asks: depth arrays[price, total_qty_at_level]timestamp: event generation time
{
"type": "trade",
"trade_id": 101,
"price": 100.1,
"qty": 2,
"buy_trader_id": "taker_1",
"sell_trader_id": "maker_1",
"timestamp": 1739980000101
}Field definitions:
trade_id: exchange-generated monotonic idprice: execution priceqty: filled quantitybuy_trader_id/sell_trader_id: trade counterpartiestimestamp: execution event time
{
"type": "liquidation",
"trader_id": "taker_1",
"reason": "maintenance_margin_breach",
"qty": 3,
"side": "sell",
"timestamp": 1739980000200
}{
"type": "position_update",
"trader_id": "maker_1",
"position": 3,
"cash": 9700.0,
"avg_entry_price": 99.8,
"realized_pnl": 12.5,
"unrealized_pnl": 4.2,
"total_equity": 9716.7,
"mark_price": 100.05,
"timestamp": 1739980000300
}Field definitions:
trader_id: trader account identifierposition: signed net positioncash: post-trade cash balanceavg_entry_price: weighted average entry for open inventoryrealized_pnl: closed PnL from executed tradesunrealized_pnl: mark-to-mid PnL at event timetotal_equity:cash + unrealized_pnlmark_price: reference mark used for unrealized/equitytimestamp: event generation time
The exchange also persists a local audit trail through exporter.py.
trades.csvfields:timestamp,price,qty,buy_trader,sell_trader
performance.csvfields:timestamp,trader_id,position,cash,realized_pnl,total_equity
Notes:
- append-only writes
- headers auto-created when files are absent
- buffered flush every 500ms