O recurso está a ser carregado... Carregamento...

Um modelo de estratégia permite que você use o WebSocket Market sem problemas

Autora:FMZ~Lydia, Criado: 2024-10-30 14:23:04, Atualizado: 2024-11-05 17:44:35

img

Este é um modelo de mercado WebSocket oficialmente desenvolvido pela FMZ.https://www.fmz.com/strategy/470349

Por que precisamos do WebSocket?

Atualmente, a estratégia FMZ baseia-se principalmente no encapsulamento tradicional da API REST. Cada etapa do acesso à API requer que uma conexão de rede seja estabelecida e os dados do mercado são obtidos por meio de pesquisa.

No entanto, o protocolo REST tem um problema de atraso inerente. Quando vários pares de negociação e estratégias de troca múltiplos são necessários, o problema de atraso será ampliado. Embora a função Go da plataforma possa ser executada simultaneamente, o problema de atraso ainda existe, o que torna difícil atender às necessidades de negociação de estratégia de frequência relativamente alta. Além disso, se houver muitos pares de negociação e a frequência de votação for muito rápida, ele encontrará o limite de frequência de acesso da plataforma de negociação.

Atualmente, os servidores das exchanges também estão sob grande carga. Todos eles fornecem um protocolo WebSocket completo e o recomendam aos usuários da API. Em comparação com o protocolo REST, o WebSocket fornece um método de conexão bidirecional persistente, que permite que as exchanges empurrem dados para o cliente em tempo real, evitando solicitações e respostas frequentes, reduzindo assim muito a latência. Geralmente, se o atraso no acesso à API REST for de cerca de 20ms, o atraso no envio de dados através do WebSocket é de cerca de 2ms. Além disso, o link para o protocolo WebSocket não é limitado pela frequência de acesso à plataforma e é possível se inscrever em dezenas de pares de negociação ao mesmo tempo.

Introdução ao modelo de ticker do WebSocket

A plataforma FMZ Quant Trading suporta o protocolo WebSocket há muito tempo, e é relativamente conveniente para chamar, mas para usuários novatos, ainda é muito complicado lidar com múltiplas assinaturas, assinar vários tickers de troca e incorporá-los de forma eficiente e conveniente em todo o processo de estratégia. Este modelo público de aceleração de dados de ticker em tempo real do WebSocket resolve este problema. É muito fácil de usar e é totalmente compatível com a chamada de API encapsulada atual. Para a maioria das estratégias REST originais, você pode simplesmente modificá-las e usá-las diretamente para acelerar sua estratégia.

Características principais:

  • Apoio a várias bolsas: Esta estratégia suporta conexões WebSocket de várias exchanges, como Binance, OKX, Bybit, Bitget, etc. Os usuários podem seguir o método de embalagem deste modelo para suportar mais exchanges.
  • Assinaturas personalizáveis: Permite a subscrição de canais de mercado específicos (como profundidade, transacções, etc.) e o processamento eficiente dos dados recebidos para utilização imediata em estratégias de negociação.
  • Gestão avançada de erros: Mecanismo integrado de rastreamento de erros e de reconexão do WebSocket para garantir a confiabilidade e a continuidade do fluxo de dados.

Uma breve introdução ao princípio da aplicação

Observe que esta estratégia usa TypeScript. Se você está apenas familiarizado com JavaScript, pode parecer um pouco estranho. O TypeScript introduz um sistema de tipos e recursos de linguagem mais ricos baseados no JavaScript. Para aplicações como negociação quantitativa que precisam lidar com lógica complexa, o uso do TypeScript pode reduzir possíveis erros e melhorar a legibilidade e a manutenção do código. Portanto, recomenda-se aprendê-lo brevemente.

Além disso, a estratégia usa o mecanismo assíncrono da plataforma FMZ. O thread filho pode enviar mensagens para o thread principal através da função __threadPostMessage. Este método é assíncrono e é adequado para notificar o thread principal de atualizações de dados geradas no thread filho. O thread principal e o thread filho podem compartilhar dados através das funções __threadGetData e __threadSetData. Este método permite que os threads acessem e modifiquem estados compartilhados.

O principal princípio desta estratégia é conectar-se às principais bolsas de moeda digital através do WebSocket e receber dados de mercado (como informações de profundidade e informações de transação) em tempo real para fornecer suporte de dados para decisões quantitativas de negociação.

1. Configurações de conexão WebSocketA funçãosetupWebsocketé usado para inicializar uma conexão WebSocket e receber dados de mercado.main_exchanges, indicando a central para se conectar.

  • MyDial função: Criar uma conexão WebSocket, gravar o tempo de conexão e a saída do tempo de fechamento ao fechar a conexão.
  • updateSymbols função: Verifique regularmente se existem novos pedidos de subscrição e atualize a lista de pares de negociação atual conforme necessário.

2. Processamento de dadosO objetosupportsDefine as trocas suportadas e a sua função de processamento (comoBinanceA função de processamento de cada intercâmbio é responsável pela análise da mensagem recebida e pela extracção dos dados relevantes.

  • processMsg função: Processar mensagens de trocas, identificar diferentes tipos de dados (como atualizações de profundidade, transações, etc.) e formatá-los em um objeto de evento unificado.

3. Dados de subscriçãoEm cada ligação, o sistema subscreverá os canais de dados de mercado relevantes com base no par de negociação actual.

  • getFunction funçãoObtenha a função de processamento correspondente de acordo com o nome da troca.
  • this.wssPublic função: Iniciar a conexão WebSocket e começar a receber dados.

4. Gestão de fiosIniciar um tópico para cada troca, receber dados em tempo real e processar os dados através de funções de callback.

  • threadMarket funçãoRecepção de dados em um tópico filho, análise e armazenamento das últimas informações de profundidade e transação.

5. Reescrever o método de aquisição de dadosReescrever os métodos para obter informações de profundidade e de negociação para cada bolsa, dando prioridade ao retorno de dados atualizados em tempo real.

Como usar o modelo

  1. Inicialização: Utilização$.setupWebsocket()para inicializar a conexão WebSocket do exchange de destino.
  2. Subscrição: O sistema subscreverá automaticamente os canais relevantes (como profundidade, negociação, etc.) para os produtos que comercializa.
  3. Aquisição de dadosO Parlamento EuropeuGetDepth()eGetTrades()funções, a profundidade do mercado e registos de transações são devolvidos automaticamente usando dados WebSocket em tempo real.
  4. Gestão de erros: A estratégia inclui um mecanismo de rastreamento para registar erros de ligação e de dados, e tentativas de reconexão automática se a ligação for perdida.

Se a função EventLoop() for adicionada à estratégia, ela será alterada para um mecanismo de gatilho. Quando houver uma atualização de dados wss, ela será obtida automaticamente imediatamente, e espera se não houver dados mais recentes. É equivalente a uma função de sono inteligente. Claro, você também pode usar o sono diretamente.

function main() {
    $.setupWebsocket()
    while (true) {
        exchanges.map(e=>{
            Log(e.GetName(), e.GetDepth())
            Log(e.GetName(), e.GetTrades())
        })
        EventLoop(100) // trigger by websocket
    }
}

Consulte o meu guia anterior de estratégia de negociação de várias moedas:https://www.fmz.com/bbs-topic/10508, que pode ser modificado facilmente para suportar WebSocket:

function MakeOrder() {
    for (let i in Info.trade_symbols) {
        let symbol = Info.trade_symbols[i];
        let buy_price = exchange.GetDepth(symbol + '_USDT').Asks[0].Price;
        let buy_amount = 50 / buy_price;
        if (Info.position[symbol].value < 2000){
            Trade(symbol, "buy", buy_price, buy_amount, symbol);
        }
    }
}

function OnTick() {
    try {
        UpdatePosition();
        MakeOrder();
        UpdateStatus();
    } catch (error) {
        Log("loop error: " + error);
    }
}

function main() {
    $.setupWebsocket()
    InitInfo();
    while (true) {
        let loop_start_time = Date.now();
        if (Date.now() - Info.time.last_loop_time > Info.interval * 1000) {
            OnTick();
            Info.time.last_loop_time = Date.now();
            Info.time.loop_delay = Date.now() - loop_start_time;
        }
        Sleep(5);
    }
}

Mais.