La plupart des plateformes d’échange de crypto-monnaie prennent en charge les envois de websocket, et certaines d’entre elles prennent en charge les mises à jour de compte de websocket. Comparé à l’API rest, websocket a généralement un faible temps de latence, une fréquence élevée, n’est pas limité par la fréquence de l’API rest de la plate-forme. https://zhuanlan.zhihu.com/p/22693475
Cet article traitera principalement de la plate-forme de quantification des inventeurs de FMZ, utilisant le langage JavaScript, la fonction Dial intégrée à la plate-forme pour la connexion, les spécifications et les paramètres sont dans la documentation, la recherche de Dial, la fonction Dial a été mise à jour plusieurs fois pour permettre diverses fonctionnalités, cet article couvrira cela, et présentera les stratégies d’événementialisation basées sur wss, ainsi que les problèmes de connexion multi-échanges.
Il existe des connexions directes, telles que la possibilité d’obtenir des tickers de sécurité:
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
Pour que les données retournées soient en format compressé, il faut que le format de compression soit spécifié lors de la connexion, compresser spécifie le format de compression, et le mode représente l’envoi de données retournées qui nécessite une compression, comme pour la connexion OKEX:
var client = Dial("wss://real.okex.com:10441/websocket?compress=true|compress=gzip_raw&mode=recv")
La fonction Dial prend en charge la reconnexion, réalisée par le langage Go sous-jacent, la reconnexion de la session de déconnexion détectée, est pratique et recommandée pour les contenus de données demandées déjà dans l’url, comme dans l’exemple de Binance. Pour ceux qui ont besoin d’envoyer des messages commandés, vous pouvez maintenir vous-même le mécanisme de reconnexion.
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr|reconnect=true")
Pour s’abonner aux nouvelles de wss, certaines bourses demandent des urls, et d’autres ont besoin de s’abonner à leurs propres chaînes, comme Coinbase:
client = Dial("wss://ws-feed.pro.coinbase.com", 60)
client.write('{"type": "subscribe","product_ids": ["BTC-USD"],"channels": ["ticker","heartbeat"]}')
Les codes suivants sont généralement lus en continu dans la boucle de mort:
function main() {
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr");
while (true) {
var msg = client.read()
var data = JSON.parse(msg) //把json字符串解析为可引用的object
// 处理data数据
}
}
wss est très rapide, Go cache toutes les données dans une queue, et les programmes comme read sont appelés, puis retournés. Les commandes des robots entraînent des retards, ce qui peut entraîner une accumulation de données. Pour le transfert de transactions, le transfert de comptes, le transfert de valeurs de profondeur, etc., nous avons besoin de données historiques. Pour les données de situation, nous ne nous soucions que des données les plus récentes, pas des données historiques.
read() renvoie les données les plus anciennes sans paramètres, et les obstrue jusqu’à ce qu’elles soient renvoyées sans données. Si vous voulez des données les plus récentes, vous pouvez utiliser client.read(-2) pour renvoyer immédiatement les données les plus récentes, mais renvoie null lorsqu’il n’y a plus de données, il faut juger et référencer.
Les paramètres de read varient en fonction de la manière dont les données anciennes sont traitées dans la cache et si elles sont bloquées en l’absence de données.

Il est évident qu’il n’est pas possible d’utiliser un simple read () dans ce cas, car un échange bloquerait les messages en attente, tandis qu’un autre échange ne recevrait pas de nouveaux messages même s’il y en avait. Le traitement général est le suivant:
function main() {
var binance = Dial("wss://stream.binance.com:9443/ws/!ticker@arr");
var coinbase = Dial("wss://ws-feed.pro.coinbase.com", 60)
coinbase.write('{"type": "subscribe","product_ids": ["BTC-USD"],"channels": ["ticker","heartbeat"]}')
while (true) {
var msgBinance = binance.read(-1) // 参数-1代表无数据立即返回null,不会阻塞到有数据返回
var msgCoinbase = coinbase.read(-1)
if(msgBinance){
// 此时币安有数据返回
}
if(msgCoinbase){
// 此时coinbase有数据返回
}
Sleep(1) // 可以休眠1ms
}
}
Cette partie du traitement est un peu gênante, car les données de poussée peuvent être interrompues, ou le retard de poussée est très élevé, même si la réception de heartbeat ne signifie pas que les données sont toujours en cours de poussée, vous pouvez définir un intervalle d’événement, si vous ne recevez pas de mises à jour après l’intervalle, vous pouvez vous reconnecter, et il est préférable de comparer les résultats avec le retour de rest après un certain temps pour voir si les données sont exactes.
Étant donné que les données de poussée sont déjà utilisées, les programmes doivent naturellement être écrits comme des événements, en tenant compte du fait que les données de poussée sont fréquentes et ne sont pas bloquées par trop de requêtes. On peut généralement écrire:
var tradeTime = Date.now()
var accountTime = Date.now()
function trade(data){
if(Date.now() - tradeTime > 2000){//这里即限制了2s内只交易一次
tradeTime = Date.now()
//交易逻辑
}
}
function GetAccount(){
if(Date.now() - accountTime > 5000){//这里即限制了5s内只获取账户一次
accountTime = Date.now()
return exchange.GetAccount()
}
}
function main() {
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr|reconnect=true");
while (true) {
var msg = client.read()
var data = JSON.parse(msg)
var account = GetAccount()
trade(data)
}
}
La façon dont les websockets de chaque plateforme sont connectés, les données envoyées, le contenu souscrit et le format de données sont souvent différents, de sorte que la plateforme n’est pas encapsulée et nécessite une connexion automatique à l’aide de la fonction Dial. Cet article couvre essentiellement quelques précautions de base.
PS. Certaines bourses n’offrent pas de websocket, mais si vous vous connectez à leur site, vous verrez qu’elles utilisent le websocket push, et que vous trouverez des formats de souscription et de retour. Certaines semblent avoir été cryptées et peuvent être décodées en base64.