---
title: "Parity Arb"
description: "Same-exchange YES + NO arbitrage when combined asks cost less than $1.00."
icon: "equals"
---

<Note>
  **Pro Feature.** Requires a Pro or Ultra subscription. [Get started at api.mathematicalcompany.com](https://api.mathematicalcompany.com)
</Note>

# Parity Arbitrage

When the YES ask + NO ask on the same exchange sums to less than \$1.00, buying both sides locks in guaranteed profit. This is the simplest and lowest-risk arbitrage method.

## How It Works

In a binary prediction market, one outcome must resolve to \$1.00. If you can buy YES at \$0.45 and NO at \$0.48, your total cost is \$0.93, guaranteeing \$0.07 profit (minus fees).

```
YES ask = $0.45
NO ask  = $0.48 (derived from 1.0 - YES bid)
Total   = $0.93
Edge    = $1.00 - $0.93 = $0.07
Net     = $0.07 - fees
```

## Engine Methods

### scan_parity_arb

```python
opp = engine.scan_parity_arb(
    market_id="election-winner",
    feed_name="polymarket",
    fee_rate=0.002,    # 20bps per trade
    max_size=50.0,
)
```

Returns a `ParityArbitrageOpportunity` or `None`.

### execute_parity_arb

```python
yes_id, no_id = engine.execute_parity_arb(
    market_id="election-winner",
    exchange="polymarket",
    yes_price=0.45,
    no_price=0.48,
    size=10.0,
)
```

Submits two FOK buy orders (YES + NO). If the second leg fails, the first is auto-canceled.

## Pipeline: parity_arb_scanner

```python
scanner = hz.parity_arb_scanner(
    market_id="election-winner",
    exchange="polymarket",
    feed_name="polymarket",
    min_edge=0.005,
    max_size=50.0,
    fee_rate=0.002,
    auto_execute=True,
    cooldown=5.0,
)

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

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `market_id` | `str` | required | Market to scan |
| `exchange` | `str` | `"paper"` | Exchange name |
| `feed_name` | `str or None` | `None` | Feed to read (defaults to exchange name) |
| `min_edge` | `float` | `0.005` | Minimum net edge |
| `max_size` | `float` | `50.0` | Maximum trade size |
| `fee_rate` | `float` | `0.002` | Fee rate per trade |
| `auto_execute` | `bool` | `False` | Auto-execute opportunities |
| `cooldown` | `float` | `5.0` | Seconds between executions |

Stores `ParityArbitrageOpportunity` in `ctx.params["last_parity_arb"]`.

## One-Shot: parity_arb_sweep

```python
result = hz.parity_arb_sweep(
    engine=engine,
    market_id="election-winner",
    feed_name="polymarket",
    exchange="polymarket",
    min_edge=0.005,
)

if result:
    print(f"Parity arb: cost={result.buy_price + result.sell_price:.4f} edge={result.net_edge:.4f}")
```

Returns `ArbResult` or `None`.

## Rust Type: ParityArbitrageOpportunity

| Field | Type | Description |
|-------|------|-------------|
| `market_id` | `str` | Market identifier |
| `exchange` | `str` | Exchange name |
| `yes_ask` | `float` | YES ask price |
| `no_ask` | `float` | NO ask price |
| `total_cost` | `float` | YES + NO cost |
| `raw_edge` | `float` | 1.0 - total_cost |
| `net_edge` | `float` | Edge after fees |
| `max_size` | `float` | Maximum executable size |
| `is_executable` | `bool` | Whether edge > 0 and size > 0 |
