Basicamente, todas as exchanges de moeda digital suportam o mercado de envio de websocket, e algumas exchanges suportam o websocket para atualizar as informações da conta. Em comparação com a rest API, o websocket geralmente possui um baixo atraso, alta frequência, não possui restrições de frequência da rest API da plataforma.https://zhuanlan.zhihu.com/p/22693475
Este artigo abordará principalmente a plataforma de quantificação do inventor da FMZ, o uso da linguagem JavaScript, a conexão com a função Dial embalada na plataforma, especificações e parâmetros em documentação, pesquisa de Dial, várias atualizações da função Dial para realizar várias funções, que serão cobertas neste artigo.
O que você pode fazer é fazer uma ligação direta para obter o ticker de segurança:
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
Para os dados de retorno que precisam ser comprimidos na conexão, compress especifica o formato de compressão, o modo representa o envio de dados de retorno que precisam ser comprimidos, como na conexão OKEX:
var client = Dial("wss://real.okex.com:10441/websocket?compress=true|compress=gzip_raw&mode=recv")
A função Dial suporta reconexão, feita pela linguagem Go subjacente, o que permite que as conexões detectadas sejam desligadas e reconectadas. É muito conveniente e recomendado para o conteúdo dos dados solicitados já estarem no url, como no exemplo de Binance.
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr|reconnect=true")
Subscrever mensagens do ws, algumas solicitações de trocas estão no url, e alguns canais exigem que você envie sua própria assinatura, como o Coinbase:
client = Dial("wss://ws-feed.pro.coinbase.com", 60)
client.write('{"type": "subscribe","product_ids": ["BTC-USD"],"channels": ["ticker","heartbeat"]}')
O código é geralmente lido continuamente durante o ciclo de morte:
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数据
}
}
Os dados do wss são muito rápidos, o fundo do Go retarda todos os dados na fila e, quando o programa chama read, retorna em seguida. As operações do robô, por exemplo, trazem um atraso, o que pode causar acumulação de dados. Para transações de transferência, transferências de contas, inserções de profundidade, etc., precisamos de dados históricos.
read ((() devolve os dados mais antigos se não forem adicionados, bloqueando-os para retornar quando não há dados. Se você quiser os dados mais recentes, pode usar o client.read (((-2) para retornar os dados mais recentes imediatamente, mas retornará null quando não houver mais dados.
Dependendo de como tratar os dados antigos armazenados no cache, e se eles ficam bloqueados quando não há dados, o read tem diferentes parâmetros, como o gráfico abaixo, o que parece complicado, mas torna o programa mais flexível.
Para essa situação, o procedimento obviamente não pode usar o simples read (), pois uma troca bloqueia a mensagem pendente, em que a outra troca não receberá a mensagem, mesmo que haja uma nova mensagem.
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
}
}
Esta parte é mais problemática, pois o envio de dados pode ser interrompido, ou o tempo de envio é muito alto, mesmo que não seja possível receber o coração, o que não significa que os dados ainda estejam sendo enviados, pode ser definido um intervalo de eventos, se exceder o intervalo não receber uma atualização, a reconexão é reiniciada, e é melhor comparar o resultado do retorno de tempo e rest para ver se os dados são precisos.
Como os dados de push já foram usados, os programas também devem ser escritos como event drivers, cuidando de impulsionar os dados com frequência, sem que muitos pedidos causem fechamento.
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)
}
}
O modo de conexão do websocket, o modo de envio de dados, o conteúdo subscrito e o formato de dados de cada exchange são muitas vezes diferentes, de modo que a plataforma não é encapsulada e precisa de uma conexão automática com a função Dial.
PS. Algumas casas de câmbio, embora não ofereçam mercado de websocket, na verdade utilizam funções de modulação para fazer o login do site. Se você pesquisar, verá que o formato de assinatura e o formato de retorno são utilizados.
xaifer48Depois de um tempo de execução da conexão wss, corre o json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) corre este erro, por favor, pergunte como lidar com isso?
O que é isso?Por que o contrato permanente do Binance foi ligado, a informação da conta mudou, e depois de um minuto, read voltou vazio?
xaifer48Recebido, obrigado.
Ervas daninhasPara resolver erros, imprimir a mensagem, fazer um erro é fácil.
QuantificaçãoO Bitcoin é um sistema de transferência de dados que permite que o usuário transfere informações de uma conta para outra, porque o Binance diz que as mensagens só são enviadas quando as informações da conta são alteradas.