El canal l2Book WebSocket de Hyperliquid entrega actualizaciones del libro de órdenes como un array levels que contiene dos sub-arrays: bids y asks, cada entrada formateada como [price, size, order count]. El canal está documentado como un snapshot completo por mensaje, por lo que el algoritmo local correcto es reemplazar todo el libro en cada mensaje en lugar de aplicar diffs incrementales. Para evitar un libro transitoriamente incorrecto, siembra desde el endpoint REST info con POST l2Book, luego cambia al stream WebSocket y reconcilia el primer snapshot contra la semilla. Detecta huecos usando el campo time del mensaje y una secuencia monotónica, y ante cualquier timeout de heartbeat o reconexión, descarta el libro local y re-siembra desde REST más el primer snapshot WebSocket fresco. Los consumidores en producción deben reconciliar periódicamente contra un snapshot REST fresco y nunca confiar en un libro local de larga vida indefinidamente.
Mecánica de suscripción al canal l2Book de Hyperliquid
El canal l2Book es una suscripción WebSocket pública que transmite niveles agregados del libro de órdenes para una sola moneda. Para suscribirse, envía un mensaje JSON con el método 'subscribe' y un objeto de suscripción que contenga el tipo 'l2Book' y el símbolo de la moneda, por ejemplo { method: 'subscribe', subscription: { type: 'l2Book', coin: 'BTC' } }. La convención de nombres de monedas sigue los símbolos de mercado de Hyperliquid, típicamente tickers en mayúsculas como 'BTC', 'ETH' o 'SOL'. El modelo de suscripción y la lista completa de canales se presentan en la guía de suscripciones WebSocket de Hyperliquid.
Cada mensaje l2Book contiene un array levels con exactamente dos sub-arrays: el primero son bids, el segundo son asks. Cada entrada es un array de tres elementos [px, sz, n] donde px es la cadena de precio, sz es la cadena de tamaño y n es el número de órdenes en ese nivel. La forma del payload está documentada en la documentación de suscripciones WebSocket de Hyperliquid. Debido a que el canal está documentado como envío de snapshots completos, el algoritmo de actualización es un reemplazo total del libro local, no una aplicación de diffs.
El mensaje también incluye un campo time. Trátalo como la marca de tiempo autoritativa para ordenamiento y verificaciones de frescura. Una secuencia monotónicamente creciente, ya sea derivada del tiempo o de un contador separado, es esencial para detectar actualizaciones fuera de orden o perdidas. Si eres nuevo en patrones de fiabilidad WebSocket, el artículo Reconexión WebSocket RPC y recuperación de huecos cubre la mecánica general que aplica aquí.
- Suscríbete con { method: 'subscribe', subscription: { type: 'l2Book', coin: 'BTC' } }.
- Los símbolos de monedas son tickers de mercado en mayúsculas; verifícalos contra la lista de mercados del exchange.
- El array levels siempre es [bids, asks] con entradas [px, sz, n].
- Trata cada mensaje como un snapshot completo a menos que la documentación del proveedor indique lo contrario.
Análisis y ordenación de niveles l2Book en un libro canónico
Después de recibir un mensaje, analiza el array levels en dos colecciones separadas: bids y asks. Para bids, ordena por precio descendente para que el mejor bid quede primero. Para asks, ordena por precio ascendente para que el mejor ask quede primero. Almacena precios y tamaños como cadenas o decimales de alta precisión para evitar errores de redondeo de punto flotante. El conteo de órdenes n es útil para análisis de liquidez pero no afecta la prioridad precio-tiempo en el libro agregado.
Una representación canónica del libro debe exponer el mejor bid, el mejor ask y el spread. El spread es el mejor ask menos el mejor bid. Si cualquiera de los lados está vacío, el libro es unilateral y el spread no está definido. Siempre valida que los precios sean positivos y los tamaños no negativos; las entradas malformadas deben registrarse y omitirse en lugar de corromper el estado local.
Debido a que los mensajes l2Book son snapshots completos, no necesitas fusionar niveles. Reemplaza las colecciones completas de bids y asks en cada mensaje. Esto simplifica la consistencia: el libro local es exactamente los niveles del último mensaje, ordenados canónicamente. La contrapartida es que no puedes detectar un mensaje perdido por un diff faltante; debes confiar en verificaciones de tiempo y secuencia.
- Bids: ordena descendente por precio; asks: ordena ascendente por precio.
- Usa aritmética de cadenas o decimales para px y sz.
- Reemplaza todo el libro en cada snapshot; no fusiones.
- Valida entradas y registra anomalías en lugar de aplicarlas.
Semántica de snapshot vs incremental y seguimiento de secuencia
El canal l2Book de Hyperliquid está documentado como envío de snapshots completos, pero la semántica exacta de diff/secuencia y cualquier campo de checksum se documentan por canal y pueden cambiar. Siempre confirma el comportamiento actual contra la documentación de suscripciones WebSocket de Hyperliquid antes de asumir solo snapshots. Si un canal alguna vez cambia a diffs incrementales, el algoritmo de actualización cambia a aplicar actualizaciones y eliminaciones de niveles de precio, y debes rastrear un número de secuencia para detectar huecos.
El campo time del mensaje proporciona una señal de ordenamiento gruesa. Si recibes un mensaje con un tiempo anterior al último mensaje aplicado, trátalo como fuera de orden y descártalo. Para garantías más fuertes, mantén un contador de secuencia monotónico si el proveedor expone uno. Sin una secuencia, solo puedes detectar huecos comparando contra un snapshot REST fresco periódicamente.
El ordenamiento de mensajes entre múltiples monedas no está garantizado globalmente. Si te suscribes a l2Book para BTC y ETH, el orden relativo de sus mensajes no es un indicador fiable del ordenamiento a nivel de mercado. Mantén un seguimiento de secuencia separado por moneda y nunca asumas causalidad entre monedas.
- Comportamiento documentado: l2Book envía snapshots completos; verifica por canal.
- Usa el tiempo y cualquier secuencia disponible para detectar actualizaciones fuera de orden o perdidas.
- El ordenamiento de mensajes entre monedas no está garantizado globalmente.
- Si se introducen diffs, cambia a lógica de aplicar y eliminar con verificaciones de secuencia.
Sembrado del libro local desde el endpoint REST info
Antes de abrir el WebSocket, siembra el libro local desde el endpoint REST info. Envía una solicitud POST a /info con cuerpo { type: 'l2Book', coin: 'BTC' }. La respuesta contiene la misma estructura de levels que el canal WebSocket. Esta semilla te da un punto de partida inmediato y consistente. El endpoint está documentado en la documentación del endpoint info de Hyperliquid.
Después de sembrar, abre el WebSocket y suscríbete a l2Book. El primer snapshot WebSocket puede diferir de la semilla REST debido al tiempo transcurrido entre las dos llamadas. Reconcilia reemplazando el libro local con el primer snapshot WebSocket, pero registra la divergencia entre la semilla y el primer snapshot. Si la divergencia excede un umbral que definas, alerta y considera re-sembrar. Esto evita un libro transitoriamente incorrecto donde el estado local es una mezcla de datos REST obsoletos y datos WebSocket frescos.
Un error común es aplicar el primer snapshot WebSocket como un diff contra la semilla REST. Debido a que l2Book es un snapshot completo, debes reemplazar, no fusionar. El paso de reconciliación es puramente observacional: compara, registra, luego reemplaza.
- Siembra con POST /info { type: 'l2Book', coin: 'BTC' }.
- Abre WebSocket y suscríbete a l2Book para la misma moneda.
- Reemplaza el libro local con el primer snapshot WebSocket.
- Registra la divergencia semilla-vs-snapshot para observabilidad.
const seedBook = async (coin) => {
const res = await fetch('https://api.hyperliquid.xyz/info', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ type: 'l2Book', coin })
});
const data = await res.json();
return data.levels; // [bids, asks]
};
// Usage
seedBook('BTC').then(levels => {
console.log('Seed bids:', levels[0].length, 'asks:', levels[1].length);
});Detección y recuperación de huecos y reconexiones
Un hueco ocurre cuando el libro local pierde una o más actualizaciones. Con snapshots completos, un mensaje perdido significa que el libro local está obsoleto hasta que llegue el siguiente snapshot. Si el siguiente snapshot llega rápidamente, el hueco se auto-sana. Si el socket está silencioso, el libro local puede permanecer obsoleto pero plausible, lo cual es peligroso para la lógica de trading. Usa un timeout de heartbeat para detectar silencio. El artículo Detección de heartbeat y keepalive WebSocket de Hyperliquid cubre la mecánica de keepalive en detalle.
Ante cualquier timeout de heartbeat o reconexión, descarta el libro local por completo. No intentes aplicar un diff parcial ni reanudar desde el último estado conocido. Re-siembra desde REST más el primer snapshot WebSocket fresco. Esto garantiza un punto de partida consistente. El patrón general se describe en Reconexión WebSocket RPC y recuperación de huecos.
Si detectas una regresión de tiempo o un salto de secuencia, trátalo como un hueco. Descarta y re-siembra. El costo de re-sembrar es un breve período sin libro, lo cual es más seguro que operar con un libro obsoleto. Para sistemas en producción, considera un interruptor de circuito que pause la lógica de trading hasta que el libro sea re-sembrado y validado.
- Timeout de heartbeat o reconexión: descarta el libro local.
- Re-siembra desde REST más el primer snapshot WebSocket fresco.
- Regresión de tiempo o salto de secuencia: trata como hueco, re-siembra.
- Pausa la lógica dependiente hasta que el libro sea validado.
Ejemplo ejecutable en Node.js: suscripción a l2Book y mantenimiento del libro
El siguiente ejemplo en Node.js se suscribe a l2Book para BTC, mantiene mapas ordenados de bids y asks, calcula el mejor bid/ask y el spread, y re-siembra al reconectar. Usa el paquete ws para WebSocket y fetch para la semilla REST. Reemplaza la URL del WebSocket con el endpoint de tu proveedor. Para opciones de endpoint, consulta Endpoints RPC de Hyperliquid (RPC Assistant).
El ejemplo trata cada mensaje como un snapshot completo y reemplaza el libro local. Rastrea el tiempo del último mensaje y descarta mensajes fuera de orden. Al reconectar, re-siembra desde REST antes de re-suscribirse. Este es un punto de partida mínimo pero correcto; agrega logging, métricas y alertas para producción.
const WebSocket = require('ws');
const COIN = 'BTC';
const WS_URL = 'wss://api.hyperliquid.xyz/ws';
const INFO_URL = 'https://api.hyperliquid.xyz/info';
let bids = new Map(); // price -> size
let asks = new Map();
let lastTime = 0;
const seed = async () => {
const res = await fetch(INFO_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ type: 'l2Book', coin: COIN })
});
const data = await res.json();
applySnapshot(data.levels);
};
const applySnapshot = (levels) => {
bids = new Map(levels[0].map(([px, sz]) => [px, sz]));
asks = new Map(levels[1].map(([px, sz]) => [px, sz]));
};
const bestBid = () => {
let best = null;
for (const [px] of bids) {
if (best === null || parseFloat(px) > parseFloat(best)) best = px;
}
return best;
};
const bestAsk = () => {
let best = null;
for (const [px] of asks) {
if (best === null || parseFloat(px) < parseFloat(best)) best = px;
}
return best;
};
const connect = async () => {
await seed();
const ws = new WebSocket(WS_URL);
ws.on('open', () => {
ws.send(JSON.stringify({
method: 'subscribe',
subscription: { type: 'l2Book', coin: COIN }
}));
});
ws.on('message', (raw) => {
const msg = JSON.parse(raw);
if (msg.channel !== 'l2Book') return;
if (msg.data.time < lastTime) return; // out-of-order
lastTime = msg.data.time;
applySnapshot(msg.data.levels);
const bb = bestBid();
const ba = bestAsk();
if (bb && ba) {
console.log('Best bid:', bb, 'Best ask:', ba, 'Spread:', parseFloat(ba) - parseFloat(bb));
}
});
ws.on('close', () => {
console.log('Reconnecting...');
setTimeout(connect, 1000);
});
};
connect();Verificación de consistencia reproducible contra snapshots REST
Para verificar tu libro local, obtén periódicamente un snapshot REST fresco y compara el mejor bid, el mejor ask y los tamaños de la parte superior del libro contra tu estado local. Ejecuta esta verificación en un intervalo fijo, por ejemplo cada 30 segundos, y registra la divergencia. Si la divergencia excede un umbral que definas, alerta y re-siembra. Este método es reproducible y no depende de garantías específicas del proveedor.
Usa la siguiente tabla para registrar tus mediciones. Rellénala con valores de tu propio endpoint y entorno. No confíes en números de benchmark de otras fuentes; mide los tuyos.
- Obtén snapshot REST vía POST /info { type: 'l2Book', coin: 'BTC' }.
- Compara el mejor bid/ask local y los tamaños superiores contra el snapshot.
- Registra la divergencia y alerta si supera el umbral.
- Re-siembra ante divergencia persistente.
const checkConsistency = async (localBids, localAsks) => {
const res = await fetch('https://api.hyperliquid.xyz/info', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ type: 'l2Book', coin: 'BTC' })
});
const data = await res.json();
const restBids = data.levels[0];
const restAsks = data.levels[1];
const restBestBid = restBids[0]?.[0];
const restBestAsk = restAsks[0]?.[0];
const localBestBid = [...localBids.keys()].sort((a,b) => parseFloat(b) - parseFloat(a))[0];
const localBestAsk = [...localAsks.keys()].sort((a,b) => parseFloat(a) - parseFloat(b))[0];
console.log('REST best bid:', restBestBid, 'Local best bid:', localBestBid);
console.log('REST best ask:', restBestAsk, 'Local best ask:', localBestAsk);
if (restBestBid !== localBestBid || restBestAsk !== localBestAsk) {
console.warn('Divergence detected');
}
};Tabla de resultados para mediciones de endpoint y entorno
Usa esta tabla para registrar tus propias mediciones. Las columnas están diseñadas para capturar la consistencia y frescura de tu libro local contra snapshots REST. Ejecuta la verificación de consistencia en un intervalo fijo y registra los resultados. Este es un método verificado por el lector; no se proporcionan números de benchmark porque dependen de tu red, proveedor y carga.
Rellena la tabla con tus propios datos. Si ves divergencias frecuentes, investiga tu conexión WebSocket, la configuración de heartbeat y la lógica de re-sembrado. El artículo Mecánica del canal de trades y fills WebSocket de Hyperliquid puede ayudarte a correlacionar actualizaciones del libro con actividad de trades.
- Timestamp: cuándo se ejecutó la verificación.
- Mejor bid/ask local: de tu libro local.
- Mejor bid/ask REST: del snapshot fresco.
- Divergencia: diferencia absoluta en precio o tamaño.
- Acción: ninguna, alertar o re-sembrar.
Solución de problemas comunes de consistencia de l2Book
Si tu libro local diverge con frecuencia, verifica si estás tratando los mensajes l2Book como diffs en lugar de snapshots. Aplicar un snapshot como diff corromperá el libro. Verifica que reemplazas las colecciones completas de bids y asks en cada mensaje. Si estás fusionando, cambia a reemplazo.
Si ves mensajes fuera de orden, asegúrate de comparar el campo time y descartar mensajes más antiguos. Si el proveedor no garantiza el ordenamiento, es posible que necesites almacenar en búfer y ordenar por tiempo. Si ves huecos, verifica que tu timeout de heartbeat no sea demasiado largo; un socket silencioso puede dejar un libro obsoleto. El artículo Detección de heartbeat y keepalive WebSocket de Hyperliquid cubre la detección.
Si el re-sembrado falla, verifica tu endpoint REST y los límites de tasa. La página de Precios RPC describe los límites del plan. Para opciones de endpoint, consulta Endpoints RPC de Hyperliquid (RPC Assistant). Si necesitas un servicio de API gestionado, consulta Servicio de API.
- Síntoma: el libro diverge después del primer mensaje. Causa: aplicar snapshot como diff. Solución: reemplazar todo el libro.
- Síntoma: libro obsoleto sin actualizaciones. Causa: socket silencioso. Solución: timeout de heartbeat y re-sembrar.
- Síntoma: actualizaciones fuera de orden. Causa: sin verificación de tiempo. Solución: descartar mensajes más antiguos.
- Síntoma: falla el re-sembrado. Causa: errores REST o límites de tasa. Solución: verificar endpoint y plan.
Limitaciones y compensaciones del mantenimiento del libro de órdenes local
La semántica exacta de diff/secuencia y cualquier campo de checksum se documentan por canal y pueden cambiar. Siempre verifica contra la documentación de suscripciones WebSocket de Hyperliquid. El ordenamiento de mensajes entre múltiples monedas no está garantizado globalmente, así que no asumas causalidad entre monedas. Un libro local es tan fresco como el último mensaje aplicado; un socket silencioso puede dejar un libro obsoleto pero plausible que parece correcto pero no lo es.
Los consumidores en producción deben reconciliar periódicamente en lugar de confiar en un libro local de larga vida indefinidamente. El costo de la reconciliación son llamadas REST adicionales, que pueden estar sujetas a límites de tasa. Equilibra la frescura contra los límites de tasa según tu estrategia de trading. Para trading de baja latencia, considera un proveedor dedicado; consulta Endpoints RPC de Hyperliquid (RPC Assistant).
Ningún libro local puede garantizar consistencia perfecta sin un número de secuencia y checksum del proveedor. Si el proveedor no expone estos, tu mejor defensa es la reconciliación frecuente y el re-sembrado conservador. Documenta tus suposiciones y monitorea la divergencia.
- La semántica de diff/secuencia se documenta por canal y puede cambiar.
- El ordenamiento entre monedas no está garantizado globalmente.
- Los sockets silenciosos pueden dejar libros obsoletos pero plausibles.
- Reconcilia periódicamente; no confíes indefinidamente.
Próximos pasos para consumidores de libros de órdenes de grado producción
Comienza implementando el patrón de sembrar y reemplazar con un timeout de heartbeat y re-sembrado al reconectar. Agrega la verificación de consistencia contra snapshots REST y registra la divergencia. Una vez estable, agrega métricas y alertas. Para una visión más amplia de Hyperliquid en OnFinality, consulta Hyperliquid y el centro de aprendizaje de OnFinality.
Si necesitas endpoints WebSocket gestionados con características de fiabilidad, explora Servicio de API y Precios RPC. Para selección de endpoint, consulta Endpoints RPC de Hyperliquid (RPC Assistant). Continúa con la guía de suscripciones WebSocket de Hyperliquid y Mecánica del canal de trades y fills WebSocket de Hyperliquid para profundizar tu comprensión.
Finalmente, revisa el artículo Reconexión WebSocket RPC y recuperación de huecos para patrones generales que aplican más allá de Hyperliquid. Prueba tu implementación bajo condiciones adversas: caídas de red, reinicios del proveedor y alta volatilidad. Solo entonces confía en tu libro local para decisiones automatizadas.
- Implementa sembrar y reemplazar con timeout de heartbeat.
- Agrega verificaciones de consistencia y registro de divergencias.
- Usa endpoints gestionados para fiabilidad.
- Prueba bajo condiciones adversas antes de confiar en el libro.