> ## Documentation Index
> Fetch the complete documentation index at: https://mathematicalcompany.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Horizon Exchanges

> Horizon's exchange model: prediction markets, crypto, stocks, and multi-exchange support.

Horizon supports ten exchange backends that all implement the same `Exchange` trait. You can trade on a single exchange or multiple exchanges simultaneously.

## Verification Status

Different exchanges have received different levels of audit. **Verification status** below reflects how rigorously each backend has been compared against its reference implementation or live API behavior.

| Exchange       | Status          | Notes                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| -------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Paper**      | ✅ Verified      | In-process simulation, exhaustively unit-tested                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| **Polymarket** | ✅ Verified      | Byte-for-byte HMAC parity with `py_clob_client` (regression-tested), live API endpoints confirmed, EOA + Gnosis Safe both supported                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| Hyperliquid    | 🟡 Fixes pushed | msgpack ordering, cloid format, spot offset, error handling, cancelByCloid all fixed in v0.8.7. Needs live verification.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| Kalshi         | 🟡 Fixes pushed | Modern host + RSA-PSS auth + fixed-point dollar field format in v0.8.7. Needs live verification.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| Coinbase       | 🟡 Fixes pushed | ES256 JWT auth + correct list-orders endpoint in v0.8.7. Needs live verification.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| Limitless      | 🟡 Fixes pushed | Polymarket fork — same salt/field name fixes applied in v0.8.7. Needs live verification.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| Alpaca         | 🟡 Fixes pushed | v0.8.8: switched fill polling to `/v2/account/activities/FILL` (the previous `/v2/orders?status=filled` query was invalid and never returned fills). Added `client_order_id` for idempotent retries, fixed limit-price formatter to preserve precision for sub-dollar stocks, added `Day` TIF, signed-qty parsing for short positions, per-order status check on cancel-all. Needs live verification.                                                                                                                                                                                                                                       |
| IBKR           | 🟡 Fixes pushed | v0.8.8: dropped fabricated `paper-api.ibkr.com` host (paper accounts use the same host), fixed positions endpoint to include the required `{pageId}` segment, added multi-step order-confirmation loop, account-id filtering on `cancel_all` and fill polling (was previously cross-account), commission string parsing (`"1.00 USD"`), epoch-ms timestamp via `trade_time_r`, contract multiplier inference for options, `/iserver/auth/ssodh/init` on session timeout, `acctId` in order body. Needs live verification — and remember the bearer token must come from IBKR's `private_key_jwt` SSO flow or a local Client Portal Gateway. |
| Robinhood      | ⚠ Unverified    | Code paths exist, never byte-for-byte audited (Bearer token may need replacement with Ed25519 for newer Crypto API)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |

For live trading with real money, **Polymarket** is the only fully verified backend. The 🟡 exchanges have all critical bugs fixed and should now work in principle, but have not been tested against real accounts. Test in paper or with small size first.

## Prediction Markets

<CardGroup cols={4}>
  <Card title="Paper" icon="file" href="/exchanges/paper">
    Local simulated exchange with tick-based matching. No credentials needed. Default for development.
  </Card>

  <Card title="Polymarket" icon="chart-line" href="/exchanges/polymarket">
    Largest prediction market on Polygon. EIP-712 signed orders via the CLOB API.
  </Card>

  <Card title="Kalshi" icon="scale-balanced" href="/exchanges/kalshi">
    US-regulated (CFTC) prediction market. REST API with bearer token auth.
  </Card>

  <Card title="Limitless" icon="infinity" href="/exchanges/limitless">
    Base chain prediction market. REST client for on-chain trading.
  </Card>
</CardGroup>

## Traditional & Crypto

<CardGroup cols={4}>
  <Card title="Alpaca" icon="chart-mixed" href="/exchanges/alpaca">
    Commission-free stock and ETF trading. Paper and live modes.
  </Card>

  <Card title="Coinbase" icon="bitcoin-sign" href="/exchanges/coinbase">
    Crypto exchange with deep liquidity. HMAC-SHA256 auth via Advanced Trade API.
  </Card>

  <Card title="Robinhood" icon="feather" href="/exchanges/robinhood">
    Commission-free crypto trading via REST API.
  </Card>

  <Card title="Hyperliquid" icon="bolt" href="/exchanges/hyperliquid">
    Decentralized perpetuals + spot on its own L1 chain. Wallet-based EIP-712 auth.
  </Card>

  <Card title="Interactive Brokers" icon="landmark" href="/exchanges/interactive-brokers">
    Multi-asset broker: stocks, options, futures, and ForecastEx prediction markets. Bridges equities/options and prediction market trading.
  </Card>
</CardGroup>

## Exchange Model

All exchanges implement a common trait:

```rust theme={null}
trait Exchange {
    fn submit_order(&self, request: &OrderRequest) -> Result<String>;
    fn cancel_order(&self, order_id: &str) -> Result<()>;
    fn cancel_all(&self) -> Result<usize>;
    fn cancel_for_market(&self, market_id: &str) -> Result<usize>;
    fn drain_fills(&self) -> Vec<Fill>;
    fn fetch_positions(&self) -> Result<Vec<Position>>;
}
```

The Engine wraps exchanges in an `ExchangeBackend` enum for dispatch without trait objects:

```
ExchangeBackend::Paper(PaperExchange)
ExchangeBackend::Polymarket(PolymarketExchange)
ExchangeBackend::Kalshi(KalshiExchange)
ExchangeBackend::Alpaca(AlpacaExchange)
ExchangeBackend::Coinbase(CoinbaseExchange)
ExchangeBackend::Hyperliquid(HyperliquidExchange)
ExchangeBackend::Robinhood(RobinhoodExchange)
ExchangeBackend::IBKR(IBKRExchange)
```

## Single vs Multi-Exchange

### Single exchange (default)

```python theme={null}
# Paper (implicit)
hz.run(name="simple", markets=["test"], pipeline=[...])

# Single live exchange
hz.run(
    name="poly_mm",
    exchange=hz.Polymarket(private_key="0x..."),
    mode="live",
    ...
)
```

### Multi-exchange

```python theme={null}
hz.run(
    name="cross_venue",
    exchanges=[
        hz.Polymarket(private_key="0x..."),
        hz.InteractiveBrokers(paper=True),
        hz.Coinbase(),
    ],
    mode="live",
    ...
)
```

See [Multi-Exchange](/multi-exchange) for details on routing, netting, and cross-venue strategies.

## 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`          |

The strategy loop calls `poll_fills()` each cycle for live exchanges, and `tick()` for paper exchanges.

## Order Routing

When you submit an order via `hz.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

You can also explicitly specify the exchange when using the Engine directly:

```python theme={null}
engine.submit_order(request, exchange="polymarket")
engine.submit_quotes("market_id", quotes, Side.Yes, exchange="kalshi")
```

## 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 an `exchange` field indicating which exchange they belong to:

```python theme={null}
order.exchange      # "polymarket", "kalshi", "alpaca", "coinbase", "hyperliquid", "robinhood", "ibkr", or "paper"
fill.exchange       # "polymarket", "kalshi", "alpaca", "coinbase", "hyperliquid", "robinhood", "ibkr", or "paper"
position.exchange   # "polymarket", "kalshi", "alpaca", "coinbase", "hyperliquid", "robinhood", "ibkr", or "paper"
```
