> ## 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 Prices Stream

> Stream SSE com snapshot completo de preços do cache WebSocket, atualizado a cada 1 segundo

## 📖 Descrição

Endpoint de **Server-Sent Events (SSE)** que transmite periodicamente um snapshot completo de todos os preços atualmente armazenados no `RealtimePriceCache`. O snapshot é emitido a cada **1 segundo**, contendo ask/bid/volume de todos os pares de todas as exchanges com conexão WebSocket ativa.

<Callout title="Diferença do Arbitrage Stream" icon="info-circle" color="blue">
  O endpoint `/v1/realtime/arbitrage` emite apenas oportunidades (pares com spread positivo). Este endpoint `/v1/realtime/prices` emite **todos os preços** do cache independentemente de haver arbitragem — ideal para dashboards de monitoramento de mercado.
</Callout>

***

## 🛠️ Requisição

### Método

`GET`

### URL

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

### Headers Necessários

| Header          | Valor               |
| --------------- | ------------------- |
| `Accept`        | `text/event-stream` |
| `Cache-Control` | `no-cache`          |

### 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/prices'
```

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

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

source.onmessage = (event) => {
    const snapshot = JSON.parse(event.data);
    // snapshot é um array de entradas de preço
    snapshot.forEach(entry => {
        console.log(`${entry.ticker} @ ${entry.exchange}: ask=${entry.ask} bid=${entry.bid}`);
    });
};

source.onerror = () => {
    // EventSource reconecta automaticamente
};

// Ao desmontar:
// source.close();
```

***

## 📤 Resposta

### Headers da Resposta

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

### Frequência de Emissão

Um evento é emitido a cada **1 segundo** enquanto a conexão estiver aberta.

### Formato dos Eventos SSE

```
data: [{"ticker":"BTC-USDT","exchange":"Binance","ask":43380.00,"bid":43375.50,...}, ...]

data: [{"ticker":"BTC-USDT","exchange":"Binance","ask":43381.00,"bid":43376.00,...}, ...]
```

### Estrutura do Payload JSON

O payload é um **array** de entradas de preço:

```json theme={null}
[
  {
    "ticker": "BTC-USDT",
    "exchange": "Binance",
    "ask": 43380.00,
    "bid": 43375.50,
    "askQty": 0.012,
    "bidQty": 0.085,
    "volume": 28543.12,
    "updatedAt": "2025-03-18T12:00:00.000Z"
  },
  {
    "ticker": "ETH-USDT",
    "exchange": "Binance",
    "ask": 2258.10,
    "bid": 2257.90,
    "askQty": 1.25,
    "bidQty": 0.75,
    "volume": 145230.00,
    "updatedAt": "2025-03-18T12:00:00.000Z"
  }
]
```

### Campos de Cada Entrada

| Campo       | Tipo              | Descrição                                     |
| ----------- | ----------------- | --------------------------------------------- |
| `ticker`    | string            | Par de trading normalizado (ex: `BTC-USDT`)   |
| `exchange`  | string            | Nome da exchange de origem                    |
| `ask`       | float             | Melhor preço de venda (ask)                   |
| `bid`       | float             | Melhor preço de compra (bid)                  |
| `askQty`    | float             | Quantidade disponível no ask                  |
| `bidQty`    | float             | Quantidade disponível no bid                  |
| `volume`    | float             | Volume de 24h (seed REST, refresh a cada 60s) |
| `updatedAt` | string (ISO 8601) | Timestamp do último tick WebSocket            |

***

## 💡 Casos de Uso

### Dashboard de Preços ao Vivo

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

function usePricesSnapshot() {
    const [prices, setPrices] = useState([]);

    useEffect(() => {
        const source = new EventSource(
            `${import.meta.env.VITE_API_URL}/v1/realtime/prices`
        );

        source.onmessage = (event) => {
            setPrices(JSON.parse(event.data));
        };

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

    return prices;
}
```

### Filtrar Preços por Exchange

```javascript theme={null}
source.onmessage = (event) => {
    const all = JSON.parse(event.data);
    const binancePrices = all.filter(e => e.exchange === 'Binance');
    updateTable(binancePrices);
};
```

### Calcular Spread Manualmente

```javascript theme={null}
source.onmessage = (event) => {
    const all = JSON.parse(event.data);
    
    // Agrupar por ticker
    const byTicker = {};
    all.forEach(entry => {
        if (!byTicker[entry.ticker]) byTicker[entry.ticker] = [];
        byTicker[entry.ticker].push(entry);
    });

    // Para cada ticker, encontrar melhor compra e venda
    Object.entries(byTicker).forEach(([ticker, entries]) => {
        const minAsk = Math.min(...entries.map(e => e.ask));
        const maxBid = Math.max(...entries.map(e => e.bid));
        const spread = (maxBid - minAsk) / minAsk * 100;

        if (spread > 0) {
            console.log(`${ticker}: spread ${spread.toFixed(2)}%`);
        }
    });
};
```

***

## ⚠️ Considerações de Performance

<Callout type="warning">
  Este endpoint emite um payload potencialmente grande (todos os pares de todas as exchanges) a cada segundo. Use-o com moderação — em produção, prefira o endpoint `/v1/realtime/arbitrage` que emite apenas as oportunidades relevantes.
</Callout>

**Volume estimado de dados:**

* Fase 1 (Binance): \~850 pares × 1 exchange ≈ \~150 KB/s por cliente
* Fase 2 (6 exchanges): \~800 pares × 6 exchanges ≈ \~900 KB/s por cliente
* Fase 3 (12 exchanges): considere paginação ou filtragem por exchange

<Callout title="Recomendação" icon="lightbulb" color="yellow">
  Para interfaces de usuário, filtre o stream no servidor ou adicione um parâmetro de query `exchange` para receber apenas os preços de interesse — evitando tráfego desnecessário.
</Callout>
