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

# Get Realtime Arbitrage Stream

> Stream SSE de oportunidades de arbitragem detectadas em tempo real via WebSocket

## 📖 Descrição

Endpoint de **Server-Sent Events (SSE)** que transmite oportunidades de arbitragem detectadas pelo motor WebSocket em tempo real. Cada evento representa uma oportunidade identificada após o debounce de 200ms por símbolo.

<Callout title="Server-Sent Events" icon="zap" color="green">
  SSE é uma conexão HTTP persistente unidirecional. O browser se reconecta automaticamente em caso de queda. Use a API nativa `EventSource` para consumir este endpoint — não é necessário WebSocket do lado do cliente.
</Callout>

***

## 🛠️ Requisição

### Método

`GET`

### URL

```plaintext theme={null}
/v1/realtime/arbitrage
```

### Headers Necessários

| Header          | Valor               | Descrição                       |
| --------------- | ------------------- | ------------------------------- |
| `Accept`        | `text/event-stream` | Indica que o cliente aceita SSE |
| `Cache-Control` | `no-cache`          | Desabilita cache intermediário  |

### Parâmetros

Nenhum.

### Exemplo de Requisição (curl)

```bash theme={null}
curl --location --no-buffer \
  -H "Accept: text/event-stream" \
  -H "Cache-Control: no-cache" \
  'localhost:8080/v1/realtime/arbitrage'
```

### Exemplo de Requisição (JavaScript)

```javascript theme={null}
const source = new EventSource('/v1/realtime/arbitrage');

source.onmessage = (event) => {
    const opportunity = JSON.parse(event.data);
    console.log('Nova oportunidade:', opportunity);
};

source.onerror = (err) => {
    console.error('Erro SSE, reconectando...', err);
    // EventSource reconecta automaticamente
};

// Ao desmontar o componente React:
// source.close();
```

***

## 📤 Resposta

### Headers da Resposta

| Header              | Valor               |
| ------------------- | ------------------- |
| `Content-Type`      | `text/event-stream` |
| `Cache-Control`     | `no-cache`          |
| `Connection`        | `keep-alive`        |
| `X-Accel-Buffering` | `no`                |

<Callout title="X-Accel-Buffering" icon="lightbulb" color="yellow">
  O header `X-Accel-Buffering: no` é necessário para que Nginx (ou proxies similares) não bufferizem a resposta, garantindo entrega imediata dos eventos.
</Callout>

### Formato dos Eventos SSE

Cada evento segue o protocolo SSE padrão:

```
data: {"ticker":"BTC-USDT","buyExchange":"Binance","sellExchange":"OKX",...}

data: {"ticker":"ETH-USDT","buyExchange":"Bybit","sellExchange":"Binance",...}
```

### Estrutura do Payload JSON

```json theme={null}
{
  "ticker": "BTC-USDT",
  "buyExchange": "Binance",
  "sellExchange": "OKX",
  "buyPrice": 43250.50,
  "sellPrice": 43380.00,
  "profitPercentAskBid": 0.30,
  "volume": 1523.45,
  "timestamp": "2025-03-18T12:00:00.000Z"
}
```

### Campos do Payload

| Campo                 | Tipo              | Descrição                                       |
| --------------------- | ----------------- | ----------------------------------------------- |
| `ticker`              | string            | Par de trading (ex: `BTC-USDT`)                 |
| `buyExchange`         | string            | Exchange onde comprar (preço mais baixo)        |
| `sellExchange`        | string            | Exchange onde vender (preço mais alto)          |
| `buyPrice`            | float             | Preço de compra (ask) na exchange de compra     |
| `sellPrice`           | float             | Preço de venda (bid) na exchange de venda       |
| `profitPercentAskBid` | float             | Spread de lucro em percentual                   |
| `volume`              | float             | Volume de 24h (do cache, atualizado a cada 60s) |
| `timestamp`           | string (ISO 8601) | Momento da detecção                             |

***

## 🔄 Ciclo de Vida da Conexão

```
Cliente → GET /v1/realtime/arbitrage
Server  → 200 OK (headers SSE)
          Connection mantida aberta
          ↓
Server  → data: {...oportunidade...}\n\n   (quando detectada)
Server  → data: {...oportunidade...}\n\n   (quando detectada)
          ...
Cliente → Fecha conexão (ou perde rede)
Server  → Remove cliente do broadcaster
```

<Callout title="Múltiplos Clientes" icon="users" color="blue">
  O `SSEBroadcaster` suporta múltiplos clientes simultâneos via fan-out. Cada cliente recebe um canal dedicado — a lentidão de um cliente não impacta os demais.
</Callout>

***

## ⚠️ Considerações

<Callout type="warning">
  Este endpoint requer `ENABLED_WEBSOCKET=1` no ambiente. Se o fluxo WebSocket não estiver ativo, a conexão SSE será estabelecida mas nenhum evento será emitido até que algum handler WebSocket detecte uma oportunidade.
</Callout>

### Exemplo de Integração React

```jsx theme={null}
import { useEffect, useRef, useState } from 'react';

const BASE_API_URL = import.meta.env.VITE_API_URL;
const MAX_OPPORTUNITIES = 50;

function useRealtimeArbitrage() {
    const [opportunities, setOpportunities] = useState([]);
    const sourceRef = useRef(null);

    useEffect(() => {
        const source = new EventSource(`${BASE_API_URL}/v1/realtime/arbitrage`);
        sourceRef.current = source;

        source.onmessage = (event) => {
            const data = JSON.parse(event.data);
            setOpportunities(prev => [data, ...prev].slice(0, MAX_OPPORTUNITIES));
        };

        return () => source.close();
    }, []);

    return opportunities;
}
```
