Wednesday, September 12, 2012

C++ FIX message validate

Since most of the financial institutions have been following FIX messages as a standard communication mechanism in between their products, today I want to share how we can create a simple FIX message in C++ and validate that message. Further I will be giving some FIX message basics to understand the whole picture of FIX. 

The following details explaining what FIX protocol is.

  • Acronym for Financial Information eXchange Protocol (not to be confused with IPFIX, the Internet Protocol Flow Information Export).
  • Open standard which defines a message format as well as a communication model.
  • This standard has been created by an industry consortium consisting of banks, independent vendors etc.
  • The intended audience consists of financial institutions like banks, brokers, dealers, exchanges etc.
  • FIX is the defacto standard in financial information exchange today.
  • FIX is platform independent (concerning systems and networks).
  • Central point for all information about FIX is http://www.fixprotocol.org. 
There are three types of main user groups involves in using FIX Protocol.
Buy-side firms: Communication with sell-side firms by means of pre-trade, trade and post-trade messages.

Sell-side firms: Communictaion with buy-side firms via pre-trade, trade and post-trade messages. In addition to that communication with exchanges and OTC markets in general.

Exchanges: Receiving trades from their members, sending execution reports etc. back to them. Currently a wide variety of product classes are suported ranging from equities to fixed income products, derivatives and the like.

A typical FIX setup shown below. 


FIX message structure and fields 
Although FIX messages always have a similar structure, the number and type of possible fields depends strongly on the version of the FIX Protocol which is used. At the time of this writing the latest version is FIX 5.0 although most current production systems use older versions 4.x (4.4 being
the last).
FIX messages are grouped into two categories:
  1. Admin messages: Connection establishment and termination, heartbeat messages etc. (logon, logoff, heartbeat,test request, resend request, reject, sequence reset,. . )
  2. Application messages: Business related message transferring trade data etc. (advertisement, indication of interest, news, execution report, order cancel, new order,quote and many, many more)
Every FIX message is built according to the following structure: 

Message header: Contains the message type, length,sender/receiver name, sequence number, time stamp..etc

Message body: Contains session/application specific data.

Message trailer: Contains a message checksum and an optional signature.

The message consists of so called FIX fields which look like this: <tag>=<value><delimiter> The tag is a numerical identifier, the value is a string (which must be of correct type and length for this particular tag) and the delimiter is SOH (Start of header – ASCII 0x01) which is written as ^ in printed messages.

Although FIX supports literally hundreds of predefined tags, there is room for custom defined tags (field numbers 5000 to 9999).

The following example of a New Order Single message 
8=FIX.4.1^9=0235^35=D^34=10^43=N^49=VENDOR^50=CUSTOMER^56=BROKER^52=19980930-09:25:58^1=XQCCFUND^11=10^21=1^ 55=EK^48=277461109^22=1^54=1^38=10000^40=2^44=76.750000^59=0^10=165

Header: 8 (version), 9 (body length), 35 (MsgType), 34 (MsgSeqNum), 43 (PossDupFlag), 49
(SenderCompID), 115 (OnBehalfOfCompID), 56 (TargetCompID), 52 (time stamp)

Body: 1 (Account), 11 (ClOrdID), 21 (HandInst), 55(Symbol), 48 (SecurityID), 22 (IDSource), 54 (Side),
38 (OrderQty), 49 (OrdType), 44 (Price), 59 (TimeInForce)

Trailer: 10 (Checksum)

Note : This checksum value is for demonstrated purpose .

The FIX Protocol supports many different message types – some of these are shown in the following:
0: Heartbeat
1: Test request
2: Resend request
3: Reject
4: Sequence reset
5: Logout
6: Indication of interest
7: Advertisement
8: Execution report
9: Order cancel reject
A: Logon
B: News
C: Email
D: Order single
E: Order list

As a programmer we need to know the ASCII value of FIX delimiter which is 1 ( \001). For example lets assume we have FIX message like following. 

8=FIX.4.2<SOH>9=97<SOH>35=6<SOH>49=BKR<SOH>56=IM<SOH>34=14<SOH>52=2010020409:18:42<SOH>23=115685<SOH>28=N<SOH>55=SPMI.MI<SOH>54=2<SOH>44=2200.75<SOH>27=S<SOH>25=H<SOH>10=248<SOH> 

Tag                  Field                  Value                          Description
8                  BeginString           FIX.4.2
9                  BodyLength           97
35                  MsgType                   6                                 Indication of Interest
49                  SenderCompID    BKR
56                  TargetCompID   IM
34                  MsgSeqNum           14
52                  SendingTime           20100204-09:18:42
23                  IOIid                   115685
28                  IOITransType           N                                 New
55                  Symbol                    SPMI.MI
54                  Side                           2                                 Sell
44                  Price                   2200.75
27                  IOIShares           S                                 Small
25                  IOIQltyInd           H                                 High
10                  CheckSum           248

We used to validate FIX message by using check sum value which will be at trailer. Every single FIX message from tcp socket has to be identified using this method in order to extract single FIX message. 

#include <iostream>  
 #include <numeric>  
 #include <stdio.h>  
 #include <string.h>  
 #include <sstream>  
 #define BUFFER_LENGTH 400  
 using namespace std;  
 int main()  
 {  
 stringstream ss;  
 char fixChkSum[4];  
 unsigned int actualChkSum = 0;  
 int claimedChkSum = 0;  
 ss<<"8=";  
 ss<<"FIX.4.2";  
 ss<<"\0019=";  
 ss<<"97";  
 ss<<"\00135=";  
 ss<<"6";  
 ss<<"\00149=";  
 ss<<"BKR";  
 ss<<"\00156=";  
 ss<<"IM";  
 ss<<"\00134=";  
 ss<<"14";  
 ss<<"\00152=";  
 ss<<"20100204-09:18:42";  
 ss<<"\00123=";  
 ss<<"115685";  
 ss<<"\00128=";  
 ss<<"N";  
 ss<<"\00155=";  
 ss<<"SPMI.MI";  
 ss<<"\00154=";  
 ss<<"2";  
 ss<<"\00144=";  
 ss<<"2200.75";  
 ss<<"\00127=";  
 ss<<"S";  
 ss<<"\00125=";  
 ss<<"H";  
 ss<<"\00110=";  
 ss<<"248";  
 ss<<"\001";  
 int length = strlen(ss.str().c_str());  
 const char * fixin = new char[BUFFER_LENGTH];  
 memset ( (char*)fixin, 0, BUFFER_LENGTH);  
 strcpy((char*)fixin , (char*)ss.str().c_str());  
 int len = (int)strlen(fixin) - 7;  
 cout <<"Input fix mesasge length="<<len<<endl;  
 actualChkSum = accumulate(fixin, fixin+len, 0)% 256 ;  
 memcpy(fixChkSum, fixin+len+3, 3);  
 fixChkSum[3] = 0;  
 claimedChkSum = atoi(fixChkSum);  
 if( actualChkSum == claimedChkSum )  
       cout <<"Valid FIX message"<<endl;  
 else  
    cout <<"FIX message is not valid"<<endl;  
 return 0;  
 }  

The output will be like this ..:)



No comments:

Post a Comment