Enviar y recibir mensajes¶
Introducción ¶
Este artÃculo sirve como introducción al uso de la API FIX para cualquier persona interesada en interactuar con Spotware cServer utilizando FIX.
En este artÃculo, utilizaremos un ejemplo en C# para describir en detalle los principios de cómo construir un mensaje FIX, enviarlo al servidor y recibir la respuesta. Este ejemplo no es de ninguna manera una aplicación a prueba de balas y se mantuvo lo más simple posible para permitir a los programadores entender fácilmente el concepto de usar mensajes de API FIX.
Para establecer y mantener una comunicación adecuada con el servidor y un manejo apropiado de las respuestas, se requiere funcionalidad adicional, que se omitió en aras de la simplicidad y claridad. Trataremos estos temas en artÃculos futuros.
Ejemplo de código ¶
Puede encontrar el ejemplo de código discutido en este artÃculo en nuestro repositorio de GitHub
Descripción general de la comunicación FIX ¶
Un mensaje FIX es simplemente una cadena compuesta por conjuntos de etiquetas numéricas y valores separados por una barra vertical (|). Cada etiqueta representa un campo diferente para el cual se permite un cierto conjunto de valores. A continuación puede ver un ejemplo de mensaje FIX que solicita autenticación al 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 puede ver, el patrón repetible que se encuentra en cada mensaje FIX es:
Tag=Value|Tag=Value|Tag=Value|...
Dependiendo del propósito de cada mensaje, se requiere un conjunto diferente de etiquetas y valores cada vez. Las etiquetas y valores requeridos para cada mensaje se describen en detalle en las Reglas de Compromiso del motor FIX de cTrader (siempre verifique las últimas reglas de compromiso).
De manera similar, las respuestas son enviadas de vuelta desde el servidor. A continuación puede ver la respuesta del servidor para el mensaje anterior.
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|
Los pasos involucrados en el proceso de comunicación con un servidor FIX son los siguientes:
-
Construir un mensaje FIX
-
Transmitir un mensaje FIX
-
Recibir un mensaje FIX
-
Analizar un mensaje FIX
Un mensaje FIX sin procesar no es un formato muy legible ya que fue diseñado pensando en la eficiencia más que en la comprensibilidad. Por lo tanto, para cada aplicación de software siempre habrá un proceso de traducción de la información proporcionada al mensaje FIX respectivo.
En nuestra aplicación de muestra en C# hemos creado una clase para manejar la construcción de mensajes, asà como funciones para crear mensajes FIX basados en la información relevante.
Después de que los mensajes han sido construidos, se transmiten entre un servidor y un cliente a través de internet mediante sockets de red. Cuando se reciben los mensajes, necesitan ser analizados para ser presentados en un formato legible.
En este artÃculo cubriremos el proceso de construcción, transmisión y recepción de la respuesta. Trataremos el análisis en un artÃculo futuro.
Construir un mensaje FIX ¶
Estructura del mensaje ¶
En nuestra aplicación de muestra hemos creado una clase responsable de crear mensajes FIX. La clase se llama MessageConstructor y se puede encontrar en el proyecto de la biblioteca de API FIX.
El MessageConstructor se inicializa con los siguientes parámetros:
-
Host(*)– la dirección donde se encuentra nuestro cServer. -
Username(*)– el número de cuenta -
Password(*)– la contraseña -
SenderCompID(*)– se proporciona en el formulario de API FIX de cTrader. Está en el formato -
SenderSubID*– es la segunda parte de SenderCompID -
TargetCompID(*)– se proporciona en el formulario de API FIX de cTrader (generalmente es cServer)
Puede encontrar esta información en su formulario de API FIX de cTrader.
Después de haber inicializado un MessageConstructor estamos listos para construir mensajes de API FIX.
Todos los mensajes se construyen de manera similar. A continuación hay un ejemplo de código de construcción de un mensaje 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 | |
Puede ver que primero construimos la parte del cuerpo, luego la pasamos a la función de encabezado y por último pasamos ambas partes a la función de trailer. Estas 3 partes se detallan a continuación.
El proceso de construcción del mensaje es simplemente la adición de las etiquetas requeridas, valores y separadores en una cadena.
Cuerpo ¶
Primero comenzaremos describiendo la construcción del cuerpo, ya que el cuerpo del mensaje debe crearse primero. Podemos ver un ejemplo arriba (creando el mensaje de Logon).
Comenzamos inicializando una clase StringBuilder y agregamos las etiquetas una por una basándonos en las entradas de la función. Según el tipo de mensaje, el cuerpo debe estar compuesto por diferentes conjuntos de etiquetas, algunas de ellas siendo obligatorias y otras opcionales.
Puede encontrar la estructura de cada mensaje en nuestras Reglas de Compromiso (/FIX).
Luego creamos un encabezado para un mensaje de Logon y le agregamos el cuerpo del mensaje. Finalmente, usando la cadena headerAndBody generamos el trailer. A continuación, veremos cómo construimos un encabezado y un trailer.
Encabezado ¶
El encabezado es la primera parte del mensaje FIX y está compuesto por los siguientes campos (igual para todos los mensajes):
BeginString– la cadena de inicio define la versión del protocolo FIX y en nuestro caso está fijada en FIX4.4.BodyLength– la longitud del cuerpo indica la longitud del mensaje en caracteres, excluyendo los camposBeginString,BodyLengthy trailer.MsgType– en este campo definimos el tipo de mensaje, para que el receptor sepa cómo analizar el cuerpo.SenderCompID– aquà establecemos elSenderCompID.TargetCompID– este es el destino de nuestro mensaje. En nuestro caso, siempre será cServer.SenderSubID– el inicio de sesión del operador.MsgSeqNum– este es el número de secuencia del mensaje. Debe incrementarse para cada mensaje enviado en la misma sesión.Sending Time– la hora de transmisión del mensaje.
A continuación puede ver la función ConstructHeader, responsable de construir los encabezados.
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 | |
Trailer ¶
El trailer es solo una etiqueta que contiene la suma de comprobación del resto del mensaje.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
Mensajes del sistema ¶
Nuestra muestra contiene funciones que devuelven los siguientes mensajes del sistema:
- Latido:
MessageConstructor.HeartbeatMessage() - Solicitud de prueba:
MessageConstructor.TestRequestMessage() - Inicio de sesión:
MessageConstructor.LogonMessage() - Cierre de sesión:
MessageConstructor.LogoutMessage() - Solicitud de reenvÃo:
MessageConstructor.ResendMessage() - Rechazo:
MessageConstructor.RejectMessage() - Restablecimiento de secuencia:
MessageConstructor.SequenceResetMessage()
Mensajes de aplicación ¶
Nuestra muestra contiene funciones que devuelven los siguientes mensajes del sistema:
- Solicitud de datos de mercado:
MessageConstructor.HeartbeatMessage() - Instantánea de datos de mercado/actualización completa:
MessageConstructor.MarketDataSnapshotMessage() - Actualización incremental de datos de mercado:
MessageConstructor.MarketDataIncrementalRefreshMessage() - Nueva orden individual:
MessageConstructor.NewOrderSingleMessage() - Solicitud de estado de orden:
MessageConstructor.OrderStatusRequest() - Informe de ejecución:
MessageConstructor.ExecutionReport() - Rechazo de mensaje de negocio:
MessageConstructor.BusinessMessageReject() - Solicitud de posiciones:
MessageConstructor.RequestForPositions() - Informe de posición:
MessageConstructor.PositionReport()
Enviar un mensaje y recibir una respuesta ¶
Para enviar un mensaje FIX a cServer, primero debe establecer una conexión con el servidor. Puede hacer esto creando un TcpClient. En nuestro caso, creamos dos clientes, ya que los mensajes de cotización de precios y los mensajes de operaciones son manejados por diferentes puertos en el servidor.
Luego, necesitamos obtener los dos flujos en los que se enviarán los mensajes. Este proceso tiene lugar en el constructor del formulario como se muestra a continuación:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
En el constructor, también inicializamos una clase MessageConstructor que se utilizará para generar los mensajes.
A continuación, para enviar los mensajes, creamos dos funciones diferentes, SendPriceMessage() y SendTradeMessage(). Cada una toma el mensaje FIX como entrada y luego llama a la función SendMessage() con el mensaje y el flujo respectivo como entrada.
La función SendMessage() funciona de la siguiente manera:
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 | |
Los pasos detallados son los siguientes:
- Codificar el mensaje en una matriz de bytes.
- Escribir la matriz de bytes en el flujo.
- Leer la respuesta del flujo.
- Aumentar el número de secuencia del mensaje.
- Codificar el mensaje en una cadena.
La función debe devolver el mensaje FIX enviado por el servidor.
Como supondrÃa, no puede mostrar un mensaje FIX sin procesar al usuario, por lo que se debe desarrollar un paso adicional de análisis del mensaje entrante.
Conclusión ¶
Esta aplicación es una breve demostración de cómo comunicarse con cServer utilizando mensajes FIX. Es solo un ejemplo que ilustra los conceptos del Protocolo FIX y de ninguna manera es un motor FIX completo. Si desea evitar construir su propio motor FIX, podrÃa considerar usar uno de los motores FIX de terceros disponibles.
Nota
Este artÃculo está actualizado al 03/02/2017 y desarrollado teniendo en cuenta el motor FIX de cTrader, Reglas de Compromiso v2.9.1.