Ogni applicazione che dialoga con un exchange crypto finisce per scrivere gli stessi due pezzi di impianto. Il primo ripristina le sottoscrizioni ai dati di mercato dopo che il socket è caduto. Il secondo rallenta le chiamate REST perché l'exchange non ti limiti. Nessuno dei due è codice interessante, entrambi sono facili da sbagliare in modo sottile, ed entrambi finora sono stati lasciati all'applicazione.
sgcWebSockets 2026.7 li integra nella libreria. I client API degli exchange possono rieseguire le proprie sottoscrizioni dopo una riconnessione, e ogni client REST già pronto ora ha un rate limiter lato client che limita quante richieste invii in una finestra temporale. Entrambi sono opzionali e disattivati per impostazione predefinita, quindi l'aggiornamento non cambia nulla finché non li attivi.
La riconnessione che ti lascia senza sottoscrizioni
Il WatchDog è sempre stato bravo a far tornare su la connessione. Si stacca un cavo, un proxy va in timeout, l'exchange riavvia un gateway, e qualche secondo dopo il client è di nuovo connesso. Quella parte funziona.
Quello che non torna sono le tue sottoscrizioni. L'exchange non ne ha memoria. Un nuovo socket è una sessione vuota, quindi gli stream di trade e di order book che avevi richiesto sul vecchio socket semplicemente non esistono più. Il sintomo è insidioso perché nulla sembra rotto: il client segnala Connected, non viene sollevato alcun errore, e gli eventi con i messaggi smettono semplicemente di arrivare. Il tuo grafico si ferma in silenzio.
La soluzione abituale è tenere una tua lista di sottoscrizioni e rieseguirla da OnConnect, il che significa ricordare ogni simbolo, ogni canale e ogni stream che hai richiesto, e ricordarsi di aggiornare quella lista ogni volta che ti iscrivi o ti disiscrivi da qualche altra parte nel codice. È contabilità che non ha nulla a che vedere con la tua strategia.
Attivare la risottoscrizione automatica
I client API sanno già a cosa ti sei iscritto, perché ti sei iscritto tramite loro. Nella 2026.7 possono conservare quella lista e rieseguirla da soli dopo una riconnessione. È un singolo Boolean sull'oggetto delle opzioni dell'exchange, chiamato Resubscribe.
Ecco la versione fatta a mano che oggi hanno quasi tutte le applicazioni di trading, e quello che la sostituisce:
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;
Con Resubscribe abilitato, il client registra ogni sottoscrizione mentre la effettui, e dopo che il WatchDog ha riportato su il socket le invia di nuovo sulla nuova sessione. La disiscrizione rimuove la voce, quindi uno stream che hai chiuso deliberatamente non risorge dopo la riconnessione successiva.
Si accompagna al WatchDog, non lo sostituisce. Il WatchDog ripristina il trasporto, Resubscribe ripristina la sessione che ci sta sopra:
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;
Il valore predefinito è False. Le applicazioni esistenti che già si risottoscrivono a mano continuano a funzionare esattamente come prima, senza sottoscrizioni duplicate, finché non cancelli il tuo codice e attivi il flag.
Quali exchange
Resubscribe si trova sull'oggetto delle opzioni di ogni client di exchange. È disponibile su Binance, Bitfinex, Bitget, BitMEX, Bitstamp, Bybit, CEX, CEX Plus, Coinbase, Crypto.com, Deribit, Gate.io, Huobi, Kraken, KuCoin, MEXC e OKX, e sul feed di streaming XTB basato su sessione. La proprietà si scrive sempre allo stesso modo, quindi la riga diventa Coinbase.Resubscribe, Bybit.Resubscribe, OKX.Resubscribe e così via, a seconda di quale componente hai messo sulla form.
Il client Lightstreamer, usato da IG e da altri broker, fa la stessa cosa internamente. Dopo un rebind della sessione il server non ha traccia delle sottoscrizioni precedenti, quindi il client le riesegue dalla sua collezione locale senza che tu debba chiederlo.
Rate limit, dal lato client
L'altra metà di un'applicazione di trading è il lato REST: inserire un ordine, cancellare un ordine, caricare i saldi, caricare l'elenco dei simboli. Ogni exchange pubblica un budget di richieste per quegli endpoint, di solito un numero di richieste o un peso al minuto per IP o per chiave. Se lo superi ricevi un 429, e se continui a superarlo ti becchi un ban temporaneo, che è una giornata decisamente peggiore.
La 2026.7 aggiunge un rate limiter lato client a TsgcHTTPAPI_client, quindi ogni client REST già pronto lo eredita. È una finestra scorrevole: al massimo MaxRequests richieste in una qualsiasi finestra di IntervalMs. Lo configuri in base alle regole pubblicate dall'exchange, perché il limite dell'exchange è l'unico che conta:
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;
Il modo classico per farsi limitare è la raffica all'avvio. L'applicazione parte e si dirama per caricare l'elenco dei simboli, i saldi, gli ordini aperti e le ultime candele per quaranta strumenti, tutto nel primo secondo. Non c'è nulla di irragionevole in questo, e l'exchange lo conta comunque come quaranta richieste in un secondo. Il limiter appiana esattamente quella forma di traffico senza che tu debba disseminare chiamate a Sleep nel codice di inizializzazione.
Il limiter viene creato in modo lazy. Se non tocchi mai RateLimit, non viene allocato alcun oggetto e il percorso della richiesta è byte per byte quello di prima, quindi non c'è nulla da pagare quando non lo usi.
Attendere o rifiutare
Quando il budget della finestra corrente è esaurito, puoi scegliere cosa succede alla chiamata successiva. Questo è Behavior, ed è una decisione vera più che una manopola di regolazione.
rlbWait, il valore predefinito, blocca la chiamata finché non si libera uno slot e poi la invia. È quello che vuoi in un worker in background che carica lo storico o riconcilia le posizioni. Il lavoro richiede un po' più di tempo e arriva comunque in fondo.
rlbReject solleva subito EsgcHTTPRateLimit e non invia nulla. È quello che vuoi quando una richiesta in ritardo è peggio di nessuna richiesta. Un ordine che arriva tre secondi dopo che hai deciso di inviarlo può essere un ordine che non vuoi più, e lanciarlo dentro un mercato in movimento è peggio che fallire in modo esplicito:
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;
Una configurazione comune li usa entrambi, con due componenti: rlbWait sul componente che fa il caricamento massivo e rlbReject sul componente che inserisce gli ordini, ognuno con il proprio budget.
Questo non è il rate limiter lato server
Vale la pena essere espliciti, perché i nomi si assomigliano. sgcWebSockets 2026.5 ha introdotto TsgcWSRateLimiter, che è un limiter lato server: protegge il tuo server dai tuoi client, limitando quanto una connessione in ingresso può inviarti. Quello di questo articolo punta nella direzione opposta. È un limiter lato client che protegge te dai limiti di qualcun altro, limitando quanto la tua applicazione invia verso un exchange. Sono indipendenti, e un'applicazione che è insieme un server e un consumatore di exchange userà tranquillamente entrambi.
Non solo crypto
RateLimit vive sul client HTTP API di base, quindi è ereditato da ogni client REST già pronto della libreria, non solo dagli exchange. I client AI hanno limiti di richieste esattamente dello stesso tipo, quindi lo ottengono OpenAI, Anthropic e Gemini, e così pure Stripe e le altre integrazioni API. La proprietà è nello stesso posto con le stesse quattro impostazioni:
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;
Se il tuo account è su un piano con un tetto basso di richieste al minuto, questo è il modo più economico per evitare che un batch parallelo lo faccia scattare.
Disponibilità
La risottoscrizione automatica e il rate limiter lato client sono disponibili in sgcWebSockets 2026.7 su Delphi da 7 a 13 e C++Builder, su Win32/Win64, Linux64, macOS, Android e iOS. Entrambi sono disattivati per impostazione predefinita, quindi l'aggiornamento è immediato.
I clienti con un abbonamento attivo possono scaricare la nuova build dall'area clienti. Chi usa la versione di prova può scaricare l'installer aggiornato su esegece.com/products/websockets/download.
Domande, commenti o aiuto per integrare tutto questo nella tua applicazione di trading? Contattaci, riceverai una risposta dalle persone che hanno scritto il codice.
