# OHLC diário de DEX e VWAP para um token, com frações exatas

> Source: https://docs.blockvectra.com/pt-br/guides/dex-daily-prices/

## What the DEX daily prices dataset is

O conjunto de dados de DEX da BlockVectra indexa a atividade de negociação de exchanges descentralizadas e calcula métricas agregadas de preços diários. O endpoint de preços diários de DEX (`getDexPrices`) fornece o preço médio ponderado por volume (VWAP) diário, indicadores de preço (campos `first_price`, `last_price`, `min_price` e `max_price`) e métricas de volume para um token especificado ao longo de um determinado intervalo de datas.

A disponibilidade deste conjunto de dados varia entre as redes; as redes que fornecem este conjunto de dados estão sujeitas à página de [Redes compatíveis](https://docs.blockvectra.com/en/chains/).

Este endpoint não é paginado: todas as linhas diárias correspondentes dentro do intervalo de datas solicitado são retornadas diretamente em `data`, e `next_cursor` nunca está presente. Se a sua aplicação exigir transações de swap granulares em vez de agregações diárias, use `GET /{chain}/dex/swaps` (consulte a [Referência da Data API](https://docs.blockvectra.com/en/api/data/)).

## Request parameters and limits

A rota do endpoint é `GET https://api.blockvectra.com/v1/data/{chain}/dex/prices`. Todas as requisições exigem autenticação fornecendo sua API key no cabeçalho `x-api-key`.

O endpoint aceita os seguintes parâmetros de query:

| Parameter | Location | Type        | Required | Description                                                                                   |
| --------- | -------- | ----------- | -------- | --------------------------------------------------------------------------------------------- |
| `chain`   | path     | string      | Yes      | Identificador da rede, por exemplo `robinhood_mainnet`                                        |
| `token`   | query    | string      | Yes      | Endereço do token base de 20 bytes, `0x` opcional, maiúsculas ou minúsculas                   |
| `quote`   | query    | string      | No       | Endereço opcional de token de cotação de 20 bytes para restringir a um único par base/cotação |
| `from`    | query    | date string | Yes      | Data de início em UTC, inclusiva, `YYYY-MM-DD`                                                |
| `to`      | query    | date string | Yes      | Data de término em UTC, inclusiva, `YYYY-MM-DD`. `to - from` deve ser `<= 90` dias            |

### Constraints and error codes

Quando uma requisição viola restrições, a API retorna um corpo de erro estruturado `{"error":{"code","message"}}`:

* **HTTP 400 (`bad_request`)**: parâmetros de query obrigatórios ausentes (`token`, `from` ou `to`), sintaxe de endereço de `token`/`quote` inválida, datas de calendário `YYYY-MM-DD` inválidas ou `from` posterior a `to`.
* **HTTP 409 (`span_exceeded`)**: `to - from` superior a 90 dias.
* **HTTP 404 (`unknown_chain`)**: `{chain}` não é uma rede listada por `GET /chains`.
* **HTTP 422 (`no_coverage`)**: a rede não é compatível com o recurso do conjunto de dados `dex_prices`.
* **HTTP 503 (`unavailable`)**: serviço temporariamente indisponível; tente novamente de acordo com o cabeçalho `Retry-After`.

## Request examples

Os exemplos a seguir consultam os preços diários de DEX para um token base ao longo de setembro de 2026:

**cURL**

```bash
curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/dex/prices?token=0x1Cdad396DB64BDa184d5182A97Dd9B3C62100b7D&from=2026-09-01&to=2026-09-30" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"
```


  **TypeScript**

```ts
const url = new URL("https://api.blockvectra.com/v1/data/robinhood_mainnet/dex/prices");
url.searchParams.set("token", "0x1Cdad396DB64BDa184d5182A97Dd9B3C62100b7D");
url.searchParams.set("from", "2026-09-01");
url.searchParams.set("to", "2026-09-30");

const res = await fetch(url, {
  headers: {
    "x-api-key": process.env.BLOCKVECTRA_API_KEY!,
  },
});

if (!res.ok) {
  throw new Error(`Request failed with status ${res.status}`);
}

const body = await res.json();
console.log(body);
```


  **Python**

```python
import os
import requests

res = requests.get(
    "https://api.blockvectra.com/v1/data/robinhood_mainnet/dex/prices",
    params={
        "token": "0x1Cdad396DB64BDa184d5182A97Dd9B3C62100b7D",
        "from": "2026-09-01",
        "to": "2026-09-30",
    },
    headers={
        "x-api-key": os.environ["BLOCKVECTRA_API_KEY"],
    },
)
res.raise_for_status()
print(res.json())
```


## Detailed field reference

Cada entrada em `data` representa as métricas diárias agregadas de DEX para o par de tokens naquela data UTC:

### Token and quote assets

* `day` (string): data UTC no formato `YYYY-MM-DD`.
* `token` (string): endereço do token base de 20 bytes em hexadecimal prefixado com `0x` em letras minúsculas.
* `token_symbol` (string ou `null`): símbolo do token base.
* `token_name` (string ou `null`): nome de exibição do token base.
* `quote_token` (string): endereço do ativo de cotação. O endereço todo zerado (`0x0000000000000000000000000000000000000000`) representa o ETH nativo como ativo de cotação.
* `quote_symbol` (string ou `null`): símbolo do ativo de cotação (`"ETH"` quando `quote_token` for o endereço todo zerado).
* `quote_name` (string ou `null`): nome de exibição do ativo de cotação (`"Ether"` quando `quote_token` for o endereço todo zerado).
* `base_decimals` (integer ou `null`): casas decimais do token base (0–255).
* `quote_decimals` (integer ou `null`): casas decimais do ativo de cotação (`18` quando `quote_token` for o endereço todo zerado).

### Volume and trade counts

* `swap_count` (integer): contagem de swaps para esta linha.
* `base_volume_raw` (string): volume base atômico como string decimal de inteiro não assinado (`UInt256String`).
* `quote_volume_raw` (string): volume de cotação atômico como string decimal de inteiro não assinado (`UInt256String`).
* `base_volume` (string ou `null`): volume legível do token base dimensionado por `base_decimals` como `DecimalString`; `null` quando `base_decimals` for desconhecido.
* `quote_volume` (string ou `null`): volume de cotação dimensionado pelas casas decimais da cotação como `DecimalString`, ou `null`.

### Price indicators and VWAP

* `vwap` (string ou `null`): preço médio ponderado por volume como `DecimalString`, ou `null`.
* `first_price` (string ou `null`): indicador de primeiro preço como `DecimalString`, ou `null`.
* `last_price` (string ou `null`): indicador de último preço como `DecimalString`, ou `null`.
* `min_price` (string ou `null`): indicador de preço mínimo como `DecimalString`, ou `null`.
* `max_price` (string ou `null`): indicador de preço máximo como `DecimalString`, ou `null`.

### Exact fraction fields

* `first_price_numerator` / `first_price_denominator` (string): numerador e denominador inteiros exatos para `first_price` (`UInt256String`).
* `last_price_numerator` / `last_price_denominator` (string): numerador e denominador inteiros exatos para `last_price` (`UInt256String`).
* `min_price_numerator` / `min_price_denominator` (string): numerador e denominador inteiros exatos para `min_price` (`UInt256String`).
* `max_price_numerator` / `max_price_denominator` (string): numerador e denominador inteiros exatos para `max_price` (`UInt256String`).
* `refreshed_at` (string): timestamp de atualização para esta linha (timestamp UTC ISO-8601).

### Envelope metadata (`meta`)

* `chain`: identificador da rede.
* `chain_slug`: slug canônico da rede em maiúsculas.
* `chain_external_id`: identificador de rede formatado em CAIP-2.
* `as_of_block`: o bloco mais recente totalmente gravado da rede (relatado por este conjunto de dados, não verificado em relação aos parâmetros da requisição).
* `coverage`: classificação de cobertura (informa `"full"` para este endpoint).
* `refreshed_at`: timestamp de atualização dos metadados. Pode ser `null`: `null` significa que o horário de atualização desses dados é desconhecido e eles devem ser tratados como desatualizados; endpoints baseados em blocos sempre retornam um valor.

## Why prices use exact numerators and denominators

Números JSON padrão dependem de pontos flutuantes de precisão dupla IEEE-754, que apresentam limitações de precisão:

1. **Truncamento e desvio de ponto flutuante**: valores Float64 fornecem apenas 53 bits de precisão, e a divisão de quantidades de tokens gera desvios de arredondamento que se acumulam ao longo dos cálculos.
2. **Segurança no transporte**: formatar valores como strings decimais (`UInt256String`) garante que os números trafeguem via HTTP sem perda de precisão em analisadores JSON.

Ao fornecer o numerador e o denominador inteiros exatos para os indicadores de preço, a BlockVectra permite cálculos matemáticos exatos sem conversão para ponto flutuante.

### Handling exact fractions in TypeScript (BigInt)

No TypeScript, você pode usar `BigInt` nativo para comparações por multiplicação cruzada e conversões para ponto fixo sem conversão para ponto flutuante:

```ts
interface DexDailyPrice {
  first_price_numerator: string;
  first_price_denominator: string;
  last_price_numerator: string;
  last_price_denominator: string;
}

// 1. Ratio comparison without floating-point conversion: check if close price is higher than open price
// a / b > c / d  is equivalent to  a * d > c * b
export function isPriceUp(row: DexDailyPrice): boolean {
  const openNum = BigInt(row.first_price_numerator);
  const openDen = BigInt(row.first_price_denominator);
  const closeNum = BigInt(row.last_price_numerator);
  const closeDen = BigInt(row.last_price_denominator);

  return closeNum * openDen > openNum * closeDen;
}

// 2. Convert fraction to a fixed-point decimal string with arbitrary scale (without floating-point loss)
export function fractionToFixedString(
  numeratorStr: string,
  denominatorStr: string,
  decimals = 18
): string {
  const num = BigInt(numeratorStr);
  const den = BigInt(denominatorStr);
  if (decimals === 0) {
    return (num / den).toString();
  }
  const scaleFactor = 10n ** BigInt(decimals);

  const scaled = (num * scaleFactor) / den;
  const intPart = scaled / scaleFactor;
  const remainder = scaled % scaleFactor;
  const fracPart = remainder.toString().padStart(decimals, "0");

  return `${intPart}.${fracPart}`;
}
```

### Handling exact fractions in Python

O Python fornece módulos da biblioteca padrão criados especificamente para cálculos racionais e decimais: `fractions.Fraction` e `decimal.Decimal`.

```python
from decimal import Decimal, getcontext
from fractions import Fraction

# 1. Exact rational calculations with fractions.Fraction
open_price = Fraction(
    int(row["first_price_numerator"]),
    int(row["first_price_denominator"])
)
close_price = Fraction(
    int(row["last_price_numerator"]),
    int(row["last_price_denominator"])
)

# Exact price delta without floating-point rounding error
price_delta = close_price - open_price
print(f"Price delta (fraction): {price_delta}")

if open_price != 0:
    percentage_change = (price_delta / open_price) * 100
    print(f"Percentage change: {float(percentage_change):.4f}%")

# 2. Arbitrary-precision decimal arithmetic with decimal.Decimal
getcontext().prec = 50

if int(row["first_price_denominator"]) != 0:
    open_decimal = Decimal(row["first_price_numerator"]) / Decimal(row["first_price_denominator"])
    print(f"High-precision open: {open_decimal}")
```

## Backfilling one year of daily prices

Para fazer o backfill de um ano de dados (365 dias) dentro do limite de intervalo de 90 dias, divida o intervalo de datas completo em janelas consecutivas de no máximo 90 dias e envie requisições fragmentadas:

```ts
interface DateSpan {
  from: string;
  to: string;
}

/**
 * Split a large date range into consecutive spans of at most maxDays (default: 90)
 */
export function splitDateRange(startDateStr: string, endDateStr: string, maxDays = 90): DateSpan[] {
  const spans: DateSpan[] = [];
  let currentStart = new Date(startDateStr);
  const end = new Date(endDateStr);

  while (currentStart <= end) {
    const chunkEnd = new Date(currentStart);
    chunkEnd.setUTCDate(chunkEnd.getUTCDate() + (maxDays - 1));
    const effectiveEnd = chunkEnd < end ? chunkEnd : end;

    spans.push({
      from: currentStart.toISOString().slice(0, 10),
      to: effectiveEnd.toISOString().slice(0, 10),
    });

    const nextStart = new Date(effectiveEnd);
    nextStart.setUTCDate(nextStart.getUTCDate() + 1);
    currentStart = nextStart;
  }

  return spans;
}

/**
 * Backfill token daily prices across multiple 90-day chunks
 */
export async function backfillTokenDailyPrices(
  chain: string,
  token: string,
  startDate: string,
  endDate: string,
  apiKey: string
) {
  const chunks = splitDateRange(startDate, endDate, 90);
  const allDailyPrices = [];

  for (const chunk of chunks) {
    const url = new URL(`https://api.blockvectra.com/v1/data/${chain}/dex/prices`);
    url.searchParams.set("token", token);
    url.searchParams.set("from", chunk.from);
    url.searchParams.set("to", chunk.to);

    const res = await fetch(url, {
      headers: { "x-api-key": apiKey },
    });

    if (!res.ok) {
      throw new Error(`Failed to fetch span ${chunk.from}..${chunk.to}: HTTP ${res.status}`);
    }

    const json = await res.json();
    allDailyPrices.push(...json.data);
  }

  return allDailyPrices;
}
```

## Capacity and CU usage calculations

Cada endpoint da Data API mede o consumo em Compute Units (CU). O peso de CU por chamada para `data.dex_prices` e o consumo estimado para backfills de tokens são calculados abaixo:

- **Peso do método:** `data.dex_prices` = 15 CU / chamada.
- **Preenchimento histórico de 1 ano de preços diários para 200 tokens:** com um intervalo máximo de 90 dias por requisição, cobrir 365 dias requer 5 partes por token, totalizando 1,000 chamadas. O consumo total é de 15,000 CU (aprox. <0.1% da cota do ciclo do plano gratuito), cerca de <$0.01 a preço de tabela.
- **Manutenção diária (atualização de 200 tokens uma vez ao dia):** 200 chamadas/dia (3,000 CU/dia), totalizando aproximadamente 6,000 chamadas por ciclo de 30 dias (90,000 CU, aprox. 0.3% da cota gratuita), cerca de <$0.01/mês a preço de tabela.

Ao escalar o volume de backfill ou necessitar de maior concorrência de requisições, recarregue on-chain na [página de faturamento](https://console.blockvectra.com/billing/) do console para fazer upgrade para uma conta paga. Para tarifas ativas e conversões de unidades, consulte a [página de preços](https://blockvectra.com/en/pricing/).

## Next steps

* [Explore o diretório de conjuntos de dados](https://blockvectra.com/en/data/) para ver todos os conjuntos de dados indexados pela BlockVectra.
* [Consulte o plano gratuito e os preços](https://blockvectra.com/en/pricing/#free) para verificar o que sua conta inclui.
* [Entre no console](https://console.blockvectra.com/login/?next=%2Fkeys%2F) para criar uma API key.
