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

# Real-Time Arbitrage

> Stream live cross-venue arbitrage returns with the SDK and React hooks

# 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. The
[List Venue Events API](/api-reference/discovery/listvenueevents) returns the initial `arbReturn`
value; the WebSocket API keeps it live.

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/listvenueevents) for REST
  request and response details.
</Info>

## SDK (vanilla JS/TS)

```typescript theme={null}
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, 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.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 theme={null}
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 theme={null}
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. For request schemas and parameters, use the
[List Venue Events API reference](/api-reference/discovery/listvenueevents); for live message
shapes, use the [WebSocket Protocol](/api/websocket#4-arbitrage-streams).

## Related

<CardGroup 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/listvenueevents">
    REST schema for loading initial `arbReturn` values, filters, pagination, and event rows.
  </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>
</CardGroup>
