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

# Global Orderbook Module Websocket

> Real-time orderbook streaming via WebSocket

# Global Orderbook Module Websocket

Real-time orderbook streaming using Socket.IO. Get live updates from multiple exchanges with aggregated global orderbook view.

## Connection

```javascript theme={null}
import { io } from 'socket.io-client';

const socket = io('wss://api.renesis.fi', {
  transports: ['websocket'],
  path: '/order-execution/socket.io'
});
```

## Authentication

**No authentication required** - Orderbook data is publicly available market data.

## Connection Keepalive

Socket.IO handles keepalive automatically via ping/pong:

| Setting         | Value | Description                              |
| --------------- | ----- | ---------------------------------------- |
| `ping_interval` | 25s   | Server sends ping every 25 seconds       |
| `ping_timeout`  | 20s   | Connection dropped if no pong within 20s |

**No client-side action required** - the Socket.IO client library handles ping/pong responses automatically. As long as the connection is open and the network is stable, the connection stays alive.

If you need to detect connection health in your app:

```javascript theme={null}
socket.on('disconnect', (reason) => {
  console.log('Disconnected:', reason);
  // reason: 'ping timeout', 'transport close', 'io server disconnect', etc.
});

socket.io.on('reconnect', (attempt) => {
  console.log('Reconnected after', attempt, 'attempts');
  // Re-subscribe to orderbooks after reconnect
});
```

## Events

### Client → Server Events

| Event                   | Payload                                   | Description                   |
| ----------------------- | ----------------------------------------- | ----------------------------- |
| `subscribe_orderbook`   | `{symbol, venues, include_global, depth}` | Subscribe to orderbook stream |
| `unsubscribe_orderbook` | `{symbol}`                                | Unsubscribe from stream       |
| `get_snapshot`          | `{symbol, venues}`                        | Request current snapshot      |

### Server → Client Events

| Event                | Payload                                   | Description                     |
| -------------------- | ----------------------------------------- | ------------------------------- |
| `connected`          | `{sid, message}`                          | Connection acknowledged         |
| `subscribed`         | `{symbol, venues, include_global, depth}` | Subscription confirmed          |
| `orderbook_snapshot` | `{symbol, venues, timestamp}`             | Initial full snapshot           |
| `orderbook_update`   | Per-venue book update                     | Real-time updates (\~10-20/sec) |
| `global_book`        | Aggregated best prices                    | Combined view across venues     |
| `error`              | `{message}`                               | Error notification              |
| `unsubscribed`       | `{symbol}`                                | Unsubscribe confirmed           |

***

## Subscribing to Orderbooks

### Subscribe to Single Exchange

```javascript theme={null}
socket.emit('subscribe_orderbook', {
  symbol: 'BTC/USDT',
  venues: ['binance'],        // Single exchange
  include_global: false,      // No aggregation needed
  depth: 10                   // 10 price levels
});
```

### Subscribe to Multiple Exchanges + Global Book

```javascript theme={null}
socket.emit('subscribe_orderbook', {
  symbol: 'BTC/USDT',
  venues: ['binance', 'bybit', 'gateio', 'kraken'],
  include_global: true,       // Get aggregated best bid/ask
  depth: 10
});
```

### Subscribe to All Exchanges

```javascript theme={null}
socket.emit('subscribe_orderbook', {
  symbol: 'ETH/USDT',
  venues: [],                 // Empty = all available venues
  include_global: true,
  depth: 5
});
```

### Subscription Parameters

| Parameter        | Type      | Default    | Description                             |
| ---------------- | --------- | ---------- | --------------------------------------- |
| `symbol`         | string    | *required* | Trading pair (e.g., "BTC/USDT")         |
| `venues`         | string\[] | `[]` (all) | Filter to specific exchanges            |
| `include_global` | boolean   | `true`     | Include aggregated global book          |
| `depth`          | number    | `5`        | Price levels per side (1, 5, 10, or 20) |

### Supported Venues

| Venue     | Update Rate | Notes             |
| --------- | ----------- | ----------------- |
| `binance` | \~9/sec     | Highest liquidity |
| `bybit`   | \~28/sec    | Fastest updates   |
| `gateio`  | \~8/sec     | Good depth        |
| `kraken`  | \~15/sec    | Reliable          |

***

## Message Formats

### Per-Venue Update (`orderbook_update`)

Sent for each exchange when the orderbook changes:

```json theme={null}
{
  "venue": "binance",
  "symbol": "BTC/USDT",
  "bids": [
    [88150.50, 1.5],      // [price, quantity]
    [88150.00, 2.3],
    [88149.50, 0.8]
  ],
  "asks": [
    [88151.00, 0.8],
    [88151.50, 1.2],
    [88152.00, 0.5]
  ],
  "spread_bps": 0.57,      // Spread in basis points
  "mid_price": 88150.75,
  "staleness_ms": 15.2,    // How old the data is
  "confidence": 0.98,      // 0-1 reliability score
  "quality": "GOOD",       // GOOD, DEGRADED, STALE, UNAVAILABLE
  "timestamp": "2025-12-19T15:30:00.000000"
}
```

### Global Book (`global_book`)

Aggregated view showing best prices across all subscribed venues:

```json theme={null}
{
  "symbol": "BTC/USDT",
  "data": {
    "symbol": "BTC/USDT",
    "timestamp": "2025-12-19T14:56:00.000000",
    "best_bid": {
      "price": 87953.60,
      "quantity": 0.23,
      "venue": "gateio"
    },
    "best_ask": {
      "price": 87949.90,
      "quantity": 0.12,
      "venue": "bybit"
    },
    "venues": {
      "binance": {
        "bid": 87951.30,
        "ask": 87951.31,
        "confidence": 0.95
      },
      "bybit": {
        "bid": 87949.80,
        "ask": 87949.90,
        "confidence": 1.0
      },
      "gateio": {
        "bid": 87953.60,
        "ask": 87953.70,
        "confidence": 0.92
      },
      "kraken": {
        "bid": 87951.30,
        "ask": 87951.40,
        "confidence": 0.98
      }
    }
  },
  "timestamp": "2025-12-19T14:56:00.000000"
}
```

### Initial Snapshot (`orderbook_snapshot`)

Sent immediately after subscribing:

```json theme={null}
{
  "symbol": "BTC/USDT",
  "venues": {
    "binance": {
      "venue": "binance",
      "symbol": "BTC/USDT",
      "bids": [[88150.50, 1.5], ...],
      "asks": [[88151.00, 0.8], ...],
      "spread_bps": 0.57,
      "mid_price": 88150.75,
      "staleness_ms": 10.5,
      "confidence": 0.98,
      "quality": "GOOD",
      "timestamp": "2025-12-19T15:30:00.000000"
    },
    "bybit": { ... }
  },
  "timestamp": "2025-12-19T15:30:00.000000"
}
```

***

## Quality Metrics

### Quality Levels

| Quality       | Staleness  | Description                      |
| ------------- | ---------- | -------------------------------- |
| `GOOD`        | \< 500ms   | Fresh data, reliable for trading |
| `DEGRADED`    | 500ms - 2s | Slightly stale, use with caution |
| `STALE`       | 2s - 5s    | Old data, risky for trading      |
| `UNAVAILABLE` | > 5s       | Do not use                       |

### Confidence Score (0.0 - 1.0)

Confidence is calculated based on:

* **Staleness**: Up to -0.4 penalty for old data
* **Spread**: Up to -0.2 penalty for wide spreads
* **Sequence gaps**: -0.05 per gap (max -0.3)
* If `UNAVAILABLE`: confidence = 0

**Recommendation**: Only trade when confidence > 0.7

***

## Complete Example (React)

```jsx theme={null}
import { useEffect, useState, useRef } from 'react';
import { io } from 'socket.io-client';

function OrderbookWidget({ symbol }) {
  const [orderbook, setOrderbook] = useState(null);
  const [globalBook, setGlobalBook] = useState(null);
  const [connected, setConnected] = useState(false);
  const socketRef = useRef(null);

  useEffect(() => {
    // Connect to WebSocket
    const socket = io('wss://api.renesis.fi', {
      transports: ['websocket'],
      path: '/order-execution/socket.io'
    });
    socketRef.current = socket;

    socket.on('connect', () => {
      console.log('Connected to orderbook stream');
      setConnected(true);
    });

    socket.on('connected', (data) => {
      console.log('Server acknowledged:', data.message);
    });

    socket.on('subscribed', (data) => {
      console.log(`Subscribed to ${data.symbol}`);
    });

    socket.on('orderbook_update', (data) => {
      // Update orderbook state for specific venue
      setOrderbook(prev => ({
        ...prev,
        [data.venue]: data
      }));
    });

    socket.on('global_book', (data) => {
      // Update global aggregated view
      setGlobalBook(data.data);
    });

    socket.on('orderbook_snapshot', (data) => {
      // Initialize with full snapshot
      setOrderbook(data.venues);
    });

    socket.on('error', (data) => {
      console.error('Orderbook error:', data.message);
    });

    socket.on('disconnect', () => {
      setConnected(false);
    });

    return () => {
      socket.disconnect();
    };
  }, []);

  // Subscribe when symbol changes
  useEffect(() => {
    if (connected && socketRef.current) {
      // Unsubscribe from previous symbol
      socketRef.current.emit('unsubscribe_orderbook', { symbol });

      // Subscribe to new symbol
      socketRef.current.emit('subscribe_orderbook', {
        symbol,
        venues: ['binance', 'bybit', 'gateio'],
        include_global: true,
        depth: 10
      });
    }
  }, [symbol, connected]);

  if (!connected) {
    return <div>Connecting...</div>;
  }

  return (
    <div>
      {/* Global Best Prices */}
      {globalBook && (
        <div className="global-book">
          <h3>Best Prices</h3>
          <div>
            Best Bid: ${globalBook.best_bid?.price}
            @ {globalBook.best_bid?.venue}
          </div>
          <div>
            Best Ask: ${globalBook.best_ask?.price}
            @ {globalBook.best_ask?.venue}
          </div>
        </div>
      )}

      {/* Per-Venue Orderbooks */}
      {orderbook && Object.entries(orderbook).map(([venue, data]) => (
        <div key={venue} className="venue-book">
          <h4>{venue} ({data.quality})</h4>
          <div className="bids">
            {data.bids?.slice(0, 5).map(([price, qty], i) => (
              <div key={i}>{price} - {qty}</div>
            ))}
          </div>
          <div className="asks">
            {data.asks?.slice(0, 5).map(([price, qty], i) => (
              <div key={i}>{price} - {qty}</div>
            ))}
          </div>
        </div>
      ))}
    </div>
  );
}

export default OrderbookWidget;
```

***

## Unsubscribing

```javascript theme={null}
// Unsubscribe from specific symbol
socket.emit('unsubscribe_orderbook', { symbol: 'BTC/USDT' });

// Disconnect completely
socket.disconnect();
```

***

## Error Handling

```javascript theme={null}
socket.on('error', (data) => {
  console.error('Orderbook error:', data.message);
  // Common errors:
  // - "symbol is required"
  // - "Invalid venue"
  // - "Subscription failed"
});

socket.on('disconnect', (reason) => {
  console.log('Disconnected:', reason);
  // Implement reconnection logic if needed
});
```

***

## Performance Tips

1. **Limit depth** - Use `depth: 5` unless you need more levels
2. **Filter venues** - Only subscribe to venues you'll display
3. **Throttle UI updates** - Don't re-render on every update (10-20/sec)
4. **Use `include_global: false`** if you only need raw venue data
5. **Unsubscribe** when components unmount

***

## REST Fallback

If WebSocket is unavailable, use REST endpoints:

```bash theme={null}
# Get current orderbook
curl -H "X-API-Key: $API_KEY" \
  "https://api.renesis.fi/order-execution/orderbook/book?symbol=BTC/USDT"

# Get quality metrics
curl -H "X-API-Key: $API_KEY" \
  "https://api.renesis.fi/order-execution/orderbook/quality?symbol=BTC/USDT"
```

See [Orderbook REST API](/oems-api/api/orderbook) for full REST documentation.
