Skip to content

Sending and Receiving Messages

Introduction

This article serves the purpose of being an introduction to using FIX API for anyone interested in interacting with Spotware's cServer using FIX.

In the following paragraphs, we will use a C# example to describe in detail the principles of how to construct a FIX message, send it to the server and receive the response.

This example is by no means a bullet proof application and was kept as simple as possible to allow programmers to easily understand the concept of using FIX API messages.

In order to establish and maintain a proper communication with the server and proper handling of the responses, additional functionality is required, which was skipped for the sake of simplicity and clarity. We will deal with these subjects in future articles.

Code Sample

You can find the code sample discussed in this article on our GitHub repository here: https://github.com/spotware/FIX-API-Sample

Overview of FIX Communication

A FIX message is just a string composed of sets of numerical tags and values separated by |. Each tag represents a different field for which a certain set of values is allowed. Below you can see a sample FIX message which requests authentication from the server.

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|

As you can see, the repeatable pattern found in each FIX message is:

Tag=Value|Tag=Value|Tag=Value|...

Depending on the purpose of each message, different set of tags and values are required each time. The tags and values required for each message are described in detail in the cTrader FIX Engine Rules of Engagement (please always check for the latest rules of engagement here)

In a similar way, responses are sent back from the server. Below you can see the response of the server for the above message.

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|

The steps involved in the process of communicating with a FIX Server are the following:

  1. Construct a FIX message

  2. Transmit a FIX message

  3. Receive a FIX message

  4. Parse a FIX message

A raw FIX message is not a very readable format since it was designed with efficiency in mind rather than understandability.

Therefore, for each software application there will always be a process of translating information provided into the respective FIX message.

In our C# sample application we have created a class for handling the message construction as well as functions for creating FIX messages based on the relevant information.

After the messages have been constructed they are transmitted between a server and a client over the internet through network sockets. When the messages are received, then they need to be parsed in order to be presented in a readable format.

In this article we will cover the process of construction, transmission and receipt of the reply. We will deal with parsing in a future article.

Constructing a FIX Message

Message Structure

In our sample application we have created a class responsible of creating FIX messages. The class is called MessageConstructor and can be found in the FIX API Library project.

The MessageConstructor is initialized with the following parameters:

  1. Host(*): The address where our cServer is located.

  2. Username(*): The account number.

  3. Password(*): The password.

  4. SenderCompID(*): It is provided in the FIX API form of cTrader. It is in the format .

  5. SenderSubID: It is the second part of SenderCompID i.e.

  6. TargetCompID(*): It is provided in the FIX API form of cTrader. Usually it is cServer.

You can find this information in your cTrader FIX API form

After we have initialized a MessageConstructor then we are ready to construct FIX API messages.

All the messages are constructed in a similar manner. Below there is a code sample of constructing a logon message.

 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
public  string LogonMessage(SessionQualifier qualifier, int messageSequenceNumber,

            int  heartBeatSeconds,  bool  resetSeqNum)

       {

            var  body = new  StringBuilder ();

        //Defines a message encryption scheme.Currently, only transportlevel security

       //is supported.Valid value is "0"(zero) = NONE_OTHER (encryption is not used).

           body.Append( "98=0|");

            //Heartbeat interval in seconds. 

           //Value is set in the 'config.properties' file (client side) as 

         // 'SERVER.POLLING.INTERVAL' . 

           //30 seconds is default interval value. If HeartBtInt is set to 0, 

         no heartbeat message  

           //is required.

           body.Append( "108="  + heartBeatSeconds +  "|");

           // All sides of FIX session should have

           //sequence numbers reset. Valid value

            //is "Y" = Yes(reset). 

            if  (resetSeqNum)

               body.Append( "141=Y|");

            //The numeric User ID.  User is linked to SenderCompID (#49) value (the

            //user's organization). 

           body.Append( "553=" + _username + "|");

           //USer Password

           body.Append( "554=" + _password + "|");

            var  header = ConstructHeader(qualifier, 

         SessionMessageCode( SessionMessageType.Logon), messageSequenceNumber,

          body.ToString());

            var  headerAndBody = header + body;            

            var  trailer = ConstructTrailer(headerAndBody);

            var  headerAndMessageAndTrailer = header + body + trailer;

            return  headerAndMessageAndTrailer.Replace("|", "\u0001");

       }

You can see that we first construct the body part, then we pass it to the header function and at last we pass both parts into the trailer function. We will see these three parts in detail in the following paragraphs.

The message construction process is just the addition of the required tags, values and separators into a string.

Body

First we will start by describing the body construction, since the body of the message needs to be created first. We can see an example above i.e. creating the logon message.

We start by initializing a StringBuilder class and we append the tags one by one based on the function inputs. Based on the message type, the body must be composed of different sets of tags, some of them being mandatory and others being optional.

You can find the structure of each message in our rules of engagement (/FIX).

Then we create a header for a logon message and append to it the body of the message. Finally, using the headerAndBody string we generate the trailer. Following on, we will see how we construct a header and a trailer.

The header is the first part of the FIX message and it is composed of the following fields (same for all the messages):

  1. BeginString: The begin string defines the FIX protocol version and in our case is fixed to FIX4.4
  2. BodyLength: The body length states the length of the message in characters, excluding the BeginString, the BodyLength and the Trailer fields.
  3. MsgType: In this field we define the message type, so that the receiver knows how to parse the body.
  4. SenderCompID: Here we set the SenderCompID
  5. TargetCompID: This is the target of our message. In our case, it will always be CSERVER.
  6. SenderSubID: The trader login.
  7. MsgSeqNum: This is the sequence number of the message. It needs to be increased for each message send in the same session.
  8. Sending Time: The time of message transmission.

Below you can see the ConstructHeader function, responsible for constructing the headers.

 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
private  string ConstructHeader(SessionQualifier qualifier, string type,

         int  messageSequenceNumber, string bodyMessage)

    {

         var  header = new  StringBuilder ();

        // Protocol version. FIX.4.4 (Always unencrypted, must be first field 

        // in message.

        header.Append( "8=FIX.4.4|");

         var  message = new  StringBuilder ();

        // Message type. Always unencrypted, must be third field in message.

        message.Append( "35=" + type + "|");

        // ID of the trading party in following format: <BrokerUID>.<Trader Login> 

        // where BrokerUID is provided by cTrader and Trader Login is numeric 

        // identifier of the trader account.

        message.Append( "49="  + _senderCompID +  "|");  

        // Message target. Valid value is "CSERVER"

        message.Append( "56="  + _targetCompID +  "|");  

        // Additional session qualifier. Possible values are: "QUOTE", "TRADE".

        message.Append( "57="  + qualifier.ToString() +  "|");  

        // Assigned value used to identify specific message originator.

        message.Append( "50="  + _senderSubID +  "|");

        // Message Sequence Number

        message.Append( "34="  + messageSequenceNumber +  "|");

         // Time of message transmission (always expressed in UTC(Universal Time  

        // Coordinated, also known as 'GMT').

        message.Append("52=" + DateTime.UtcNow.ToString("yyyyMMdd-HH:mm:ss") + "|");

         var  length = message.Length + bodyMessage.Length;

        // Message body length. Always unencrypted, must be second field in message.

        header.Append( "9=" + length + "|");

        header.Append(message);      

         return  header.ToString();

    }

Trailer

The trailer is just a tag containing the checksum of the rest of the message.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
private  string ConstructTrailer(string message)

       {

            //Three byte, simple checksum.  Always last field in message; i.e. serves,

           //with the trailing<SOH>, 

           //as the end - of - message delimiter. Always defined as three characters

           //(and always unencrypted).

            var  trailer = "10=" + CalculateChecksum(message.Replace("|", "\u0001").ToString()).ToString().PadLeft(3, '0') + "|";

            return  trailer;

       }

System Messages

Our sample contains functions that return the following system messages:

  • Heartbeat: MessageConstructor.HeartbeatMessage()
  • Test Request: MessageConstructor.TestRequestMessage()
  • Logon: MessageConstructor.LogonMessage()
  • Logout: MessageConstructor.LogoutMessage()
  • Resend Request: MessageConstructor.ResendMessage()
  • Reject: MessageConstructor.RejectMessage()
  • Sequence Reset: MessageConstructor.SequenceResetMessage()

Application Messages

Our sample contains functions that return the following system messages:

  • 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()
  • RequestForPositions: MessageConstructor.RequestForPositions()
  • Position Report: MessageConstructor.PositionReport()

Sending a Message and Receiving a Response

In order to send a FIX message to cServer you first need to establish a connection with the server. You can do this by creating a TcpClient. In our case we create two clients, since price quotation messages and trade messages are handled by different ports on the server.

Then, we need to get the two streams on which the messages will be sent. This process takes place in the form's constructor as shown below:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
public  frmFIXAPISample()
{

   InitializeComponent();

    _priceClient = new  TcpClient( _host, _pricePort);           

   _priceStream = _ priceClient.GetStream ();            

   _tradeClient =  new  TcpClient ( _host, _tradePort);

   _tradeStream = _ tradeClient.GetStream ();

   _messageConstructor = new  MessageConstructor( _host, _username,

       _password, _senderCompID, _senderSubID, _targetCompID);

}

In the constructor, we also initialize a MessageConstructor class which will be used for generating the messages.

Then for sending the messages we created two different functions, SendPriceMessage () and SendTradeMessage(). Each of them takes as an input the FIX message and then calls SendMessage() function with the message and the respective stream as an input.

SendMessage() function works as follows:

 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
private  string SendMessage(string message,  NetworkStream  stream)
{
    var  byteArray =  Encoding.ASCII.GetBytes (message);

    stream.Write(byteArray, 0, byteArray.Length);

    var  buffer = new byte[1024];

    int  i = 0;

    while  (!stream.DataAvailable && i < 100)
    {
         Thread.Sleep ( 100);
         i++;
    }

    if( stream.DataAvailable )
        stream.Read(buffer, 0, 1024);

    _messageSequenceNumber++;

    var  returnMessage = Encoding.ASCII.GetString(buffer);

    return  returnMessage;
}

In detail the steps are the following

  1. Encode the message to a byte array.
  2. Write the byte array on the stream.
  3. Read the reply from the stream.
  4. Increase the message sequence number.
  5. Encode the message into string.

The function should return the FIX message sent by the server.

As you would assume, you cannot show a raw FIX message to the user, so an additional step of parsing the incoming message should be developed.

Conclusion

This application is a brief demonstration on how to communicate with cServer using FIX messages. It is just an example illustrating the concepts of FIX protocol and it is by no means a full FIX engine. If you would like to avoid building your own FIX engine, you might consider using one of the 3rd party FIX engines available.

Note

This article is up to date as of 03/02/2017 and developed having in mind cTrader FIX Engine, Rules of Engagement v2.9.1