Envoyer et recevoir des messages¶
Introduction ¶
Cet article sert d'introduction à l'utilisation de FIX API pour toute personne intéressée par l'interaction avec Spotware cServer en utilisant FIX.
Dans cet article, nous utiliserons un exemple en C# pour décrire en détail les principes de construction d'un message FIX, son envoi au serveur et la réception de la réponse. Cet exemple n'est en aucun cas une application à toute épreuve et a été maintenu aussi simple que possible pour permettre aux programmeurs de comprendre facilement le concept d'utilisation des messages FIX API.
Afin d'établir et de maintenir une communication appropriée avec le serveur et un traitement approprié des réponses, des fonctionnalités supplémentaires sont nécessaires, qui ont été omises par souci de simplicité et de clarté. Nous traiterons ces sujets dans de futurs articles.
Exemple de code ¶
Vous pouvez trouver l'exemple de code discuté dans cet article sur notre dépôt GitHub
Aperçu de la communication FIX ¶
Un message FIX n'est qu'une chaîne composée d'ensembles de balises numériques et de valeurs séparées par une barre verticale (|). Chaque balise représente un champ différent pour lequel un certain ensemble de valeurs est autorisé. Ci-dessous, vous pouvez voir un exemple de message FIX qui demande l'authentification au serveur.
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|
Comme vous pouvez le voir, le modèle répétable trouvé dans chaque message FIX est :
Tag=Value|Tag=Value|Tag=Value|...
Selon le but de chaque message, un ensemble différent de balises et de valeurs est requis à chaque fois. Les balises et les valeurs requises pour chaque message sont décrites en détail dans les Règles d'engagement du moteur FIX de cTrader (vérifiez toujours les dernières règles d'engagement).
De la même manière, les réponses sont renvoyées par le serveur. Ci-dessous, vous pouvez voir la réponse du serveur pour le message ci-dessus.
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|
Les étapes impliquées dans le processus de communication avec un serveur FIX sont les suivantes :
-
Construire un message FIX
-
Transmettre un message FIX
-
Recevoir un message FIX
-
Analyser un message FIX
Un message FIX brut n'est pas un format très lisible car il a été conçu dans un souci d'efficacité plutôt que de compréhensibilité. Par conséquent, pour chaque application logicielle, il y aura toujours un processus de traduction des informations fournies dans le message FIX respectif.
Dans notre exemple d'application C#, nous avons créé une classe pour gérer la construction des messages ainsi que des fonctions pour créer des messages FIX basés sur les informations pertinentes.
Une fois les messages construits, ils sont transmis entre un serveur et un client via Internet par le biais de sockets réseau. Lorsque les messages sont reçus, ils doivent être analysés pour être présentés dans un format lisible.
Dans cet article, nous couvrirons le processus de construction, de transmission et de réception de la réponse. Nous traiterons de l'analyse dans un futur article.
Construire un message FIX ¶
Structure du message ¶
Dans notre exemple d'application, nous avons créé une classe responsable de la création des messages FIX. La classe s'appelle MessageConstructor et se trouve dans le projet FIX API Library.
Le MessageConstructor est initialisé avec les paramètres suivants :
-
Host(*)– l'adresse où se trouve notre cServer. -
Username(*)– le numéro de compte -
Password(*)– le mot de passe -
SenderCompID(*)– il est fourni dans le formulaire API FIX de cTrader. Il est au format -
SenderSubID*– c'est la deuxième partie de SenderCompID -
TargetCompID(*)– il est fourni dans le formulaire API FIX de cTrader (généralement c'est cServer)
Vous pouvez trouver ces informations dans votre formulaire API FIX de cTrader.
Après avoir initialisé un MessageConstructor, nous sommes prêts à construire des messages API FIX.
Tous les messages sont construits de manière similaire. Ci-dessous se trouve un exemple de code de construction d'un message 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 | |
Vous pouvez voir que nous construisons d'abord la partie corps, puis nous la transmettons à la fonction d'en-tête et enfin nous transmettons les deux parties à la fonction de fin. Ces 3 parties sont détaillées ci-dessous.
Le processus de construction du message consiste simplement à ajouter les tags, valeurs et séparateurs requis dans une chaîne.
Corps ¶
Nous allons commencer par décrire la construction du corps, car le corps du message doit être créé en premier. Nous pouvons voir un exemple ci-dessus (création du message Logon).
Nous commençons par initialiser une classe StringBuilder et nous ajoutons les balises une par une en fonction des entrées de la fonction. En fonction du type de message, le corps doit être composé de différents ensembles de balises, certaines étant obligatoires et d'autres facultatives.
Vous pouvez trouver la structure de chaque message dans notre Rules of Engagement (/FIX).
Ensuite, nous créons un en-tête pour un message Logon et nous y ajoutons le corps du message. Enfin, en utilisant la chaîne headerAndBody, nous générons la fin. Par la suite, nous verrons comment nous construisons un en-tête et une fin.
En-tête ¶
L'en-tête est la première partie du message FIX et il est composé des champs suivants (identiques pour tous les messages) :
BeginString– la chaîne de début définit la version du protocole FIX et dans notre cas est fixée à FIX4.4.BodyLength– la longueur du corps indique la longueur du message en caractères, à l'exclusion des champsBeginString,BodyLengthet de fin.MsgType– dans ce champ, nous définissons le type de message, afin que le destinataire sache comment analyser le corps.SenderCompID– ici, nous définissons leSenderCompID.TargetCompID– il s'agit de la cible de notre message. Dans notre cas, ce sera toujours cServer.SenderSubID– l'identifiant du trader.MsgSeqNum– il s'agit du numéro de séquence du message. Il doit être augmenté pour chaque message envoyé dans la même session.Sending Time– l'heure de transmission du message.
Ci-dessous, vous pouvez voir la fonction ConstructHeader, responsable de la construction des en-têtes.
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 | |
Pied de page ¶
La fin est simplement une balise contenant la somme de contrôle du reste du message.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
Messages système ¶
Notre exemple contient des fonctions qui renvoient les messages système suivants :
- Heartbeat :
MessageConstructor.HeartbeatMessage() - Test request :
MessageConstructor.TestRequestMessage() - Logon :
MessageConstructor.LogonMessage() - Logout :
MessageConstructor.LogoutMessage() - Resend request :
MessageConstructor.ResendMessage() - Reject :
MessageConstructor.RejectMessage() - Sequence reset :
MessageConstructor.SequenceResetMessage()
Messages d'application ¶
Notre exemple contient des fonctions qui renvoient les messages système suivants :
- Market data request :
MessageConstructor.HeartbeatMessage() - Market data snapshot/full refresh :
MessageConstructor.MarketDataSnapshotMessage() - Market data incremental refresh :
MessageConstructor.MarketDataIncrementalRefreshMessage() - New order single :
MessageConstructor.NewOrderSingleMessage() - Order status request :
MessageConstructor.OrderStatusRequest() - Execution report :
MessageConstructor.ExecutionReport() - Business message reject :
MessageConstructor.BusinessMessageReject() - Request for positions :
MessageConstructor.RequestForPositions() - Position report :
MessageConstructor.PositionReport()
Envoyer un message et recevoir une réponse ¶
Pour envoyer un message FIX à cServer, vous devez d'abord établir une connexion avec le serveur. Vous pouvez le faire en créant un TcpClient. Dans notre cas, nous créons deux clients, car les messages de cotation de prix et les messages de trading sont gérés par différents ports sur le serveur.
Ensuite, nous devons obtenir les deux flux sur lesquels les messages seront envoyés. Ce processus a lieu dans le constructeur du formulaire comme indiqué ci-dessous :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
Dans le constructeur, nous initialisons également une classe MessageConstructor qui sera utilisée pour générer les messages.
Ensuite, pour envoyer les messages, nous avons créé deux fonctions différentes, SendPriceMessage() et SendTradeMessage(). Chacune prend le message FIX comme entrée, puis appelle la fonction SendMessage() avec le message et le flux respectif comme entrée.
La fonction SendMessage() fonctionne comme suit :
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 | |
Les étapes détaillées sont les suivantes :
- Encoder le message dans un tableau d'octets.
- Écrire le tableau d'octets sur le flux.
- Lire la réponse du flux.
- Augmenter le numéro de séquence du message.
- Encoder le message dans une chaîne.
La fonction doit renvoyer le message FIX envoyé par le serveur.
Comme vous pouvez le supposer, vous ne pouvez pas afficher un message FIX brut à l'utilisateur, donc une étape supplémentaire d'analyse du message entrant doit être développée.
Conclusion ¶
Cette application est une brève démonstration sur la façon de communiquer avec cServer en utilisant des messages FIX. Il s'agit simplement d'un exemple illustrant les concepts du protocole FIX et ce n'est en aucun cas un moteur FIX complet. Si vous souhaitez éviter de créer votre propre moteur FIX, vous pourriez envisager d'utiliser l'un des moteurs FIX tiers disponibles.
Remarque
Cet article est à jour au 03/02/2017 et développé en tenant compte du moteur FIX cTrader, Rules of Engagement v2.9.1.