Exchange trait. You can trade on a single exchange or multiple exchanges simultaneously.
Prediction Markets
Paper
Local simulated exchange with tick-based matching. No credentials needed. Default for development.
Polymarket
Largest prediction market on Polygon. EIP-712 signed orders via the CLOB API.
Kalshi
US-regulated (CFTC) prediction market. REST API with bearer token auth.
Limitless
Base chain prediction market. REST client for on-chain trading.
Traditional & Crypto
Alpaca
Commission-free stock and ETF trading. Paper and live modes.
Coinbase
Crypto exchange with deep liquidity. HMAC-SHA256 auth via Advanced Trade API.
Robinhood
Commission-free crypto trading via REST API.
Hyperliquid
Decentralized perpetuals + spot on its own L1 chain. Wallet-based EIP-712 auth.
Interactive Brokers
Multi-asset broker: stocks, options, futures, and ForecastEx prediction markets. Bridges equities/options and prediction market trading.
Exchange Model
All exchanges implement a common trait:ExchangeBackend enum for dispatch without trait objects:
Single vs Multi-Exchange
Single exchange (default)
Multi-exchange
Fill Model
All exchanges use a pull model for fills:| Exchange | Fill Source | Method |
|---|---|---|
| Paper | tick(market_id, mid_price) | Matches orders against mid price |
| Polymarket | drain_fills() → poll_fills_async() | Polls /trades endpoint |
| Kalshi | drain_fills() → poll_fills_async() | Polls /portfolio/fills endpoint |
| Alpaca | drain_fills() → poll_fills_async() | Polls /v2/orders?status=filled |
| Coinbase | drain_fills() → poll_fills_async() | Polls /orders/historical/fills |
| Robinhood | drain_fills() → poll_fills_async() | Polls /crypto/trading/orders/?status=filled |
| IBKR | drain_fills() → poll_fills_async() | Polls /iserver/account/trades |
| Hyperliquid | drain_fills() → poll_fills_async() | Polls /info with userFillsByTime |
poll_fills() each cycle for live exchanges, and tick() for paper exchanges.
Order Routing
When you submit an order viahz.run(), it’s automatically routed to the correct exchange based on the market.exchange field:
- Markets resolved as
"polymarket"→ routed to the Polymarket backend - Markets resolved as
"kalshi"→ routed to the Kalshi backend - Markets with
"alpaca"→ routed to the Alpaca backend - Markets with
"ibkr"→ routed to the IBKR backend - Markets with
"coinbase"→ routed to the Coinbase backend - Markets with
"robinhood"→ routed to the Robinhood backend - Markets with
"hyperliquid"→ routed to the Hyperliquid backend - Markets with
"paper"or empty exchange → routed to the primary exchange
Side Mapping
| Exchange | Side Used | Notes |
|---|---|---|
| Polymarket | Side.Yes / Side.No | Binary prediction contracts |
| Kalshi | Side.Yes / Side.No | Binary prediction contracts |
| Limitless | Side.Yes / Side.No | Binary prediction contracts |
| Alpaca | Side.Long | Equities — no Yes/No concept |
| Coinbase | Side.Long | Crypto — no Yes/No concept |
| Hyperliquid | Side.Long | Perps/spot — no Yes/No concept |
| Robinhood | Side.Long | Crypto — no Yes/No concept |
| IBKR | Side.Long | Multi-asset — no Yes/No concept |
| Paper | Any | Copies the side from the order request |
Exchange Fields on Types
Orders, Fills, and Positions all carry anexchange field indicating which exchange they belong to: