FMZ Plataforma Quantitativa de Criptomoedas Guia de Uso do WebSocket (Explicação detalhada da função de discagem atualizada)

Autora:Lydia., Criado: 2023-07-13 14:03:32, Atualizado: 2024-01-03 21:05:36

img

FMZ Plataforma Quantitativa de Criptomoedas Guia de Uso do WebSocket (Explicação detalhada da função de discagem atualizada)

A maioria das casas de câmbio de criptomoedas suporta o envio de dados de mercado via WebSocket, e algumas casas de câmbio também suportam a atualização de informações de conta via WebSocket.

Este artigo introduz principalmente o uso da função Dial, que é encapsulada na plataforma FMZ Quant usando a linguagem JavaScript. As instruções e parâmetros específicos podem ser encontrados na documentação pesquisando Dial. A fim de alcançar várias funcionalidades, a função Dial passou por várias atualizações, que serão abordadas neste artigo. Além disso, também discutirá a estratégia baseada em eventos baseada no WebSocket Secure (wss) e a questão da conexão com várias exchanges.

Conexão Websocket:

Uma conexão direta é geralmente suficiente, como obter um ticker de segurança da moeda:

var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")

Quando os dados retornados estão em formato comprimido, eles precisam ser especificados durante a conexão. compress é usado para especificar o formato de compressão, e mode representa qual parte dos dados (envio ou retorno) precisa ser comprimido.

var client = Dial("wss://real.okex.com:10441/websocket?compress=true|compress=gzip_raw&mode=recv")

A função Dial suporta a reconexão, que é tratada pela linguagem Go subjacente. Ela se reconecta automaticamente quando uma conexão é detectada para ser desconectada. Para casos em que os dados de solicitação já estão incluídos no URL, como o exemplo anterior com o Binance, é muito conveniente e recomendável usar. No entanto, para casos em que o envio de mensagens de assinatura é necessário, recomenda-se manter o mecanismo de reconexão manualmente.

var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr|reconnect=true")

Subscrever para mensagens wss, algumas trocas têm pedidos no url, e há também canais que você precisa enviar suas próprias assinaturas para, tais como coinbase:

client = Dial("wss://ws-feed.pro.coinbase.com", 60)
client.write('{"type": "subscribe","product_ids": ["BTC-USD"],"channels": ["ticker","heartbeat"]}')

2. Websocket de leitura

Geralmente, pode ser lido continuamente em um loop infinito.

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 
    }
}

A velocidade de transferência de dados do wss é muito rápida. A camada inferior do Golang armazenará em cache todos os dados na fila e, quando o programa chamar, os dados serão devolvidos. No entanto, operações como colocar uma ordem no bot causarão atrasos, o que pode resultar no acúmulo de dados. Para informações como transferência de execução de negociação, transferência de conta e transferência de interpolação de profundidade, precisamos dos dados do histórico. Para os dados do mercado de cotações, na maioria dos casos, nos preocupamos apenas com os dados mais recentes, não com os dados do histórico.

Se read() não adicionar parâmetros, ele retornará os dados mais antigos e bloqueará até retornar quando não houver dados.

Dependendo de como lidar com os dados cacheados antigos e se ele é bloqueado quando não há dados, read tem parâmetros diferentes, como mostrado na tabela abaixo, que parece complicado, mas torna o programa mais flexível.

img

3. Conexão com várias plataformas por Websocket

Neste caso, é óbvio que simplesmente usar read() não funciona no programa, porque uma plataforma bloqueará mensagens em espera e outra plataforma não receberá mesmo se houver novas mensagens.

    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
        }
    }

4. Problemas de desconexão e reconexão

Esta parte do processamento é mais problemática, porque os dados de push podem ser interrompidos, ou o atraso de push é extremamente longo. Mesmo que o batimento cardíaco possa ser recebido, isso não significa que os dados ainda estejam sendo empurrados. Você pode definir um intervalo de evento; se nenhuma atualização for recebida após o intervalo, reconecte; é melhor comparar os resultados retornados por rest após um período de tempo, para ver se os dados são precisos. Para os casos especiais do Binance, você pode definir diretamente a reconexão automática.

5. Usando o Framework de Programa Geral do Websocket

Para os dados de push foram usados, o programa será naturalmente escrito como evento desencadeado; prestar atenção à frequência de dados de push, porque os pedidos de alta frequência levarão a ser bloqueado; geralmente você pode escrever:

    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)
        }
    }

6. Conclusão

O método de conexão, o método de transmissão de dados, o conteúdo assinado e o formato de dados do websocket em cada plataforma são muitas vezes diferentes, então a plataforma não o encapsula e precisa usar a função Dial para se conectar sozinha.

PS: Embora algumas plataformas não forneçam citações de websocket, na verdade, quando você entra no site para usar a função de depuração, você descobrirá que todos eles estão usando o websocket push.


Mais.