---
title: "Latency Arb"
description: "Front-run slow prediction market book updates using fast external feeds."
icon: "bolt"
---

<Warning>
  **Ultra Feature.** Requires an Ultra subscription. [Get started at api.mathematicalcompany.com](https://api.mathematicalcompany.com)
</Warning>

# Latency Arbitrage

Use a fast external feed (e.g., Binance WebSocket) to detect price moves before the prediction market book reprices. When the book is stale and a significant move has occurred, trade ahead of the expected repricing.

## How It Works

1. Monitor a fast **reference feed** (e.g., BTC price on Binance)
2. Monitor the prediction market **book feed** (e.g., "Will BTC hit \$100k?")
3. When the reference feed shows a move but the book hasn't updated (stale):
  - Expected price = mid + (ref_change * sensitivity)
  - If expected > ask + fees: **BUY** (market will reprice up)
  - If expected < bid - fees: **SELL** (market will reprice down)

## Rust Type: LatencyArbOpportunity

| Field | Type | Description |
|-------|------|-------------|
| `direction` | `str` | `"buy"` or `"sell"` |
| `expected_price` | `float` | Expected repriced level |
| `market_price` | `float` | Current market price (ask for buy, bid for sell) |
| `edge` | `float` | Edge after fees |
| `staleness_ms` | `float` | Book staleness in milliseconds |
| `ref_price_change` | `float` | Reference price change |

## Engine Method: scan_latency_arb

```python
opp = engine.scan_latency_arb(
    market_id="btc-100k",
    ref_feed="binance",
    market_feed="polymarket",
    sensitivity=1.0,
    min_age_ms=500.0,
    min_edge=0.02,
    fee_rate=0.002,
)
```

## Pipeline: latency_arb

```python
scanner = hz.latency_arb(
    market_id="btc-100k",
    ref_feed="binance",
    market_feed="polymarket",
    sensitivity=1.0,
    min_staleness_ms=500.0,
    min_edge=0.02,
    max_size=20.0,
    fee_rate=0.002,
    auto_execute=True,
    cooldown=2.0,
    max_daily_trades=50,
)

hz.run(pipeline=[scanner], ...)
```

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `market_id` | `str` | required | Market to trade |
| `ref_feed` | `str` | required | Fast reference feed |
| `market_feed` | `str` | required | Prediction market feed |
| `sensitivity` | `float` | `1.0` | Ref move multiplier |
| `min_staleness_ms` | `float` | `500.0` | Min book staleness (ms) |
| `min_edge` | `float` | `0.02` | Min edge after fees |
| `max_size` | `float` | `20.0` | Max trade size |
| `fee_rate` | `float` | `0.002` | Fee rate |
| `auto_execute` | `bool` | `False` | Auto-execute |
| `cooldown` | `float` | `2.0` | Seconds between trades |
| `max_daily_trades` | `int` | `50` | Hard cap on daily trades |

Stores `LatencyArbOpportunity` in `ctx.params["last_latency_arb"]`.

## Safety Controls

- **max_daily_trades**: Hard cap that resets at midnight. Prevents runaway execution.
- **min_staleness_ms**: Only trades when the book is genuinely stale, not just slow.
- **cooldown**: Minimum time between executions.
- **Ultra tier gate**: Only available to Ultra subscribers.

## Example

```python
import horizon as hz

scanner = hz.latency_arb(
    market_id="btc-100k",
    ref_feed="binance",
    market_feed="polymarket",
    sensitivity=0.8,
    min_staleness_ms=750.0,
    min_edge=0.03,
    max_size=15.0,
    auto_execute=True,
    cooldown=3.0,
    max_daily_trades=30,
)

hz.run(
    name="latency_arb_bot",
    exchanges=[hz.Polymarket(private_key="0x...")],
    markets=["btc-100k"],
    feeds={
        "binance": hz.BinanceWS("BTCUSDT"),
        "polymarket": hz.PolymarketBook("btc-100k"),
    },
    pipeline=[scanner],
    interval=0.1,  # Fast polling for latency arb
)
```

<Warning>
  Latency arb is high-risk. Markets may reprice before your order fills, resulting in adverse selection. Always use conservative sizing and the `max_daily_trades` safety cap.
</Warning>
