3
focar em
1444
Seguidores

Guia de uso do Websocket da plataforma quantitativa de moeda digital Inventor (explicação detalhada após a atualização da função de discagem)

Criado em: 2019-04-01 11:06:09, atualizado em: 2019-12-04 10:41:25
comments   5
hits   5811

Basicamente, todas as exchanges de moeda digital suportam o envio de websocket, e algumas exchanges suportam a atualização de informações de conta do websocket. Em comparação com a rest API, a websocket geralmente tem um atraso baixo, alta frequência, não é limitada pela frequência da rest API da plataforma, o inconveniente é que há problemas de interrupção e o processamento não é intuitivo. https://zhuanlan.zhihu.com/p/22693475

Este artigo irá abordar principalmente a plataforma de quantificação dos inventores do FMZ, usando o JavaScript, usando a função Dial embutida na plataforma para conectar, com especificações e parâmetros no documento, a busca no Dial, que foi atualizada várias vezes para implementar várias funções. Este artigo irá cobrir isso e abordar a estratégia de direção de eventos baseada no wss, bem como a questão de conectar várias exchanges.

Conexão websocket:

Em geral, a conexão é direta, como o envio de ticker de segurança de moeda:

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

Para que os dados retornados sejam em formato de compressão, é necessário especificar o formato de compressão na conexão, comprimir especifica o formato de compressão, o modo representa o envio de dados retornados que precisam ser comprimidos, como a conexão OKEX:

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

A função Dial suporta a reconexão, feita pela linguagem Go de nível inferior, a detecção da conexão desligada e a reconexão, é conveniente e recomendada para o conteúdo de dados solicitados já no url, como o exemplo de Binance recentemente. Para aqueles que precisam enviar mensagens por encomenda, o mecanismo de reconexão pode ser mantido por conta própria.

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

Para subscrever as mensagens do wss, algumas das exchanges pedem no url, e também há alguns canais que precisam enviar suas próprias assinaturas, como a coinbase:

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

2. websocket diz:

O código é o seguinte:

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 data push é muito rápido, o nível de base do Go vai guardar todos os dados na fila, quando o programa é chamado de leitura, e depois retornar. E a operação de encomenda do robô vai trazer atrasos, o que pode causar acumulação de dados. Para o envio de transações, o envio de contas, o envio de inserções de profundidade, etc., precisamos de dados históricos, para os dados atuais, a maioria das vezes só nos preocupamos com os mais recentes, não nos preocupamos com os dados históricos.

read() se não adicionar um parâmetro, retornará o dado mais antigo, bloqueado para retornar quando não há dados. Se você quiser dados mais recentes, você pode usar client.read(-2) para retornar os dados mais recentes imediatamente, mas retornará null quando não houver mais dados, precisando de julgamento e referência.

Dependendo de como tratar os dados antigos armazenados no cache, e se eles estão bloqueados quando não há dados, o read possui diferentes parâmetros, como o gráfico abaixo, que parece complicado, mas permite maior flexibilidade no programa. Guia de uso do Websocket da plataforma quantitativa de moeda digital Inventor (explicação detalhada após a atualização da função de discagem)

3. Conectar vários websockets de exchanges:

Para este tipo de situação, o procedimento não pode ser simplesmente usado, pois uma bolsa bloqueia a mensagem em espera, enquanto a outra bolsa não recebe a mensagem, mesmo que haja uma nova. O procedimento geral é:

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

4. Problemas de reconexão:

Esta parte do processamento é um pouco problemático, porque o envio de dados pode ser interrompido, ou o envio de atraso é muito alto, mesmo que possa receber o heartbeat não significa que os dados ainda estão sendo enviados, você pode configurar um intervalo de evento, se exceder o intervalo sem receber atualizações, re-conecte-se, e é melhor comparar o resultado com o rest retornado em um período de tempo para ver se os dados estão corretos. Para este caso especial, o envio de moeda pode ser configurado diretamente.

5. Um framework de programação geral que usa o websocket:

Uma vez que os dados de push já foram usados, o programa também deve ser escrito como um driver de eventos, observe que os dados de push são frequentes e não são bloqueados com muitas solicitações, geralmente pode ser escrito como:

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

6. Resumo:

O modo de conexão, o modo de envio de dados, o conteúdo de assinatura e o formato de dados de cada plataforma geralmente são diferentes, então a plataforma não é encapsulada e precisa se conectar automaticamente com a função Dial. Este artigo abrange basicamente alguns cuidados básicos.

PS. Algumas casas de câmbio não oferecem websocket, mas quando você acessa o site e usa a função de modelagem, você descobre que eles usam o websocket push. Se você pesquisar, você encontrará o formato de assinatura e o formato de retorno. Algumas parecem criptografadas e podem ser decodificadas com base64.