---
title: "Horizon + Coinbase"
description: "Trade crypto on Coinbase Advanced Trade for spot and cross-asset strategies."
icon: "/images/exchanges/coinbase.svg"
---

[Coinbase Advanced Trade](https://www.coinbase.com/advanced-trade) is a crypto exchange with deep liquidity across hundreds of trading pairs. Horizon connects to Coinbase for spot crypto trading and cross-asset strategies alongside prediction markets.

## Quick Setup

```python
hz.run(
    name="crypto_mm",
    exchange=hz.Coinbase(api_key="...", api_secret="..."),
    mode="live",
    ...
)
```

## Credentials

<Tabs>
  <Tab title="Explicit">
    ```python
    hz.Coinbase(api_key="organizations/...", api_secret="-----BEGIN EC...")
    ```
  </Tab>
  <Tab title="Environment variables">
    ```bash
    export COINBASE_API_KEY="organizations/..."
    export COINBASE_API_SECRET="-----BEGIN EC PRIVATE KEY-----\n..."
    ```

    ```python
    hz.Coinbase()  # reads from env
    ```
  </Tab>
</Tabs>

## Coinbase Configuration

```python
@dataclass
class Coinbase:
    api_key: str | None = None
    api_secret: str | None = None
    api_url: str = "https://api.coinbase.com/api/v3/brokerage"
```

| Field | Default | Description |
|-------|---------|-------------|
| `api_key` | `None` | Coinbase API key (env: `COINBASE_API_KEY`) |
| `api_secret` | `None` | Coinbase API secret (env: `COINBASE_API_SECRET`) |
| `api_url` | `https://api.coinbase.com/api/v3/brokerage` | Override API base URL |

## Authentication

Coinbase uses HMAC-SHA256 signature auth. Three headers are sent on every request:

- `CB-ACCESS-KEY: {api_key}`
- `CB-ACCESS-SIGN: HMAC-SHA256(timestamp + method + path + body)`
- `CB-ACCESS-TIMESTAMP: {unix_timestamp}`

## Market Data Feed

Real-time crypto ticker via WebSocket:

```python
hz.run(
    feeds={
        "btc": hz.CoinbaseFeed(product_ids=["BTC-USD"]),
        "eth": hz.CoinbaseFeed(product_ids=["ETH-USD", "SOL-USD"]),
    },
    ...
)
```

The feed connects to `wss://advanced-trade-ws.coinbase.com` and subscribes to the `ticker` channel with authenticated messages.

Each product gets its own snapshot entry keyed by `{feed_name}:{PRODUCT_ID}` (e.g., `btc:BTC-USD`), plus a feed-level entry with the latest update.

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `product_ids` | `list[str]` | required | Trading pairs to subscribe (e.g., `["BTC-USD", "ETH-USD"]`) |
| `api_key` | `str` | `None` | Override API key (defaults to env vars) |
| `api_secret` | `str` | `None` | Override API secret (defaults to env vars) |

## Symbol Mapping

Coinbase uses product IDs in `BASE-QUOTE` format:

```python
market = hz.Market(id="BTC-USD", name="Bitcoin / USD")
```

| Horizon Field | Coinbase Field | Notes |
|---------------|---------------|-------|
| `OrderRequest.market_id` | `product_id` | e.g., "BTC-USD", "ETH-USD" |
| `OrderRequest.order_side` | `side` | `"BUY"` or `"SELL"` |
| `OrderRequest.price` | `limit_price` | Limit order price |
| `OrderRequest.size` | `base_size` | Base currency amount |

## Multi-Exchange

Use Coinbase alongside prediction markets for crypto-correlated hedging:

```python
hz.run(
    name="crypto_hedge",
    exchange=[
        hz.Polymarket(),    # prediction market
        hz.Coinbase(),      # crypto hedge
    ],
    feeds={
        "btc_pred": hz.PolymarketBook("will-btc-hit-150k"),
        "btc_spot": hz.CoinbaseFeed(product_ids=["BTC-USD"]),
    },
    pipeline=[my_strategy],
)
```

## Getting API Keys

1. Sign in at [coinbase.com/advanced-trade](https://www.coinbase.com/advanced-trade)
2. Go to **Settings** > **API**
3. Create a new API key with **Trade** permissions
4. Save both the API key and secret securely
