Des flux crypto qui survivent à une reconnexion, et un limiteur de débit qui vous évite le bannissement | Blog eSeGeCe

Des flux crypto qui survivent à une reconnexion, et un limiteur de débit qui vous évite le bannissement

· Composants

Toute application qui dialogue avec une plateforme d'échange crypto finit par écrire la même tuyauterie, deux fois. La première rétablit vos abonnements aux données de marché après la chute du socket. La seconde ralentit vos appels REST pour que la plateforme ne vous limite pas. Ni l'un ni l'autre n'est du code intéressant, les deux sont faciles à rater subtilement, et les deux ont été laissés à la charge de l'application jusqu'à présent.

sgcWebSockets 2026.7 les intègre. Les clients d'API des plateformes peuvent rejouer leurs propres abonnements après une reconnexion, et chaque client REST prêt à l'emploi dispose désormais d'un limiteur de débit côté client qui plafonne le nombre de requêtes envoyées dans une fenêtre de temps. Les deux sont optionnels et désactivés par défaut, donc la mise à jour ne change rien tant que vous ne les activez pas.

La reconnexion qui vous laisse abonné à rien

Le WatchDog a toujours été bon pour récupérer la connexion. Un câble est débranché, un proxy dépasse son délai, la plateforme redémarre une passerelle, et quelques secondes plus tard le client est de nouveau connecté. Cette partie fonctionne.

Ce qui ne revient pas, ce sont vos abonnements. La plateforme n'en a aucun souvenir. Un nouveau socket est une session vierge, donc les flux de transactions et de carnet d'ordres que vous aviez demandés sur l'ancien socket n'existent tout simplement plus. Le symptôme est vicieux car rien n'a l'air cassé : le client signale Connected, aucune erreur n'est levée, et les événements de message cessent simplement d'arriver. Votre graphique devient silencieusement obsolète.

Le correctif habituel consiste à tenir votre propre liste d'abonnements et à la rejouer depuis OnConnect, ce qui implique de mémoriser chaque symbole, chaque canal et chaque flux demandé, et de penser à mettre cette liste à jour chaque fois que vous vous abonnez ou vous désabonnez ailleurs dans le code. C'est de la comptabilité qui n'a rien à voir avec votre stratégie.

Activer le réabonnement automatique

Les clients d'API savent déjà à quoi vous êtes abonné, puisque vous vous êtes abonné à travers eux. Dans 2026.7 ils peuvent conserver cette liste et la rejouer eux-mêmes après une reconnexion. C'est un unique booléen sur l'objet d'options de la plateforme, nommé Resubscribe.

Voici la version faite à la main que la plupart des applications de trading ont aujourd'hui, et ce qui la remplace :

uses
  sgcWebSocket, sgcWebSocket_API_Binance;

// Before: keep your own list and replay it on every reconnect.
procedure TForm1.OnBinanceConnect(Connection: TsgcWSConnection);
begin
  sgcWSAPI_Binance1.SubscribeTrades('btcusdt');
  sgcWSAPI_Binance1.SubscribeTicker('btcusdt');
  sgcWSAPI_Binance1.SubscribeTrades('ethusdt');
  // ... and every other symbol you had open, in the right order.
end;

// After: the API client replays them for you.
sgcWSAPI_Binance1.Binance.Resubscribe := True;

Avec Resubscribe activé, le client enregistre chaque abonnement au moment où vous le faites, et une fois que le WatchDog a rétabli le socket, il les renvoie sur la nouvelle session. Le désabonnement supprime l'entrée, donc un flux que vous avez délibérément fermé ne ressuscite pas à la prochaine reconnexion.

Cela va de pair avec le WatchDog plutôt que de le remplacer. Le WatchDog rétablit le transport, Resubscribe rétablit la session par-dessus :

uses
  sgcWebSocket, sgcWebSocket_API_Kraken;

begin
  sgcWebSocketClient1.WatchDog.Enabled := True;
  sgcWebSocketClient1.WatchDog.Timeout := 5;   // retry the socket every 5 seconds

  sgcWSAPI_Kraken1.Client := sgcWebSocketClient1;
  sgcWSAPI_Kraken1.Kraken.Resubscribe := True; // and restore the streams on top

  sgcWebSocketClient1.Active := True;
  sgcWSAPI_Kraken1.SubscribeTrade(['XBT/USD', 'ETH/USD']);
end;

La valeur par défaut est False. Les applications existantes qui se réabonnent déjà à la main continuent de fonctionner exactement comme avant, sans abonnements en double, jusqu'à ce que vous supprimiez votre propre code et activiez le drapeau.

Quelles plateformes

Resubscribe se trouve sur l'objet d'options de chaque client de plateforme. Il est disponible sur Binance, Bitfinex, Bitget, BitMEX, Bitstamp, Bybit, CEX, CEX Plus, Coinbase, Crypto.com, Deribit, Gate.io, Huobi, Kraken, KuCoin, MEXC et OKX, ainsi que sur le flux de streaming XTB basé sur une session. La propriété s'écrit toujours de la même façon, donc la ligne se lit Coinbase.Resubscribe, Bybit.Resubscribe, OKX.Resubscribe et ainsi de suite, selon le composant que vous avez déposé sur la fiche.

Le client Lightstreamer, utilisé par IG et d'autres courtiers, fait la même chose en interne. Après une reliaison de session, le serveur n'a aucune trace des abonnements précédents, donc le client les rejoue depuis sa collection locale sans que vous ayez à le demander.

Les limites de débit, vues du côté client

L'autre moitié d'une application de trading, c'est le côté REST : passer un ordre, annuler un ordre, charger les soldes, charger la liste des symboles. Chaque plateforme publie un budget de requêtes pour ces points de terminaison, généralement un nombre de requêtes ou un poids par minute et par IP ou par clé. Dépassez-le et vous recevez un 429, et si vous continuez à le dépasser vous récoltez un bannissement temporaire, ce qui est une bien pire journée.

2026.7 ajoute un limiteur de débit côté client à TsgcHTTPAPI_client, de sorte que tous les clients REST prêts à l'emploi en héritent. C'est une fenêtre glissante : au plus MaxRequests requêtes dans toute fenêtre IntervalMs. Vous le configurez à partir des règles publiées par la plateforme, car la limite de la plateforme est la seule qui compte :

uses
  sgcHTTP_API, sgcHTTP_API_Binance;

var
  oBinance: TsgcHTTP_API_Binance_Rest;
begin
  oBinance := TsgcHTTP_API_Binance_Rest.Create(nil);
  try
    oBinance.RateLimit.Enabled     := True;
    oBinance.RateLimit.IntervalMs  := 60000;   // one minute window
    oBinance.RateLimit.MaxRequests := 1000;    // stay under the published budget
    oBinance.RateLimit.Behavior    := rlbWait; // default

    // Every request through this component now takes a slot first.
    oBinance.GetAccountInformation;
  finally
    oBinance.Free;
  end;
end;

La manière classique de se faire limiter, c'est la rafale au démarrage. L'application se lance, et elle part dans tous les sens pour charger la liste des symboles, les soldes, les ordres ouverts et les dernières bougies de quarante instruments, le tout dans la première seconde. Rien de déraisonnable là-dedans, et la plateforme compte quand même quarante requêtes en une seconde. Le limiteur lisse exactement ce profil de trafic sans que vous ayez à parsemer votre code d'initialisation d'appels à Sleep.

Le limiteur est créé de manière paresseuse. Si vous ne touchez jamais à RateLimit, aucun objet n'est alloué et le chemin de requête est octet pour octet celui d'avant, donc il n'y a rien à payer quand vous ne l'utilisez pas.

Attendre ou refuser

Lorsque le budget de la fenêtre courante est épuisé, c'est à vous de choisir ce qui arrive à l'appel suivant. C'est Behavior, et c'est une véritable décision plutôt qu'un bouton de réglage.

rlbWait, la valeur par défaut, bloque l'appel jusqu'à ce qu'un créneau se libère, puis l'envoie. C'est ce que vous voulez dans un worker d'arrière-plan qui charge de l'historique ou réconcilie des positions. Le travail prend un peu plus de temps et il aboutit entièrement.

rlbReject lève EsgcHTTPRateLimit immédiatement et n'envoie rien. C'est ce que vous voulez quand une requête tardive est pire que pas de requête du tout. Un ordre qui arrive trois secondes après que vous avez décidé de l'envoyer peut être un ordre dont vous ne voulez plus, et le lancer dans un marché en mouvement est pire qu'un échec bruyant :

uses
  SysUtils, sgcHTTP_API, sgcHTTP_API_Binance;

begin
  oBinance.RateLimit.Enabled     := True;
  oBinance.RateLimit.IntervalMs  := 1000;
  oBinance.RateLimit.MaxRequests := 10;
  oBinance.RateLimit.Behavior    := rlbReject;

  try
    oBinance.NewOrder('BTCUSDT', 'BUY', 'LIMIT', ...);
  except
    on E: EsgcHTTPRateLimit do
      // Budget exhausted. Drop the order rather than send it stale.
      LogWarning('rate limit hit, order not sent: ' + E.Message);
  end;
end;

Une configuration courante consiste à utiliser les deux, avec deux composants : rlbWait sur le composant qui fait le chargement en masse, et rlbReject sur le composant qui passe les ordres, chacun avec son propre budget.

Ce n'est pas le limiteur de débit côté serveur

Cela vaut la peine d'être explicite, car les noms sont proches. sgcWebSockets 2026.5 a livré TsgcWSRateLimiter, qui est un limiteur côté serveur : il protège votre serveur de vos clients, en plafonnant ce qu'une connexion entrante est autorisée à vous envoyer. Celui de cet article pointe dans l'autre direction. C'est un limiteur côté client qui vous protège des limites de quelqu'un d'autre, en plafonnant ce que votre application envoie vers une plateforme. Ils sont indépendants, et une application qui est à la fois un serveur et un consommateur de plateforme utilisera volontiers les deux.

Pas seulement la crypto

RateLimit vit sur le client HTTP API de base, donc il est hérité par chaque client REST prêt à l'emploi de la bibliothèque, pas seulement par les plateformes d'échange. Les clients AI ont des limites de requêtes exactement du même genre, donc OpenAI, Anthropic et Gemini en bénéficient, tout comme Stripe et le reste des intégrations d'API. La propriété se trouve au même endroit avec les mêmes quatre réglages :

uses
  sgcHTTP_API, sgcHTTP_API_OpenAI;

begin
  oOpenAI.RateLimit.Enabled     := True;
  oOpenAI.RateLimit.IntervalMs  := 60000;
  oOpenAI.RateLimit.MaxRequests := 500;    // your tier's requests per minute
  oOpenAI.RateLimit.Behavior    := rlbWait;
end;

Si votre compte est sur un palier avec un plafond bas de requêtes par minute, c'est le moyen le moins coûteux d'empêcher un traitement par lots parallèle de le faire sauter.

Disponibilité

Le réabonnement automatique et le limiteur de débit côté client sont disponibles dans sgcWebSockets 2026.7 pour Delphi 7 à 13 et C++Builder, sur Win32/Win64, Linux64, macOS, Android et iOS. Les deux sont désactivés par défaut, donc la mise à jour se fait sans rien changer.

Les clients disposant d'un abonnement actif peuvent télécharger la nouvelle version depuis l'espace client. Les utilisateurs de la version d'essai peuvent récupérer le programme d'installation mis à jour sur esegece.com/products/websockets/download.

Des questions, des remarques ou besoin d'aide pour intégrer cela dans votre application de trading ? Contactez-nous, vous obtiendrez une réponse des personnes qui ont écrit le code.