Die meisten Kryptowährungsbörsen unterstützen das Senden von Marktdaten über WebSocket, und einige Börsen unterstützen auch das Aktualisieren von Kontoinformationen über WebSocket. Im Vergleich zu REST API hat WebSocket im Allgemeinen eine geringere Latenzzeit, eine höhere Frequenz und unterliegt nicht den Rest API-Grenzwerten der Plattform. Es hat jedoch den Nachteil potenzieller Unterbrechungen und einer weniger intuitiven Handhabung.
Dieser Artikel wird vor allem die Verwendung der Dial-Funktion vorstellen, die in der FMZ Quant-Plattform mit der JavaScript-Sprache eingekapselt ist. Die spezifischen Anweisungen und Parameter finden Sie in der Dokumentation, indem Sie nach
Eine direkte Verbindung ist in der Regel ausreichend, wie zum Beispiel eine Münzsicherheit:
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
Wenn die zurückgegebenen Daten in komprimiertem Format sind, muss dies während der Verbindung angegeben werden.
var client = Dial("wss://real.okex.com:10441/websocket?compress=true|compress=gzip_raw&mode=recv")
Die Dial-Funktion unterstützt die Wiederverbindung, die von der zugrunde liegenden Go-Sprache verwaltet wird. Sie wird automatisch wieder verbunden, wenn eine Verbindung erkannt wird, dass sie getrennt wird. Für Fälle, in denen die Anforderungsdaten bereits in der URL enthalten sind, wie das vorherige Beispiel mit Binance, ist sie sehr praktisch und empfehlenswert. Für Fälle, in denen das Senden von Abonnementnachrichten erforderlich ist, empfiehlt es sich jedoch, den Wiederverbindungsmechanismus manuell zu pflegen.
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr|reconnect=true")
Abonnieren Sie wss Nachrichten, einige Börsen haben Anfragen in der URL, und es gibt auch Kanäle, an die Sie Ihre eigenen Abonnements senden müssen, wie Coinbase:
client = Dial("wss://ws-feed.pro.coinbase.com", 60)
client.write('{"type": "subscribe","product_ids": ["BTC-USD"],"channels": ["ticker","heartbeat"]}')
Im Allgemeinen kann es kontinuierlich in einer unendlichen Schleife gelesen werden.
function main() {
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr");
while (true) {
var msg = client.read()
var data = JSON.parse(msg) // Parse json strings into quotable objects
// Process data
}
}
Die Geschwindigkeit des WSS-Datenpushes ist sehr schnell. Die Unterschicht von Golang speichert alle Daten in der Warteschlange und wenn der Programmruf gelesen wird, werden die Daten wiedergegeben. Allerdings verursachen Operationen wie das Platzieren einer Bestellung auf dem Bot Verzögerungen, was zu einer Anhäufung von Daten führen kann. Für Informationen wie Handelsausführungspush, Konto-Push und Tiefeninterpolationspush benötigen wir die Historiendaten. Für Marktdaten kümmern wir uns in den meisten Fällen nur um die neuesten Daten, nicht um Historiendaten.
Wenn read() keine Parameter hinzufügt, wird es die ältesten Daten zurückgeben und bis zur Rückgabe blockieren, wenn keine Daten vorhanden sind. Wenn Sie die neuesten Daten möchten, können Sie client.read(-2) verwenden, um die neuesten Daten sofort zurückzugeben, aber wenn keine Daten vorhanden sind, wird es null zurückgeben, was vor der Referenz beurteilt werden muss.
Je nachdem, wie man mit den alten zwischengespeicherten Daten umgeht und ob sie blockiert werden, wenn keine Daten vorhanden sind, hat
In diesem Fall ist es offensichtlich, dass die einfache Verwendung von
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) // Parameter -1 represents no data and return null immediately; it will not occur that being blocked before there is data to be returned
var msgCoinbase = coinbase.read(-1)
if(msgBinance){
// at this time, Binance has data to return
}
if(msgCoinbase){
// at this time, coinbase has data to return
}
Sleep(1) // Sleep for 1 millisecond
}
}
Dieser Teil der Verarbeitung ist problematischer, da die Push-Daten unterbrochen werden können oder die Push-Verzögerung extrem lang ist. Auch wenn der Herzschlag empfangen werden kann, bedeutet dies nicht, dass die Daten immer noch gedrückt werden. Sie können ein Ereignisintervall festlegen; wenn nach dem Intervall kein Update empfangen wird, verbinden Sie sich erneut; es ist am besten, die Ergebnisse, die von
Für die Push-Daten verwendet wurde, wird das Programm natürlich als Ereignis ausgelöst geschrieben werden; achten Sie auf die Häufigkeit der Push-Daten, weil Hochfrequenz-Anfragen führen zu blockiert werden; im Allgemeinen können Sie schreiben:
var tradeTime = Date.now()
var accountTime = Date.now()
function trade(data){
if(Date.now() - tradeTime > 2000){//Here it limits only one trade in 2 seconds
tradeTime = Date.now()
// Trading logic
}
}
function GetAccount(){
if(Date.now() - accountTime > 5000){//Here it limits GetAccount only once in 5 seconds
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)
}
}
Die Verbindungsmethode, die Datenübertragungsmethode, der abonnierte Inhalt und das Datenformat des Websockets auf jeder Plattform sind oft unterschiedlich, so dass die Plattform sie nicht einkapselt und die Dial-Funktion verwenden muss, um sich selbst zu verbinden.
PS: Obwohl einige Plattformen keine Websocket-Zitate anbieten, werden Sie bei der Anmeldung auf der Website feststellen, dass sie alle den Websocket-Push verwenden. Nach der Recherche werden Sie feststellen, dass einige Abonnementformate und Rückgabeformate verschlüsselt zu sein scheinen, was durch Entschlüsselung und Dekomprimierung mit base64 zu sehen ist.