OHLC y VWAP diarios de DEX para un token, con fracciones exactas
Consulta precios OHLC y VWAP diarios de DEX en la Data API, maneja fracciones racionales exactas en TypeScript y Python y carga datos históricos de forma eficiente.
Qué es el conjunto de datos de precios diarios de DEX
El conjunto de datos DEX de BlockVectra indexa la actividad de operaciones de exchanges descentralizados y calcula métricas de precios agregadas por día. El endpoint de precios diarios de DEX (getDexPrices) proporciona el precio medio ponderado por volumen (VWAP) diario, indicadores de precio (campos first_price, last_price, min_price y max_price) y métricas de volumen para un token específico en un rango de fechas determinado.
La disponibilidad de este conjunto de datos varía entre redes; consulte las cadenas que lo ofrecen en la página de Cadenas admitidas.
Este endpoint no tiene paginación: todas las filas diarias coincidentes dentro del intervalo de fechas solicitado se devuelven directamente en data, y next_cursor nunca está presente. Si su aplicación necesita transacciones de swap individuales en lugar de agregados diarios, use GET /{chain}/dex/swaps (consulte la referencia de la Data API).
Parámetros de solicitud y límites
La ruta del endpoint es GET https://api.blockvectra.com/v1/data/{chain}/dex/prices. Todas las solicitudes requieren autenticación mediante su API key en el encabezado x-api-key.
El endpoint acepta los siguientes parámetros de consulta:
| Parámetro | Ubicación | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
chain | path | string | Sí | Identificador de cadena, p. ej., robinhood_mainnet |
token | query | string | Sí | Dirección del token base de 20 bytes, 0x opcional, en mayúsculas o minúsculas |
quote | query | string | No | Dirección opcional del token de cotización de 20 bytes para restringir a un único par base/cotización |
from | query | date string | Sí | Fecha de inicio UTC, inclusive, YYYY-MM-DD |
to | query | date string | Sí | Fecha de fin UTC, inclusive, YYYY-MM-DD. to - from debe ser <= 90 días |
Restricciones y códigos de error
Cuando una solicitud incumple las restricciones, la API devuelve un cuerpo de error estructurado {"error":{"code","message"}}:
- HTTP 400 (
bad_request): Faltan parámetros de consulta obligatorios (token,fromoto), la sintaxis de las direccionestoken/quoteno es válida, las fechas del calendarioYYYY-MM-DDno son válidas, ofromes posterior ato. - HTTP 409 (
span_exceeded):to - fromsupera los 90 días. - HTTP 404 (
unknown_chain):{chain}no es una cadena listada porGET /chains. - HTTP 422 (
no_coverage): La cadena no admite la capacidad del conjunto de datosdex_prices. - HTTP 503 (
unavailable): Servicio temporalmente no disponible; reintente según el encabezadoRetry-After.
Ejemplos de solicitudes
Los ejemplos siguientes consultan los precios diarios de DEX de un token base durante septiembre 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"Referencia detallada de campos
Cada entrada de data representa métricas diarias agregadas de DEX para el par de tokens en esa fecha UTC:
Token y activos de cotización
day(string): Fecha UTC en formatoYYYY-MM-DD.token(string): Dirección del token base de 20 bytes en hexadecimal en minúsculas con prefijo0x.token_symbol(string onull): Símbolo del token base.token_name(string onull): Nombre para mostrar del token base.quote_token(string): Dirección del activo de cotización. La dirección de ceros (0x0000000000000000000000000000000000000000) representa ETH nativo como activo de cotización.quote_symbol(string onull): Símbolo del activo de cotización ("ETH"cuandoquote_tokenes la dirección de ceros).quote_name(string onull): Nombre para mostrar del activo de cotización ("Ether"cuandoquote_tokenes la dirección de ceros).base_decimals(integer onull): Decimales del token base (0–255).quote_decimals(integer onull): Decimales del activo de cotización (18cuandoquote_tokenes la dirección de ceros).
Volumen y recuento de operaciones
swap_count(integer): Número de swaps de esta fila.base_volume_raw(string): Volumen base en unidades atómicas como cadena decimal de entero sin signo (UInt256String).quote_volume_raw(string): Volumen de cotización en unidades atómicas como cadena decimal de entero sin signo (UInt256String).base_volume(string onull): Volumen del token base legible para humanos, escalado segúnbase_decimalscomoDecimalString;nullcuando se desconocebase_decimals.quote_volume(string onull): Volumen de cotización escalado según los decimales de cotización comoDecimalString, onull.
Indicadores de precio y VWAP
vwap(string onull): Precio medio ponderado por volumen comoDecimalString, onull.first_price(string onull): Indicador del primer precio comoDecimalString, onull.last_price(string onull): Indicador del último precio comoDecimalString, onull.min_price(string onull): Indicador de precio mínimo comoDecimalString, onull.max_price(string onull): Indicador de precio máximo comoDecimalString, onull.
Campos de fracciones exactas
first_price_numerator/first_price_denominator(string): Numerador y denominador enteros exactos defirst_price(UInt256String).last_price_numerator/last_price_denominator(string): Numerador y denominador enteros exactos delast_price(UInt256String).min_price_numerator/min_price_denominator(string): Numerador y denominador enteros exactos demin_price(UInt256String).max_price_numerator/max_price_denominator(string): Numerador y denominador enteros exactos demax_price(UInt256String).refreshed_at(string): Marca de tiempo de actualización de esta fila (marca de tiempo UTC ISO-8601).
Metadatos de la estructura de respuesta (meta)
chain: Identificador de cadena.chain_slug: Slug canónico de la cadena en mayúsculas.chain_external_id: Identificador de cadena en formato CAIP-2.as_of_block: Último bloque de la cadena completamente escrito (comunicado por este conjunto de datos, sin comprobarlo frente a los parámetros de solicitud).coverage: Clasificación de cobertura (comunica"full"para este endpoint).refreshed_at: Marca de tiempo de actualización de los metadatos. Puede sernull:nullsignifica que se desconoce cuándo se actualizaron estos datos y deben tratarse como obsoletos; los endpoints basados en bloques siempre devuelven un valor.
Por qué los precios usan numeradores y denominadores exactos
Los números JSON estándar dependen de valores de coma flotante de doble precisión IEEE-754, que tienen limitaciones de precisión:
- Truncamiento y desviación de coma flotante: Los valores Float64 solo ofrecen 53 bits de precisión, y dividir cantidades de tokens genera desviaciones de redondeo que se acumulan entre cálculos.
- Seguridad en la transmisión: Dar formato a los valores como cadenas decimales (
UInt256String) garantiza que los números se transmitan por HTTP sin perder precisión en los analizadores JSON.
Al proporcionar el numerador y el denominador enteros exactos de los indicadores de precio, BlockVectra permite cálculos matemáticos exactos sin conversión a coma flotante.
Manejo de fracciones exactas en TypeScript (BigInt)
En TypeScript, puede usar BigInt nativo para comparaciones mediante multiplicación cruzada y conversiones a punto fijo sin conversión a coma flotante:
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}`;
}Manejo de fracciones exactas en Python
Python proporciona módulos de la biblioteca estándar diseñados específicamente para cálculos racionales y decimales: fractions.Fraction y 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}")Carga histórica de un año de precios diarios
Para cargar un año de datos (365 días) dentro del límite de intervalo de 90 días, divida el rango completo de fechas en ventanas consecutivas de un máximo de 90 días y envíe solicitudes por segmentos:
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;
}Cálculos de capacidad y consumo de CU
Cada endpoint de la Data API mide el consumo en unidades de cómputo (CU). A continuación se calculan el peso CU por llamada de data.dex_prices y el consumo estimado de las cargas históricas de tokens:
data.dex_prices: 15 CU / call- Carga histórica de 1 año de precios diarios para 200 tokens: con un rango máximo de 90 días por solicitud, cubrir 365 días toma 5 fragmentos por token, con un total de 1,000 llamadas. El consumo total es de 15,000 CU (aprox. <0.1% de la cuota del ciclo del plan gratuito), aprox. <$0.01 a precio de lista.
- Mantenimiento diario (actualización de 200 tokens una vez al día): 200 llamadas/día (3,000 CU/día), con un total de aprox. 6,000 llamadas por ciclo de 30 días (90,000 CU, aprox. 0.3% de la cuota gratuita), aprox. <$0.01/mes a precio de lista.
Cuando aumente el volumen de carga histórica o necesite mayor concurrencia de solicitudes, recargue on-chain en la página de Facturación de la consola para pasar a una cuenta de pago. Para conocer las tarifas vigentes y las conversiones de unidades, consulte la página de Precios.
Próximos pasos
- Explore el catálogo de conjuntos de datos para ver todos los conjuntos de datos que indexa BlockVectra.
- Consulte el plan gratuito y los precios para comprobar qué incluye su cuenta.
- Inicie sesión en la consola para crear una API key.
Última actualización:
Despliegue de contratos
Despliega Hello.sol en una red EVM con Foundry o Hardhat 2, verifica el chain ID y comprueba el recibo de la transacción y la respuesta del contrato.
Estado histórico EVM
Distinga las ventanas de estado autenticadas, el historial sin clave y la amplitud de logs. Elija un bloque fijo para eth_call y diagnostique errores state_window.