Home » Products » FF.FIX Engine » FF.FIX Engine Knowledgebase » FIX Parser

FIX Parser

The FIX Parser transforms a raw message stream (bytes or string) into a FixMessage data structure which is suitable for querying the required information from the message.

An object of the FixParser class does not need a FIX Data Dictionary for parsing simple messages. However, a FIX Data Dictionary is essential for parsing:

  • Custom messages.
  • Messages having custom fields or custom enumerations.
  • Messages having Repeating Group fields.
  • Messages having data type fields.

FF.FIX Engine also allows to create FixParserHint objects which:

  • Provide the relevant information for successful parsing of messages and enable parsing in the presence or absence of a FIX Data Dictionary.
  • Force the FixParser object to ignore certain default validations. It is useful to deal with specific needs.

::FAQ::

  1. What is the role of the FixParser class? How do I parse a simple FIX Message?
  2. How do I specify a FIX Data Dictionary in FixParser objects?
  3. How do I specify FixParserHint objects for parsing complex FIX Messages?
  4. Which important public methods are available on FixParser objects?
  5. How I parse a FIX Message with Repeating Groups?
  6. How do I parse a FIX Message having data type fields?
  7. How do I parse a FIX Message string that includes a binary or encoded data as field values?
  1. What is the role of the FixParser class? How do I parse a simple FIX Message?

The FixParser class in the FF.Fix.Core.Message namespace offers fast and powerful parsing of a FIX Message stream resulting into a FixMessage object.

The FixParser object can parse simple FIX Messages. However, it requires more inputs like FixDataDictionary and FixParserHint objects to deal with complexities like:

  • Custom fields.
  • Custom messages.
  • Repeating Groups.
  • Data type fields.

For example, the code for parsing a simple FIX Message string is:

using FF.Fix.Core;
using FF.Fix.Core.Message;
...
...

//Specify the Raw Message string
string rawFIXMessage = "8=FIX.4.2|9=249|35=D|49=FF|56=ASX|34=201|52=20060103-11:31:06.329|57=X|369=256|142=FFG
|50=FFG|108=30|1=606060|11=ORD0301200612310600000500|21=1|38=25|40=3|54=1|55=GE|59=0|60=2006010311:31:06.3
29|99=9632|107=GEH6|167=FUT|204=1|9702=1|9717=ORD0301200612310600000281|10=068|”;

//Parse the Raw Message string by creating a FixParser object.
FixParser fixParser = new FixParser(rawFIXMessage);

//If a FixParser object gets created without parsing error, the FIX Message is valid.

//Create a FixMessage object from the FixParser object for further processing.
FixMessage fixMessage = fixParser.GetFixMessage();

The FixParser constructor in the above example represents a default FixParser object constructor. It takes only the Raw Message string (rawFIXMessage) as input.

The FixParser object created using the default constructor:

  • Checks the presence and correct order of the mandatory fields BeginString (tag 8), BodyLength (tag 9) and MsgType (tag 35).
  • Validates the value of the BodyLength field.
  • Checks the presence of the CheckSum field (tag 10) as the last field of the FIX Message and validates its value.
  • Checks the presence of the mandatory header fields SenderCompID (tag 49), TargetCompID (tag 56), and MsgSeqNum (tag 34).

The FixParser object throws an error on violation of any of the above conditions.

  1. How do I specify a FIX Data Dictionary in FixParser objects?

For parsing complex messages, a constructor for FixParser objects should include a FIX Data Dictionary as inputs. Such constructor is given below:

public FixParser identifierName = new FixParser(string originalRawFixMessage, FixDataDictionary fixDataDictionary);

For example:

/* Initially, create a new fixDataDictionary object using the required Data Dictionary file in XML format. */
string dataDictionyFileName = @"D:\...\Dictionaries\XYZInitiatorFixDataDictionary.xml";
FixDataDictionary fixDataDictionary = new FixDataDictionary(dataDictionyFileName);

//Access the original Raw FIX Message string.
string originalRawFixMessage = "8=FIX.4.2|9=249|35=D|49=FF|56=ASX|34=201|52=20060103-11:31:06.329|57=X|369=256
|142=FFG|50=FFG|108=30|1=606060|11=ORD0301200612310600000500|21=1|38=25|40=3|54=1|55=GE|59=0|60=2006010
311:31:06.329|99=9632|107=GEH6|167=FUT|204=1|9702=1|9717=ORD0301200612310600000281|10=068|”;

//Create a FixParser object from the message string and the fixDataDictionary object.
FixParser fixParser = new FixParser(originalRawFixMessage, fixDataDictionary);

//Get a FixMessage object from the FixParser object for further message processing.
FixMessage fixMessage = fixParser.GetFixMessage();

  1. How do I specify FixParserHint objects for parsing complex FIX Messages?

The FixParserHint class in the FF.Fix.Core.Message namespace includes useful hints and information about Repeating Groups fields, Data type fields and custom Header fields. You can also override certain default validations through these objects, as required. Different constructors for FixParserHint objects are:

  • Constructor 1: For declaring Header fields.

    FixParserHint(int[] headerFields)

    It initializes a new instance of FixParserHint with the specified FIX Message Header tags. For example, to create a FixParserHint object that informs the parser about custom Header fields at tag 5001 and 5002, the code is:

    //Create a FixParserHint object for new Header fields.
    FixParserHint fixParserHint = new FixParserHint(new int[]{5001, 5002});

    //Create a new FixParser object.
    FixParser fixParser = new FixParser(originalRawFixMessage, fixDataDictionary, fixParserHint);

  • Constructor 2: For declaring Header fields, Data type fields and Repeating Group fields.

    FixParserHint(int[] headerFields, MsgDataTypeFieldInfo msgDataTypeFieldInfo, MsgRepeatingGroupFieldInfo msgRepeatingGroupFieldInfo)

    It initializes a new instance of FixParserHint object with the following information:

    • Header fields: All custom fields expected to appear in message Headers.
    • Data type fields: All Data type fields that may appear in the Body parts of different messages. The MsgDataTypeFieldInfo class includes the information about Data type fields in different message types.
    • Repeating Group fields: All the Repeating Group fields that may appear in the Body parts of different messages. The MsgRepeatingGroupFieldInfo class provides the information about Repeating Group fields in different message types.

    For example, create a FixParserHint object to inform the parser that:

    • The News message (MsgType = B) shall contain the Data type fields RawData (tag 96), EncodedText (tag 355) and EncodedHeadline (tag 359).
    • The MarketDataIncrementalRefresh message (MsgType = X) shall include the Repeating Group field NoMDEntries (tag 268) and the tag numbers of fields under it would be 79, 69, 6, 70 and 71 respectively.

    The code for this requirement is:

    /*Create the msgDataTypeFieldInfo object, which contains the information that tags 96, 355 and 359 are the Data type fields in the message type B. The AddDataTypeFieldInfo method enables you to add information on Data type fields across several message types into the same MsgDataTypeFieldInfo object.*/
    MsgDataTypeFieldInfo msgDataTypeFieldInfo = new MsgDataTypeFieldInfo();
    msgDataTypeFieldInfo.AddDataTypeFieldInfo(FixMessageTypes.News_B, new int[]{359, 355, 96});

    /*Create the repeatingGroupFieldInfo object, which contains the information that:
    [1] Tags 79, 69, 5, 70 and 71 occur as a group of fields.
    [2] These fields occur in each group and in the same order.
    [3] The NumInGroup field at tag 268 specifies the number of group of fields that repeat after it. */
    RepeatingGroupFieldInfo repeatingGroupFieldInfo = new RepeatingGroupFieldInfo(268, new int[]{79, 69, 5, 70, 71});

    /*Create a msgRepeatingGroupFieldInfo object that shall contain information about Repeating Group fields in a specific message type. */
    MsgRepeatingGroupFieldInfo msgRepeatingGroupFieldInfo = new MsgRepeatingGroupFieldInfo();

    /*Specify that the msgRepeatingGroupFieldInfo object shall contain Repeating Group fields under Tag 268 in message type X. The AddMsgRepeatingGroupInfo method enables you to add information on Repeating Group fields across several message types into the same MsgRepeatingGroupFieldInfo object. */
    msgRepeatingGroupFieldInfo.AddMsgRepeatingGroupInfo(FixMessageTypes.MarketData_IncrementalRefresh_X, repeatingGroupFieldInfo);

    /*Create a FixParserHint object for Data type fields and Repeating Group fields in several message types. Note that the null value for headerFields array indicates that there are no declarations for the same.*/
    FixParserHint fixParserHint = new FixParserHint(null, msgDataTypeFieldInfo, msgRepeatingGroupFieldInfo);

    //Create a new FixParser object.
    FixParser fixParser = new FixParser(originalRawFixMessage, fixDataDictionary, fixParserHint);

  • Constructor 3: For declaring Header fields, Data type fields and Repeating Group fields and ignoring certain validations.

    FixParserHint(int[] headerFields, MsgDataTypeFieldInfo msgDataTypeFieldInfo, MsgRepeatingGroupFieldInfo msgRepeatingGroupFieldInfo, bool ignoreBodyLengthValidation, bool ignoreCheckSumValidation, bool ignoreHeaderRequiredFldValidation)

    It initializes a new instance of FixParserHint object with the following information:

    • Header fields: All custom fields expected to appear in message Headers.
    • Data type fields: All Data type fields that may appear in the Body part of different messages. The MsgDataTypeFieldInfo class includes the information about Data type fields in different message types.
    • Repeating Group fields: All the Repeating Group fields that may appear in the Body part of different messages. The MsgRepeatingGroupFieldInfo class provides the information about Repeating Group fields in different message types.
    • ignoreBodyLengthValidation: A boolean parameter that tells the parser whether to validate or ignore the BodyLength field (tag 9) during parsing.
    • ignoreCheckSumValidation: A boolean parameter that tells the parser whether to validate or ignore the CheckSum field (tag 10) during parsing.
    • ignoreHeaderRequiredFldValidation: A boolean parameter that tells the parser whether the validation of the required (mandatory) Header fields shall be ignored during parsing.

    For example, refer to Example for the Constructor 2 above. In addition to the cited requirements, assume that your application is creating and validating the message before sending. It is then essential to ignore the validation of tag 10 because it is inserted automatically before sending the message. You may wish to ignore the validation of the BodyLength field as the message is not yet final. Further you wish to validate the presence of all mandatory Header fields. The required code for this purpose would be:

    /* The code for creating msgRepeatingGroupFieldInfo and msgDataTypeFieldInfo objects is same as in Example for the Constructor 2.*/

    /*Create a FixParserHint object for Data type fields and Repeating Group fields in several message types. Note that the null value for headerFields array indicates that there are no declarations for the same.*/
    FixParserHint fixParserHint = new FixParserHint(null, msgDataTypeFieldInfo, msgRepeatingGroupFieldInfo, true, true, false);

    //Create a new FixParser object.
    FixParser fixParser = new FixParser(originalRawFixMessage, fixDataDictionary, fixParserHint);

  1. Which important public methods are available on FixParser objects?

Public methods Description
string OriginalRawFixMessage Gets the original message string (Raw Message string).
string HeaderMessage Gets the Header part of the Raw Message string.
string BodyMessage Gets the Body part of the Raw Message string.
string TrailerMessage Gets the Trailer part of the Raw Message string.
string BeginString Gets the value of the BeginString field (tag 8).
int BodyLength Gets the value of the BodyLength field (tag 9).
int MsgSeqNum Gets the value of MsgSeqNum field (tag 34).
string MsgType Gets the value of the MsgType field (tag 35).
string SenderCompID Gets the value of the SenderCompID field (tag 49).
string TargetCompID Gets the value of the TargetCompID field (tag 56).
bool PossDupFlag Gets the value of the PossDupFlag field (tag 43).
bool PossResend Gets the value of the PossResend field (tag 97).
string SendingTime Gets the value of the SendingTime field (tag 52).
DateTime SendingTimeDT Gets the value of the SendingTime field (tag 52) as a System.DateTime.
bool HasOriginalSendingTime Identifies the presence of the OrigSendingTime field (tag 122).
bool HasSignature Identifies the presence of the Signature field (tag 89) appearing in the FIX Message Trailer.
string OriginalSendingTime Gets the value of the OrigSendingTime field (tag 122) in the string format.
DateTime OriginalSendingTimeDT Gets the value of the OrigSendingTime field (tag 122) as a System.DateTime.
string CheckSum Gets the value of the CheckSum field (tag 10) appearing in FIX Message Trailer.
bool AdminMessage Identifies whether the FIX Message is an Admin Message (session level message).
bool ApplicationMessage Identifies whether the FIX Message is an Application Message (business message/application level message).

  1. How I parse a FIX Message with Repeating Groups?

To parse a FIX Message stream having a Repeating Group, you require to provide an appropriate FixParserHint object containing the details about the Repeating Group field. For example:

using FF.Fix.Core;
using FF.Fix.Core.Message;
...
...

/* In the following message string, Tag 268 is the Repeating Group (NumInGroup type) field. Two groups of fields (tag numbers 79, 69, 5, 70 and 71) would repeat as 268=2. */
string rawFixMessage = "8=FIX.4.2|9=114|35=D|49=FF|56=ASX|34=1|52=2007101508:23:30.140|268=2|79=0|69=3|5=GBP/CHF|70=0|71=4|79=0|69
=3|5=EUR/GBP|70=0|71=5|10=031|";

/*Create the repeatingGroupFieldInfo object, which contains the information that:
[1] Tags 79, 69, 5, 70 and 71 occur as a group of fields.
[2] These fields occur in each group and in the same order.
[3] The NumInGroup field at Tag 268 specifies the number of group of fields that repeat after it. */
RepeatingGroupFieldInfo repeatingGroupFieldInfo = new RepeatingGroupFieldInfo(268, new int[]{79, 69, 5, 70, 71});

/* Create a msgRepeatingGroupFieldInfo object that shall contain information about the Repeating Group fields. */
MsgRepeatingGroupFieldInfo msgRepeatingGroupFieldInfo = new MsgRepeatingGroupFieldInfo();

/* Specify that the msgRepeatingGroupFieldInfo object shall contain information about the Repeating Group fields under Tag 268 in message type X. The AddMsgRepeatingGroupInfo method enables you to add information on Repeating Group fields across several message types into the same MsgRepeatingGroupFieldInfo object. */
msgRepeatingGroupFieldInfo.AddMsgRepeatingGroupInfo(FixMessageTypes.MarketData_IncrementalRefresh_X, repeatingGroupFieldInfo);

/*Create a FixParserHint object for the Repeating Group fields. As the hint is not for Header or Data type fields, first two arguments are null. */
FixParserHint fixParserHint = new FixParserHint(null, null, msgRepeatingGroupFieldInfo);

/* Create a FixParser object for parsing the Raw Message string. No Data Dictionary is specified. Hence the second argument is null. */
FixParser fixParser = new FixParser(rawFixMessage, null, fixParserHint);

//Obtain a FixMessage object from the parsed message
FixMessage fixMessage = fixParser.GetFixMessage();

  1. How do I parse a FIX Message having data type fields?

To parse a FIX Message stream having Data type fields, you have to provide an appropriate FixParserHint object containing the details about the Data type fields.

For example: A FIX Message contains the Body field RawData (tag 96). It is a Data type field with value Hello|World. The two words Hello and World are separated by a <SOH> character, shown by '|'.

To parse this message successfully, the code would be as follows:

using FF.Fix.Core;
using FF.Fix.Core.Message;
...
...
string rawFixMessage = 8=FIX.4.2|9=110|35=A|49=FFN|56=CME|34=18|52=2006051609:12:59.408|57=G|369=14|142=FFG|50=FFG|95=11|96=Hello|
World|98=0|108=30|10=035|";

/*Create the msgDataTypeFieldInfo object, which contains the information that tag 96 is a Data type field in the message type A. */
MsgDataTypeFieldInfo msgDataTypeFieldInfo = new MsgDataTypeFieldInfo(FixMessageTypes.Logon_A, new int[]{96});

/*Create a FIX parser hint for Data type fields. Note that the null value for the headerFields array indicates that there are no declarations for the same. Further, as there are no Repeating Groups, the third argument related to the MsgRepeatingGroupFieldInfo field parameter is also set to null. */
FixParserHint fixParserHint = new FixParserHint(null, msgDataTypeFieldInfo, null);

/*Create a new FixParser object. The null value for the second argument is related to Data Dictionary (not used here). */
FixParser fixParser = new FixParser(rawFixMessage, null, fixParserHint);

//Create a FixMessage object from the parsed message.
FixMessage fixMessage = fixParser.GetFixMessage();

  1. How do I parse a FIX Message string that includes a binary or encoded data as field values?

If a FIX Message stream contains a binary or encoded data, the FixParser object takes a stream of byte data for successful parsing.

See the following steps for verification:

  1. Take some rawFixMessage string, parse it and obtain a FixMessage structure from it with the name fixMessage1.
  2. The fields at tag 89, 91 and 96 contain encoded data. Tag 89 is the Signature field in the Trailer. Tag 91 is the Header field SecureData. Tag 96 is the Body field RawData. Include these fields in the message structure fixMessage1.
  3. After this, extract the modified message in the fixMessage1 structure as a byte array having the name bFixMessage1.
  4. Parse bFixMessage1 and obtain another FixMessage structure from it with the name fixMessage2.
  5. The fixMessage2 structure is obtained after parsing a message having encoded fields. Get the FIX Message as a byte array with name bFixMessage2 from the fixMessage2 structure.
  6. Compare bFixMessage1 with bFixMessage2. The comparison of the two byte arrays should return a true value, as they must be identical. This is a test that verifies that the encoded messages are successfully parsed.

The code for these steps is:

using FF.Fix.Core;
using FF.Fix.Core.Message;
...
...

//Step 1:

//Define rawFixMessage and create fixMessage1 structure from it.
string rawFixMessage = "8=FIX.4.2|9=249|35=D|49=FF|56=ASX|34=201|52=20060103-11:31:06.329|5=X|369=256|142=FFG|
50=FFG|108=30|1606060|11=ORD0301200612310600000500|21=1|38=25|40=3|54=1|55=GE|59=0|60=2006010311:31:06.32
9|99=9632|107=GEH6|167=FUT|204=1|9702=1|9717=ORD0301200612310600000281|10=068|";

//Create a FixParser object based on rawFixMessage string.
FixParser fixParser = new FixParser(rawFixMessage);

//Obtain a FixMessage object based on rawFixMessage from the FixParser object.
FixMessage fixMessage1 = fixParser.GetFixMessage();

//Step 2:

//Insert tag 89 with the value “FFFIX” in an encoded form into the fixMessage1 structure.

//Generate MD5 hash for FFFIX (Encoding).
byte[] strBytes = ASCIIEncoding.ASCII.GetBytes("FFFIX");
byte[] resultBytes = System.Security.Cryptography.MD5CryptoServiceProvider.Create().ComputeHash(strBytes);

//Add binary information to the Signature field of the Trailer
fixMessage1.Trailer.SetSignatureField(resultBytes);

//Insert tag 91 with the value “My Secure Data” in an encoded form into fixMessage1.

//Encoding the SecureData field.
byte[] secureData = ASCIIEncoding.ASCII.GetBytes("My Secure Data");

//Adding encoded information to the SecureData field in the Header part of fixMessage1.
fixMessage1.Header.SetSecureDataField(secureData);

//Insert tag 96 with value “Body Raw Data Field” in an encoded form into fixMessage1.

//Encoding the RawData field
byte[] bRawDataField = ASCIIEncoding.ASCII.GetBytes("Body Raw Data Field");

//Adding binary information to the Raw Data field in the Body part of fixMessage1.
fixMessage1.SetRawDataField(bRawDataField);

/Step 3:

//Obtain the binary data bFixMessage1 from the modified fixMessage1 object.
byte[] bFixMessage1 = fixMessage1.ToArray();

//Step 4:

//Parse the byte array bFixMessage1 using a parser hint for Data type fields in the body.

/*Specify that tag 96 is a Data type field from message type D and add this information into the msgDataTypeFieldInfo object. */
MsgDataTypeFieldInfo msgDataTypeFieldInfo = new MsgDataTypeFieldInfo(D, new int[]{96});

//Create a FIX parser hint for Data type fields.
FixParserHint fixParserHint = new FixParserHint(null, msgDataTypeFieldInfo, null);

/*Create a new FixParser object. The null value for the second argument is related to the Data Dictionary (not used here). */
FixParser fixParser = new FixParser(bFixMessage1, null, fixParserHint);

//Obtain the fixMessage2 object from the parsed binary message bFixMessage1.
FixMessage fixMessage2 = fixParser.GetFixMessage();

//Step 5:

//Obtain a binary FIX Message with the name bFixMessage2 from the fixMessage2 structure.
byte[] bFixMessage2 = fixMessage2.ToArray();

//step 6:

//If bFixMessage1 = bFixMessage2, the parsing of encoded fields is successful.

//Compare the binary messages bFixMessage1 and bFixMessage2.
bool result = FF.Fix.Core.Util.StringUtil.CompareBytes(bFixMessage1, bFixMessage2);

The identifier result returns the TRUE value. It means bFixMessage1 = bFixMessage2. This confirms the successful parsing of encoded fields.