---
title: Real-Time Arbitrage
description: "Stream live cross-venue arbitrage returns with the SDK and React hooks"
---

> **For AI agents:** the complete documentation index is at [llms.txt](/llms.txt). Append `.md` to any page URL for its markdown version.

# Real-Time Arbitrage

AGG real-time arbitrage streams help prediction market apps find cross-venue price dislocations as
they happen. Use `arbReturn` to rank matched markets, power trading dashboards, alert users, or feed
agent workflows with live arbitrage signals.

`arbReturn` is the estimated cross-venue arbitrage return for a matched market — a decimal fraction
(e.g. `0.012` = 1.2%) derived from the best prices across the venues in a matched cluster. It is
available from three places:

- **[List Venue Events](/api-reference/discovery/list-venue-events)** — an `arbReturn` embedded in
  every listing row. Synced by a background job, so it can lag the live books; use it for initial
  render and sorting, not as a live signal.
- **[Get Midpoints](/api-reference/orderbook/get-live-midpoints-for-multiple-markets) with `bestPrice=true`** — computed fresh
  by the pricing engine on every request. The REST source of truth when you need a current value
  on demand (agents, alerts, one-off checks) without holding a socket open.
- **WebSocket arb streams** — pushes updates as they happen. The right choice for anything that
  stays on screen.

Two consumption modes:

- **Per-market** — for a detail view of one or a few markets.
- **Feed** — a single coalesced subscription for a whole listing, so you don't manage a
  subscription per visible row.

## What you get

- `arbReturn` on venue event and market listings for initial page loads and sorting.
- Per-market WebSocket updates for focused detail views.
- A coalesced `arb-feed` stream for large lists and dashboards.
- SDK helpers (`subscribeArb`, `subscribeArbFeed`) and React hooks (`useMarketArb`, `useArbFeed`).
- Event-level rollups through `useArbFeed`, where `byEvent` keeps the max live `arbReturn` across
  markets in the same event.

<Info>
  The stream is **delta-only and last-value-wins** — there is no snapshot or sequence number. Load
  the initial `arbReturn` from the REST listing, then layer the stream on top. A market that hasn't
  moved since page load simply won't appear in the stream yet, so always fall back to the listing
  value. Updates are loss-tolerant. See the [WebSocket Protocol](/api/websocket#4-arbitrage-streams)
  for the wire format and the [API Reference](/api-reference/discovery/list-venue-events) for REST
  request and response details.
</Info>

## SDK (vanilla JS/TS)

```typescript
import { createAggClient } from "@agg-build/sdk";

const client = createAggClient({
  baseUrl: "https://api.agg.market",
  appId: "your-app-id",
  wsUrl: "wss://ws.agg.market/ws",
});

const ws = client.createWebSocket();

// Per-market: subscribe returns an unsubscribe function.
const offMarket = ws.subscribeArb("vm_1", (update) => {
  // update: { type, marketId, activeVenuesOnly: true, venueEventId, arbReturn, ts }
  renderArb(update.marketId, update.arbReturn);
});

// Last value received for a market (or null), e.g. to seed a re-render.
const current = ws.getArb("vm_1");

// Feed: one subscription for the whole listing.
const offFeed = ws.subscribeArbFeed((batch) => {
  // batch.activeVenuesOnly === true; entries contain no per-entry venue metadata.
  // batch.entries: [{ marketId, venueEventId, arbReturn, ts }, ...]
  for (const e of batch.entries) {
    updateRow(e.marketId, e.arbReturn);
  }
});

// Clean up when done.
offMarket();
offFeed();
```

The SDK handles ref-counting (multiple subscribers to the same market share one server
subscription) and re-subscribes automatically on reconnect.

## React (hooks)

### One market

```tsx
import { useMarketArb } from "@agg-build/hooks";

function ArbBadge({ marketId, initialArbReturn }: { marketId: string; initialArbReturn: number }) {
  const { arbReturn, isLive } = useMarketArb(marketId);

  // Fall back to the listing value until the first live update arrives.
  const value = arbReturn ?? initialArbReturn;

  return (
    <span>
      {(value * 100).toFixed(2)}%{isLive ? " ●" : ""}
    </span>
  );
}
```

### A listing (feed)

`useArbFeed` maintains a live `byMarket` map and a derived `byEvent` map (the **max** `arbReturn`
across the markets of each `venueEventId`), so you can render either market-level or event-level
arbitrage live.

```tsx
import { useArbFeed } from "@agg-build/hooks";

function EventList({ events }: { events: VenueEvent[] }) {
  const { byEvent } = useArbFeed();

  return (
    <ul>
      {events.map((event) => {
        // Live value if the feed has sent one for this event, else the listing value.
        const arb = byEvent.get(event.id) ?? event.arbReturn ?? 0;
        return (
          <li key={event.id}>
            {event.title} — {(arb * 100).toFixed(2)}%
          </li>
        );
      })}
    </ul>
  );
}
```

<Tip>
  **Initial value:** the feed only carries markets whose value has *changed*, so a freshly loaded
  row may not be in `byMarket`/`byEvent` yet. Always resolve with `feedValue ?? restValue` — read
  `arbReturn` from your listing response as the fallback.
</Tip>

<Tip>
  **Sort stability:** if you sort a listing by `arbReturn`, re-sorting on every flush makes rows
  jump. Prefer updating values in place and re-sorting only on an explicit user action or the next
  listing refetch.
</Tip>

## FAQ

### What is prediction market arbitrage?

Prediction market arbitrage is a cross-venue price dislocation where matched markets imply a
positive return if the relevant outcomes can be bought or hedged at the displayed prices. AGG
calculates this signal on matched market clusters so apps can spot opportunities across venues
without building their own matching and price-comparison layer.

### What does `arbReturn` mean?

`arbReturn` is the estimated arbitrage return expressed as a decimal fraction. For example,
`0.012` means an estimated 1.2% cross-venue return for that matched market based on the best prices
AGG sees in the cluster. Use it as a ranking, alerting, or trading signal, and render it as a
percentage in user-facing views.

### Is `arbReturn` guaranteed execution?

No. `arbReturn` is a real-time market signal, not a guaranteed fill or guaranteed profit. Execution
can still depend on venue availability, liquidity, routeability, fees, stale prices, slippage, and
order timing. Before placing trades, check the relevant market and outcome routeability fields and
use AGG's routing and execution APIs for executable quotes.

### Should I use REST or WebSocket data?

Use the venue-event listing to load the initial page, filters, and fallback `arbReturn` values, then
use WebSocket data to keep visible markets live. The WebSocket stream is delta-only, so it does not
replace the listing response.

If you need a *fresh* value over REST — for example an agent or alerting job that polls rather than
holding a socket — call [`GET /midpoints?bestPrice=true`](/api-reference/orderbook/get-live-midpoints-for-multiple-markets)
with the market ids you care about. Its `arbReturn` is computed by the pricing engine at request
time, unlike the listing value, which a background sync can leave stale.

For request schemas and parameters, use the
[List Venue Events API reference](/api-reference/discovery/list-venue-events); for live message
shapes, use the [WebSocket Protocol](/api/websocket#4-arbitrage-streams).

## Related

<Columns cols={2}>
  <Card title="WebSocket Protocol" icon="brackets-curly" href="/api/websocket#4-arbitrage-streams">
    The arbitrage stream wire format — channels, subscribe frames, and message shapes.
  </Card>
  <Card title="List Venue Events API" icon="book-open" href="/api-reference/discovery/list-venue-events">
    REST schema for loading initial `arbReturn` values, filters, pagination, and event rows.
  </Card>
  <Card title="Get Midpoints API" icon="arrows-left-right" href="/api-reference/orderbook/get-live-midpoints-for-multiple-markets">
    Fresh, engine-computed `arbReturn` over REST — pass `bestPrice=true`.
  </Card>
  <Card title="Comparing Venue Prices" icon="scale-balanced" href="/recipes/comparing-venue-prices">
    Cross-venue price comparison the arbitrage return is derived from.
  </Card>
  <Card title="Real-Time Orderbook" icon="code" href="/recipes/websocket-orderbook">
    Live aggregated orderbook subscriptions over the same socket.
  </Card>
  <Card title="Setup Guide" icon="gear" href="/api/setup">
    Client setup, provider wiring, and the full hooks reference.
  </Card>
</Columns>
