Enviar e receber mensagens¶
Introdução ¶
Este artigo serve como uma introdução à utilização da API FIX para qualquer pessoa interessada em interagir com o cServer da Spotware utilizando FIX.
Neste artigo, utilizaremos um exemplo em C# para descrever em detalhe os princípios de como construir uma mensagem FIX, enviá-la para o servidor e receber a resposta. Este exemplo não é, de forma alguma, uma aplicação à prova de balas e foi mantido o mais simples possível para permitir que os programadores compreendam facilmente o conceito de utilização de mensagens da API FIX.
Para estabelecer e manter uma comunicação adequada com o servidor e um tratamento adequado das respostas, é necessária funcionalidade adicional, que foi omitida por uma questão de simplicidade e clareza. Abordaremos estes assuntos em artigos futuros.
Exemplo de código ¶
Pode encontrar o exemplo de código discutido neste artigo no nosso repositório GitHub
Visão geral da comunicação FIX ¶
Uma mensagem FIX é apenas uma string composta por conjuntos de etiquetas numéricas e valores separados por uma barra vertical (|). Cada etiqueta representa um campo diferente para o qual é permitido um determinado conjunto de valores. Abaixo, pode ver uma mensagem FIX de exemplo que solicita autenticação ao servidor.
8=FIX.4.4|9=126|35=A|49=theBroker.12345|56=CSERVER|34=1|52=20170117- 08:03:04|57=TRADE|50=any_string|98=0|108=30|141=Y|553=12345|554=passw0rd!|10=131|
Como pode ver, o padrão repetível encontrado em cada mensagem FIX é:
Tag=Value|Tag=Value|Tag=Value|...
Dependendo do objetivo de cada mensagem, é necessário um conjunto diferente de etiquetas e valores de cada vez. As etiquetas e valores necessários para cada mensagem são descritos em detalhe nas Regras de Envolvimento do motor FIX do cTrader (verifique sempre as regras de envolvimento mais recentes).
De forma semelhante, as respostas são enviadas de volta pelo servidor. Abaixo, pode ver a resposta do servidor para a mensagem acima.
8=FIX.4.4|9=106|35=A|34=1|49=CSERVER|50=TRADE|52=20170117- 08:03:04.509|56=theBroker.12345|57=any_string|98=0|108=30|141=Y|10=066|
As etapas envolvidas no processo de comunicação com um servidor FIX são as seguintes:
-
Construir uma mensagem FIX
-
Transmitir uma mensagem FIX
-
Receber uma mensagem FIX
-
Analisar uma mensagem FIX
Uma mensagem FIX em bruto não é um formato muito legível, uma vez que foi concebida tendo em mente a eficiência e não a compreensibilidade. Portanto, para cada aplicação de software, haverá sempre um processo de tradução das informações fornecidas para a respetiva mensagem FIX.
Na nossa aplicação de exemplo em C#, criámos uma classe para lidar com a construção de mensagens, bem como funções para criar mensagens FIX com base nas informações relevantes.
Depois de as mensagens terem sido construídas, são transmitidas entre um servidor e um cliente através da Internet por meio de sockets de rede. Quando as mensagens são recebidas, precisam de ser analisadas para serem apresentadas num formato legível.
Neste artigo, abordaremos o processo de construção, transmissão e receção da resposta. Trataremos da análise num artigo futuro.
Construir uma mensagem FIX ¶
Estrutura da mensagem ¶
Na nossa aplicação de exemplo, criámos uma classe responsável por criar mensagens FIX. A classe chama-se MessageConstructor e pode ser encontrada no projeto FIX API Library.
O MessageConstructor é inicializado com os seguintes parâmetros:
-
Host(*)– o endereço onde o nosso cServer está localizado. -
Username(*)– o número da conta -
Password(*)– a palavra-passe -
SenderCompID(*)– é fornecido no formulário da API FIX do cTrader. Está no formato -
SenderSubID*– é a segunda parte do SenderCompID -
TargetCompID(*)– é fornecido no formulário da API FIX do cTrader (geralmente é cServer)
Pode encontrar estas informações no seu formulário da API FIX do cTrader.
Depois de termos inicializado um MessageConstructor, estamos prontos para construir mensagens da API FIX.
Todas as mensagens são construídas de maneira semelhante. Abaixo, há um exemplo de código de construção de uma mensagem de Logon.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | |
Pode ver que primeiro construímos a parte do corpo, depois passamo-la para a função de cabeçalho e, por último, passamos ambas as partes para a função de rodapé. Estas 3 partes são detalhadas abaixo.
O processo de construção da mensagem é apenas a adição das etiquetas, valores e separadores necessários numa string.
Corpo ¶
Primeiro, começaremos por descrever a construção do corpo, uma vez que o corpo da mensagem precisa de ser criado primeiro. Podemos ver um exemplo acima (criando a mensagem de Logon).
Começamos por inicializar uma classe StringBuilder e anexamos as etiquetas uma a uma com base nas entradas da função. Com base no tipo de mensagem, o corpo deve ser composto por diferentes conjuntos de etiquetas, algumas delas sendo obrigatórias e outras opcionais.
Pode encontrar a estrutura de cada mensagem nas nossas Regras de Envolvimento (/FIX).
Em seguida, criamos um cabeçalho para uma mensagem de Logon e anexamos a ele o corpo da mensagem. Finalmente, usando a string headerAndBody, geramos o rodapé. A seguir, veremos como construímos um cabeçalho e um rodapé.
Cabeçalho ¶
O cabeçalho é a primeira parte da mensagem FIX e é composto pelos seguintes campos (iguais para todas as mensagens):
BeginString– a string de início define a versão do protocolo FIX e, no nosso caso, é fixa para FIX4.4.BodyLength– o comprimento do corpo indica o comprimento da mensagem em caracteres, excluindo os camposBeginString,BodyLengthe rodapé.MsgType– neste campo, definimos o tipo de mensagem, para que o recetor saiba como analisar o corpo.SenderCompID– aqui definimos oSenderCompID.TargetCompID– este é o destino da nossa mensagem. No nosso caso, será sempre cServer.SenderSubID– o login do trader.MsgSeqNum– este é o número de sequência da mensagem. Precisa de ser aumentado para cada mensagem enviada na mesma sessão.Sending Time– a hora de transmissão da mensagem.
Abaixo, pode ver a função ConstructHeader, responsável por construir os cabeçalhos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | |
Rodapé ¶
O rodapé é apenas uma etiqueta contendo a soma de verificação do resto da mensagem.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
Mensagens do sistema ¶
O nosso exemplo contém funções que retornam as seguintes mensagens do sistema:
- Heartbeat:
MessageConstructor.HeartbeatMessage() - Pedido de teste:
MessageConstructor.TestRequestMessage() - Logon:
MessageConstructor.LogonMessage() - Logout:
MessageConstructor.LogoutMessage() - Pedido de reenvio:
MessageConstructor.ResendMessage() - Rejeitar:
MessageConstructor.RejectMessage() - Redefinição de sequência:
MessageConstructor.SequenceResetMessage()
Mensagens de aplicação ¶
O nosso exemplo contém funções que retornam as seguintes mensagens do sistema:
- Pedido de dados de mercado:
MessageConstructor.HeartbeatMessage() - Instantâneo de dados de mercado/atualização completa:
MessageConstructor.MarketDataSnapshotMessage() - Atualização incremental de dados de mercado:
MessageConstructor.MarketDataIncrementalRefreshMessage() - Nova ordem única:
MessageConstructor.NewOrderSingleMessage() - Pedido de estado da ordem:
MessageConstructor.OrderStatusRequest() - Relatório de execução:
MessageConstructor.ExecutionReport() - Rejeição de mensagem de negócio:
MessageConstructor.BusinessMessageReject() - Pedido de posições:
MessageConstructor.RequestForPositions() - Relatório de posição:
MessageConstructor.PositionReport()
Enviar uma mensagem e receber uma resposta ¶
Para enviar uma mensagem FIX para o cServer, primeiro precisa de estabelecer uma ligação com o servidor. Pode fazer isso criando um TcpClient. No nosso caso, criamos dois clientes, uma vez que as mensagens de cotação de preços e as mensagens de negociação são tratadas por portas diferentes no servidor.
Em seguida, precisamos de obter os dois fluxos nos quais as mensagens serão enviadas. Este processo ocorre no construtor do formulário, como mostrado abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
No construtor, também inicializamos uma classe MessageConstructor que será usada para gerar as mensagens.
Em seguida, para enviar as mensagens, criámos duas funções diferentes, SendPriceMessage() e SendTradeMessage(). Cada uma recebe a mensagem FIX como entrada e depois chama a função SendMessage() com a mensagem e o respetivo fluxo como entrada.
A função SendMessage() funciona da seguinte forma:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
As etapas detalhadas são as seguintes:
- Codificar a mensagem para uma matriz de bytes.
- Escrever a matriz de bytes no fluxo.
- Ler a resposta do fluxo.
- Aumentar o número de sequência da mensagem.
- Codificar a mensagem numa string.
A função deve retornar a mensagem FIX enviada pelo servidor.
Como pode supor, não pode mostrar uma mensagem FIX em bruto ao utilizador, por isso deve ser desenvolvida uma etapa adicional de análise da mensagem recebida.
Conclusão ¶
Esta aplicação é uma breve demonstração de como comunicar com o cServer usando mensagens FIX. É apenas um exemplo que ilustra os conceitos do Protocolo FIX e não é, de forma alguma, um motor FIX completo. Se quiser evitar construir o seu próprio motor FIX, pode considerar usar um dos motores FIX de terceiros disponíveis.
Nota
Este artigo está atualizado a partir de 03/02/2017 e foi desenvolvido tendo em consideração o motor FIX do cTrader, Regras de Envolvimento v2.9.1.