Présentation générale
Le StreamL4Book Le flux fournit l'intégralité du carnet d'ordres avec un niveau de détail par ordre individuel : chaque ordre en attente est accompagné de l'adresse de l'utilisateur, de l'identifiant de l'ordre, de son volume, des informations de déclenchement et des horodatages. Lors de l'abonnement, le flux envoie un instantané complet de tous les ordres en attente, puis des différences incrémentielles par bloc.
gRPC : OrderBookStreaming
gRPC : StreamL4Book
Disponibilité de l'API : API gRPC uniquement
Modèle de mise à jour : Instantané complet lors de l'abonnement, puis différences incrémentielles par bloc, avec possibilité de remplacer à tout moment l'instantané de référence
Comment ça marche ?
- Lors de l'inscription : Le flux envoie un
L4BookSnapshotcontenant toutes les offres d'achat et de vente en attente, avec les détails complets des ordres - Par bloc supplémentaire : Le flux envoie
L4BookDiffmessages au format JSONdonnéeschaîne contenantstatuts_de_commande(tous les objets de statut de commande correspondant au flux « Orders ») etbook_diffs(modifications progressives à l'aide deraw_book_diff(format correspondant au flux « Book Updates ») - Appliquez les modifications à votre copie locale de l'instantané pour maintenir l'état actuel
- Instantanés de remplacement : Le flux peut envoyer un autre
L4BookSnapshotaprès le premier, par exemple lorsqu’un ajout de frais prioritaires ALO modifie l’ordre de la file d’attente ou lorsque l’état du flux est reconstruit. Considérer chaque instantané comme faisant autorité : effacer les deux côtés du registre local, reconstruire à partir deoffresetdemandedans l'ordre dans lequel ils ont été générés, et continuer à appliquer les diffs ultérieurs à partir de cet instantanéhauteur
Il s'agit d'une méthode nettement plus simple pour créer et mettre à jour une vue locale du carnet d'ordres L4, car l'instantané initial est intégré : aucun amorçage REST ni aucune gestion des conditions de concurrence n'est nécessaire. Lors de la reconnexion, un nouvel instantané est automatiquement fourni.
Structure de données
Aperçu (premier message et messages suivants)
La première L4BookSnapshot contient le carnet d'ordres complet. Les instantanés ultérieurs reprennent la même structure et remplacent intégralement le carnet d'ordres local :
{
"snapshot": {
"coin": "ETH",
"time": 1764867600518,
"height": 817863403,
"bids": [
{
"user": "0x1c1c270b573d55b68b3d14722b5d5d401511bed0",
"coin": "ETH",
"side": "B",
"limit_px": "3167.4",
"sz": "1.5785",
"oid": 258166296856,
"timestamp": 1764867590000,
"trigger_condition": "N/A",
"is_trigger": false,
"trigger_px": "0",
"is_position_tpsl": false,
"reduce_only": false,
"order_type": "Limit",
"tif": "Gtc"
}
],
"asks": [
{
"user": "0xe9acfdc9322f6f924f007016c082e6891a3c653c",
"coin": "ETH",
"side": "A",
"limit_px": "3168.0",
"sz": "2.0000",
"oid": 258166160909,
"timestamp": 1764867580000,
"trigger_condition": "N/A",
"is_trigger": false,
"trigger_px": "0",
"is_position_tpsl": false,
"reduce_only": false,
"order_type": "Limit",
"tif": "Gtc"
}
]
}
}
Diff (messages suivants)
Après la prise d'instantané, chaque bloc génère un L4BookDiff avec des modifications incrémentielles encodées au format JSON :
{
"diff": {
"time": 1764867601000,
"height": 817863404,
"data": "{\"order_statuses\": [...], \"book_diffs\": [...]}"
}
}
Paramètres de requête
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
| pièce de monnaie | chaîne de caractères | Oui | Symbole à souscrire — pour les contrats à terme, on utilise des noms (par exemple, « BTC », « ETH ») ; pour le marché au comptant, on utilise le format @index (par exemple, « @142 ») |
Dénomination des pièces
Le pièce de monnaie Ce paramètre respecte la convention de nommage Hyperliquid, qui distingue sans ambiguïté les contrats à durée indéterminée des contrats au comptant :
- Titre perpétuel: Noms lisibles par l'utilisateur —
« BTC »,« ETH »,« HYPE »,« SOL » - Jetons au comptant:
@{index}format —« @1 »,« @107 »,« @142 »,« @166 » - Marchés des résultats (HIP-4):
#Nformat. Chaque résultat comporte deux#Npièces — une par côté (Oui et Non). Les marchés de questions à prix multiples se composent de plusieurs résultats regroupés (tranches de prix plus une option de repli), chacun disposant de sa propre paire de pièces Oui/Non. Utilisez leoutcomeMetaendpoint mettre en correspondance les indices des cryptomonnaies avec les noms et les côtés du marché. - Exception:
« PURR/USDC »C'est la seule pièce de monnaie dont le nom est lisible.
Il n'y a pas de chevauchement entre les formats. « BTC » fait toujours référence au contrat à terme perpétuel sur BTC ; le BTC au comptant est « @142 ». Pour découvrir @index mappages pour les jetons ponctuels, interroger le méta ou spotMeta points de terminaison d'information.
Champs de réponse
Mise à jour L4Book
Chaque message est un Mise à jour L4Book contenant soit un instantané, soit un fichier de différences :
| Champ | Type | Description |
|---|---|---|
| instantané | L4BookSnapshot | Aperçu complet du carnet de commandes (envoyé lors de l'abonnement, lors de la reconnexion et en cas de réinitialisation en cours de cycle) |
| diff | L4BookDiff | Différentiel incrémental (envoyé par bloc entre deux instantanés) |
L4BookSnapshot
| Champ | Type | Description |
|---|---|---|
| pièce de monnaie | chaîne de caractères | Symbole (par exemple, « BTC », « ETH ») |
| temps | uint64 | Horodatage du bloc en millisecondes |
| hauteur | uint64 | Hauteur du bloc |
| offres | L4Order[] | Tous les ordres d'achat en attente |
| demande | L4Order[] | Toutes les commandes en attente |
L4BookDiff
| Champ | Type | Description |
|---|---|---|
| temps | uint64 | Horodatage du bloc en millisecondes |
| hauteur | uint64 | Hauteur du bloc |
| données | chaîne de caractères | Objet encodé au format JSON contenant les champs « order_statuses » et « book_diffs », conforme au format de données existant des nœuds |
L4Order
| Champ | Type | Description |
|---|---|---|
| utilisateur | chaîne de caractères | Ethereum du titulaire de la commande |
| pièce de monnaie | chaîne de caractères | Identifiant de la paire de devises (par exemple, « ETH », « BTC ») |
| côté | chaîne de caractères | « A » (Cours vendeur/Vente) ou « B » (Cours acheteur/Achat) |
| limit_px | chaîne de caractères | Prix limite sous forme de chaîne décimale |
| sz | chaîne de caractères | Taille de la commande sous forme de chaîne décimale |
| oid | uint64 | Référence unique de la commande |
| horodatage | uint64 | Moment où l'ordre a été enregistré dans le carnet d'ordres (en millisecondes) |
| condition_de_déclenchement | chaîne de caractères | État de la condition de déclenchement : « N/A », « Déclenchée », etc. |
| is_trigger | bool | Que l'ordre soit un ordre à déclenchement ou un ordre stop |
| trigger_px | chaîne de caractères | Prix de déclenchement sous forme de chaîne décimale |
| is_position_tpsl | bool | Que l'ordre soit un ordre de prise de bénéfice ou un ordre stop-loss |
| réduire_uniquement | bool | Que l'ordre soit « réduction uniquement » |
| type_de_commande | chaîne de caractères | Type d'ordre : « à cours limité », « au marché », etc. |
| tif | chaîne de caractères (facultatif) | Durée de validité : « Gtc » (Valable jusqu'à annulation), « Ioc » (Immédiat ou annulé), « Alo » (Ajout de liquidité uniquement) |
| cloïde | chaîne de caractères (facultatif) | Référence de la commande client (identifiant personnalisé défini par l'utilisateur) |
Définition de « proto »
StreamL4Book est défini dans orderbook.proto:
service OrderBookStreaming {
rpc StreamL4Book (L4BookRequest) returns (stream L4BookUpdate);
}
message L4BookRequest {
string coin = 1;
}
message L4BookUpdate {
oneof update {
L4BookSnapshot snapshot = 1;
L4BookDiff diff = 2;
}
}
message L4BookSnapshot {
string coin = 1;
uint64 time = 2;
uint64 height = 3;
repeated L4Order bids = 4;
repeated L4Order asks = 5;
}
message L4BookDiff {
uint64 time = 1;
uint64 height = 2;
string data = 3;
}
message L4Order {
string user = 1;
string coin = 2;
string side = 3;
string limit_px = 4;
string sz = 5;
uint64 oid = 6;
uint64 timestamp = 7;
string trigger_condition = 8;
bool is_trigger = 9;
string trigger_px = 10;
bool is_position_tpsl = 11;
bool reduce_only = 12;
string order_type = 13;
optional string tif = 14;
optional string cloid = 15;
}
Exemples de mises à jour
Instantané L4 (état complet initial)
{
"snapshot": {
"coin": "ETH",
"time": 1764867600518,
"height": 817863403,
"bids": [
{
"user": "0x1c1c270b573d55b68b3d14722b5d5d401511bed0",
"coin": "ETH",
"side": "B",
"limit_px": "3167.4",
"sz": "1.5785",
"oid": 258166296856,
"timestamp": 1764867590000,
"trigger_condition": "N/A",
"is_trigger": false,
"trigger_px": "0",
"is_position_tpsl": false,
"reduce_only": false,
"order_type": "Limit",
"tif": "Gtc"
},
{
"user": "0x999a4b5f268a8fbf33736feff360d462ad248dbf",
"coin": "ETH",
"side": "B",
"limit_px": "3167.0",
"sz": "5.0000",
"oid": 258166123456,
"timestamp": 1764867585000,
"trigger_condition": "N/A",
"is_trigger": false,
"trigger_px": "0",
"is_position_tpsl": false,
"reduce_only": false,
"order_type": "Limit",
"tif": "Gtc",
"cloid": "0x20251204000000000000000000381433"
}
],
"asks": [
{
"user": "0xe9acfdc9322f6f924f007016c082e6891a3c653c",
"coin": "ETH",
"side": "A",
"limit_px": "3168.0",
"sz": "2.0000",
"oid": 258166160909,
"timestamp": 1764867580000,
"trigger_condition": "N/A",
"is_trigger": false,
"trigger_px": "0",
"is_position_tpsl": false,
"reduce_only": false,
"order_type": "Limit",
"tif": "Alo"
}
]
}
}
Diff L4 (mise à jour incrémentielle par bloc)
{
"diff": {
"time": 1764867601000,
"height": 817863404,
"data": "{\"order_statuses\":[...],\"book_diffs\":[...]}"
}
}
Le données Le champ est une chaîne encodée au format JSON. Une fois analysée, elle contient :
statuts_de_commande — Événements relatifs à l'état complet de la commande, à raison d'un par commande modifiée dans ce bloc. Chaque élément correspond à la Flux de commandes forme de l'événement :
{
"order": {
"coin": "ETH",
"side": "B",
"limitPx": "3167.4",
"sz": "1.5785",
"oid": 258166296856,
"timestamp": 1764867590000,
"triggerCondition": "N/A",
"isTrigger": false,
"triggerPx": "0.0",
"isPositionTpsl": false,
"reduceOnly": false,
"orderType": "Limit",
"tif": "Gtc",
"cloid": "0x...",
"user": null
},
"status": "filled",
"time": "2025-12-04T17:00:00.518000000",
"user": "0x1c1c270b573d55b68b3d14722b5d5d401511bed0"
}
book_diffs — Modifications incrémentielles du carnet de commandes. Chaque élément utilise le même raw_book_diff format tel que le Actualités sur les livres flux :
// New order or size update
{
"coin": "ETH",
"oid": 258166296857,
"px": "3168.0",
"raw_book_diff": { "new": { "sz": "2.0000" } },
"side": "A",
"user": "0xe9acfdc9322f6f924f007016c082e6891a3c653c"
}
// Order removed (cancelled or filled)
{
"coin": "ETH",
"oid": 258166296856,
"px": "3167.4",
"raw_book_diff": "remove",
"side": "B",
"user": "0x1c1c270b573d55b68b3d14722b5d5d401511bed0"
}
Ordre à déclenchement / ordre stop-loss
{
"user": "0x7a475736bf02d67bf51b00414ab766ef4da9214d",
"coin": "BTC",
"side": "A",
"limit_px": "90000.0",
"sz": "0.5000",
"oid": 258166400000,
"timestamp": 1764867595000,
"trigger_condition": "Triggered",
"is_trigger": true,
"trigger_px": "91000.0",
"is_position_tpsl": true,
"reduce_only": true,
"order_type": "Limit",
"tif": "Gtc"
}
Utilisation de l'API
gRPC
// Perp order book
const request = {
coin: 'ETH'
};
// Spot order book (@ index format)
const spotRequest = {
coin: '@142'
};
StreamL4Book n'est disponible que via l'API gRPC (OrderBookStreaming service). Il n'est pas disponible via JSON-RPC ou WebSocket.
Comparaison : ensemble de données « L4 Book » vs « L2 Book » vs « Book Updates »
| Fonctionnalité | StreamL4Book | StreamL2Book | MISE À JOUR DES LIVRES |
|---|---|---|---|
| Granularité | Commandes individuelles | Agrégés par niveau de prix | Différences au niveau des commandes individuelles |
| Comprend l'état actuel | Oui — instantané initial | Oui — chaque message | Non — à sens unique |
| Nécessite le démarrage REST | Non | Non | Oui |
| Gestion de l'état du client | Appliquer les modifications à l'instantané | Aucun | Créer à partir de zéro |
| Détails par commande | Utilisateur, oid, déclencheurs, horodatages, tif | Uniquement la taille totale et le nombre | Utilisateur, oid, taille |
| Bande passante | Plus haut (détails complets de la commande) | Moyen (limité à n_levels) | Faible (différentielles uniquement) |
| Idéal pour | HFT, équipes de trading quantitatif, MEV | La plupart des clients | Les clients qui ont uniquement besoin de mises à jour de livres |
Remarques importantes
- Considérez chaque instantané comme faisant autorité: les instantanés sont reçus lors de l'abonnement et de la reconnexion, et un instantané de remplacement peut également être reçu après des mises à jour incrémentielles normales (par exemple, lorsqu'une insertion de commission prioritaire ALO modifie l'ordre de la file d'attente). Sur les marchés actifs, les instantanés de remplacement peuvent être reçus plusieurs fois par minute. À chaque réception d'un instantané, effacez le carnet d'ordres local et reconstruisez-le à partir de l'instantané.
- La priorité de la file d'attente est déterminée par les instantanés, et non par
insertBefore: Le brut Actualités sur les livres Le flux expose uninsertBeforechamp sur les insertions prioritaires ; les diffs L4 ne le prennent pas en charge. Les streams L4 transmettent streams les modifications dans l'ordre de la file d'attente via des instantanés de remplacement dontoffresetdemandesont émises dans l'ordre canonique de la file d'attente. - Autoriser les messages volumineux: les instantanés de remplacement contiennent la profondeur L4 complète et peuvent être bien plus volumineux qu'un diff incrémental, en particulier pour le BTC. Prévoyez au moins 100 Mo pour gRPC entrants et appliquez chaque instantané de manière atomique avant de traiter les mises à jour ultérieures.
PERTE_DE_DONNÉESreconnexion: Le flux peut émettre des appels gRPCPERTE_DE_DONNÉESerreurs d'état lors de problèmes temporaires. Mettre en place une logique de reconnexion automatique surPERTE_DE_DONNÉES— un instantané actualisé est fourni à chaque nouvelle connexion, ce qui évite toute restauration manuelle de l'état.- Appliquer les modifications à l'état local: Entre deux instantanés, appliquez chacune d'entre elles
L4BookDiffpour tenir à jour le registre actuel. Chaquebook_diffsutilisations de l'articleraw_book_diff: {"new": {"sz": "..."}}pour ajouter ou modifier une commande, ouraw_book_diff : « supprimer »pour en supprimer un, selon le même format que le Actualités sur les livres flux. - Version dactylographiée disponible: Si vous avez uniquement besoin d'ajouter, de mettre à jour ou de supprimer des mouvements pour chaque commande sans analyser le format JSON,
donnéeschaîne, StreamL4BookUpdates fournit les mêmes modifications au niveau des ordres que les diffs Protobuf typés. - La compression zstd est vivement recommandée: les messages L4 peuvent être volumineux en raison des détails complets de la commande. Activez la compression zstd sur votre gRPC afin de réduire considérablement la bande passante.
Streams associés
- StreamL2Book - Niveaux de prix agrégés : plus simples, moins gourmands en bande passante, sans gestion d'état côté client
- StreamL4BookUpdates - Différences d'ajout, de mise à jour et de suppression classées par ordre, sans analyse JSON requise
- Mises à jour du livre - Comparaisons incrémentielles unidirectionnelles via StreamData (approche héritée)
- Commandes - Événements liés au cycle de vie des commandes (en cours, exécutées, annulées, etc.)
- Transactions - Données relatives aux transactions exécutées, avec informations sur les « makers » et les « takers »