Interfaces & Data Contracts
Interfaces & Data Contracts
Terminology (Canon)
Cornice uses a consistent naming model across docs, code, and schemas:
- Exchange: the platform/company (Polymarket, Kalshi).
- Venue: Cornice-internal alias for Exchange (used in logs and fields).
- Market: the event definition + resolution rules (cross-venue concept).
- Contract: the tradable instrument for a specific Outcome (venue-specific).
Internal Messaging (RabbitMQ)
Use RabbitMQ for internal events and decouple data from execution.
Exchanges and Routing
market.data(topic): normalized market and orderbook updatesmarket.signal(topic): derived signals for strategyexecution.intent(topic): selected trade intentsexecution.result(topic): fills, rejects, and errors
Example Routing Keys
kalshi.orderbook.updatepolymarket.orderbook.updatesignal.arb.detectedintent.place_orderresult.order_filled
Normalized Data Shapes (Draft)
Keep fields minimal and consistent. All prices in cents.
MarketUpdate
market_id: string
venue: "kalshi" | "polymarket"
symbol: string
title: string
end_time: iso8601 | null
timestamp: iso8601
best_yes: int
best_no: int
MarketMetadata
market_id: string
venue: "kalshi" | "polymarket"
symbol: string
title: string
category: string | null
end_time: iso8601 | null
outcomes: [ "YES", "NO" ]
venue_tokens: { yes: string, no: string } | null
active: bool
OrderBookDepth
market_id: string
venue: "kalshi" | "polymarket"
timestamp: iso8601
yes_bids: [ [price, size] ]
yes_asks: [ [price, size] ]
no_bids: [ [price, size] ]
no_asks: [ [price, size] ]
Signal
signal_id: string
type: "arb"
legs: [ { venue, side, price, size } ]
edge_cents: int
timestamp: iso8601
ExecutionIntent
intent_id: string
signal_id: string
orders: [ { venue, side, price, size } ]
dry_run: bool
ExecutionResult
intent_id: string
status: "filled" | "partial" | "rejected" | "error"
fills: [ { venue, side, price, size, order_id } ]
error: string | null
Socket.io Events (UI)
market:update: latest normalized market snapshotsignal:update: newly detected opportunitiesexecution:update: intent status and fillshealth:update: heartbeat + latency
HTTP API (FastAPI)
GET /healthbasic status and versionGET /confignon-secret config snapshotPOST /admin/pausetoggle trading pause
Raw -> Normalized Field Mapping (Phase 1)
Polymarket (Gamma + CLOB)
event.id->markets.venue_market_idevent.slug->markets.slugevent.title->markets.titleevent.tags[].label->markets.category(pick primary tag)markets[0].clobTokenIds->markets.venue_tokensmarkets[0].outcomes->markets.outcomes(normalize to ["YES","NO"])- CLOB
bookbest ask ->MarketUpdate.best_yes/best_no event.active/closed->markets.active(active && !closed)
Kalshi (Public Trade API)
market.idormarket.ticker->markets.venue_market_idmarket.subtitle/market.title->markets.titlemarket.event_ticker->markets.symbolmarket.close_time->markets.end_timemarket.yes_ask/no_ask->MarketUpdate.best_yes/best_nomarket.status->markets.active