OHLC diário de DEX e VWAP para um token, com frações exatas
Consulte preços diários de OHLC e VWAP de DEX na Data API, manipule frações racionais exatas em TypeScript e Python e faça o backfill de dados históricos com eficiência.
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.
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).
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,fromouto), sintaxe de endereço detoken/quoteinválida, datas de calendárioYYYY-MM-DDinválidas oufromposterior ato. - HTTP 409 (
span_exceeded):to - fromsuperior a 90 dias. - HTTP 404 (
unknown_chain):{chain}não é uma rede listada porGET /chains. - HTTP 422 (
no_coverage): a rede não é compatível com o recurso do conjunto de dadosdex_prices. - HTTP 503 (
unavailable): serviço temporariamente indisponível; tente novamente de acordo com o cabeçalhoRetry-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 -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"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 formatoYYYY-MM-DD.token(string): endereço do token base de 20 bytes em hexadecimal prefixado com0xem letras minúsculas.token_symbol(string ounull): símbolo do token base.token_name(string ounull): 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 ounull): símbolo do ativo de cotação ("ETH"quandoquote_tokenfor o endereço todo zerado).quote_name(string ounull): nome de exibição do ativo de cotação ("Ether"quandoquote_tokenfor o endereço todo zerado).base_decimals(integer ounull): casas decimais do token base (0–255).quote_decimals(integer ounull): casas decimais do ativo de cotação (18quandoquote_tokenfor 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 ounull): volume legível do token base dimensionado porbase_decimalscomoDecimalString;nullquandobase_decimalsfor desconhecido.quote_volume(string ounull): volume de cotação dimensionado pelas casas decimais da cotação comoDecimalString, ounull.
Price indicators and VWAP
vwap(string ounull): preço médio ponderado por volume comoDecimalString, ounull.first_price(string ounull): indicador de primeiro preço comoDecimalString, ounull.last_price(string ounull): indicador de último preço comoDecimalString, ounull.min_price(string ounull): indicador de preço mínimo comoDecimalString, ounull.max_price(string ounull): indicador de preço máximo comoDecimalString, ounull.
Exact fraction fields
first_price_numerator/first_price_denominator(string): numerador e denominador inteiros exatos parafirst_price(UInt256String).last_price_numerator/last_price_denominator(string): numerador e denominador inteiros exatos paralast_price(UInt256String).min_price_numerator/min_price_denominator(string): numerador e denominador inteiros exatos paramin_price(UInt256String).max_price_numerator/max_price_denominator(string): numerador e denominador inteiros exatos paramax_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 sernull:nullsignifica 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:
- 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.
- 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:
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.
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:
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:
data.dex_prices: 15 CU / call- 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 do console para fazer upgrade para uma conta paga. Para tarifas ativas e conversões de unidades, consulte a página de preços.
Next steps
- Explore o diretório de conjuntos de dados para ver todos os conjuntos de dados indexados pela BlockVectra.
- Consulte o plano gratuito e os preços para verificar o que sua conta inclui.
- Entre no console para criar uma API key.
Última atualização:
Implantação de contratos
Implante o Hello.sol em uma rede EVM com Foundry ou Hardhat 2, verifique o Chain ID e confira o recibo da transação e a resposta do contrato.
Estado histórico da EVM
Distinga janelas de estado autenticadas, histórico sem chave e intervalos de logs. Escolha um bloco fixo para eth_call e diagnostique erros de state_window.