Exemple de code pour l'interprétation du flux de carnet d'ordres de l'API WebSocket v1 (asynchrone/multithread)

Dernière mise à jour : 2 avr. 2025

Des instructions détaillées pour interpréter le flux de carnet d'ordres de l'API WebSocket v1 sont disponibles sur notre page d'assistance Comment maintenir un carnet d'ordres valide.

Un exemple de code en Python pour l'intégration avec le flux de carnet d'ordres de l'API WebSocket v1 et la maintenance d'une copie locale d'un carnet d'ordres est fourni ci-dessous.

Le code utilise la bibliothèque WebSocket Python standard et implémente une approche asynchrone (pilotée par les événements/multithread), ce qui permet à d'autres tâches de se poursuivre en parallèle de l'interprétation du flux de carnet d'ordres.

Utilisation

Le code doit être exécuté via une invite de commande (comme le Terminal macOS) comme suit :

  • krakenwsorderbookasync.py symbole profondeur, ou,

  • python3 krakenwsorderbookasync.py symbole profondeur

Par exemple, la commande suivante récupérerait et interpréterait le flux de carnet d'ordres Dogecoin/USD (XDG/USD) à une profondeur de 10 niveaux de prix (par côté) :

  • krakenwsorderbookasync.py XDG/USD 10

Note que le code s'exécutera indéfiniment jusqu'à ce qu'il soit terminé par une interruption clavier (Ctrl+C dans la plupart des environnements de ligne de commande).

Code Python

Le code Python peut être consulté ci-dessous et peut également être téléchargé sous le nom krakenwsorderbookasync.py.

#!/usr/bin/env python3

# Importer la bibliothèque client WebSocket (et autres)
import sys
import json
import signal
import time
import _thread
import websocket

# Analyser les arguments de ligne de commande (symbole et profondeur)
if len(sys.argv) < 3:
sys.exit(1)
else:
api_symbol = sys.argv[1]
api_depth = int(sys.argv[2])

# Définir les variables du carnet d'ordres
api_book = {'bid':{}, 'ask':{}}

# Définir les fonctions de mise à jour du carnet d'ordres
def dicttofloat(data):
return float(data[0])

def api_book_update(api_book_side, api_book_data):
for data in api_book_data:
price_level = data[0]
volume = data[1]
if float(volume) > 0.0:
api_book[api_book_side][price_level] = volume
else:
api_book[api_book_side].pop(price_level)
if api_book_side == 'bid':
api_book['bid'] = dict(sorted(api_book['bid'].items(), key=dicttofloat, reverse=True)[:api_depth])
elif api_book_side == 'ask':
api_book['ask'] = dict(sorted(api_book['ask'].items(), key=dicttofloat)[:api_depth])

# Définir les fonctions de rappel WebSocket
def ws_thread(*args):
ws = websocket.WebSocketApp('wss://ws.kraken.com/', on_open=ws_open, on_message=ws_message)
ws.run_forever()

def ws_open(ws):
ws.send('{"event":"subscribe", "subscription":{"name":"book", "depth":%(api_depth)d}, "pair":["%(api_symbol)s"]}' % {'api_depth':api_depth, 'api_symbol':api_symbol})

def ws_message(ws, ws_data):
api_data = json.loads(ws_data)
if 'event' in api_data:
return
else:
if 'as' in api_data[1]:
api_book_update('ask', api_data[1]['as'])
api_book_update('bid', api_data[1]['bs'])
else:
for data in api_data[1:len(api_data)-2]:
if 'a' in data:
api_book_update('ask', data['a'])
elif 'b' in data:
api_book_update('bid', data['b'])

# Démarrer un nouveau thread pour l'interface WebSocket
_thread.start_new_thread(ws_thread, ())

# Afficher le carnet d'ordres (une fois par seconde) dans le thread principal
try:
while True:
if len(api_book['bid']) < api_depth or len(api_book['ask']) < api_depth:
time.sleep(1)
else:
bid = sorted(api_book['bid'].items(), key=dicttofloat, reverse=True)
ask = sorted(api_book['ask'].items(), key=dicttofloat)
print('Offre\t\t\t\t\t\t\tDemande')
for count in range(api_depth):
print('%(bidprice)s (%(bidvolume)s)\t\t\t\t%(askprice)s (%(askvolume)s)' \
% {'bidprice':bid[count][0], 'bidvolume':bid[count][1], 'askprice':ask[count][0], 'askvolume':ask[count][1]})
time.sleep(1)
except KeyboardInterrupt:
sys.exit(0)

Besoin d’aide supplémentaire ?