Click or drag to resize

Messages

A FIX message (specified by the FIX Protocol, see FIX Messages) is represented by the com.b2bits.FIXAntennaFixMessage class

This topic contains the following sections:

The FixMessage class is responsible for:

Note  Note

To compile the samples below, please declare the usage of com.b2bits.FIXAntenna namespace

Creating Framework

To create a framework for a FIX message, call the FixMessageCreate static method. After this you can set the desired field values of the message and send it to the remote FixEngine.

C#
FixMessage msg = FixMessage.Create(FixVersion.FIX44, "D"); 
// New Order - Single (MsgType = D)
msg.SetField(Tag.ClOrdID, "90001008"); 
msg.SetField(Tag.Side, "1");             
msg.SetField(Tag.TimeInForce, "0");
//...
Console.WriteLine("Msg: " + msg);
VB
Dim msg As FixMessage = FixMessage.Create(FixVersion.FIX44, "D")

' New Order - Single (MsgType = D)
msg.SetField(Tag.ClOrdID, "90001008")
msg.SetField(Tag.Side, "1")
msg.SetField(Tag.TimeInForce, "0")
'...
Console.WriteLine("Msg: " & msg.ToString())
C++
FixMessage^ msg = FixMessage::Create(FixVersion::FIX44, "D"); 

 // New Order - Single (MsgType = D)
msg->SetField(Tag::ClOrdID, "90001008"); 
msg->SetField(Tag::Side, "1");             
msg->SetField(Tag::TimeInForce, "0");
//...
Console::WriteLine("Msg: " + msg);

User-defined messages are supported, too.

C#
FixMessage msg = FixMessage.Create(FixVersion.FIX44, "U1"); // User-defined message (MsgType = U1)
msg.SetField(5100, "90001008"); 
//...
Console.WriteLine("Msg: " + msg);
VB
Dim msg As FixMessage = FixMessage.Create(FixVersion.FIX44, "U1") ' User-defined message (MsgType = U1)
msg.SetField(5100, "90001008")
'...
Console.WriteLine("Msg: " & msg.ToString())
C++
FixMessage^ msg = FixMessage::Create(FixVersion::FIX44, "U1"); // User-defined message (MsgType = U1)
msg->SetField(5100, "90001008"); 
//...
Console::WriteLine("Msg: {0}", msg);
Parsing Raw FIX Message

To parse a string containing a raw FIX message into the FixMessage class, use the FixMessageParse static method.

C#
string rawMsg = "8=FIX.4.4\u00019=86\u000135=D\u000149=0\u000156=0\u0001"+
            "34=1\u000152=99990909-17:17:17\u000111=90001008\u000121=1\u0001"+
            "55=IBM\u000154=1\u000138=10\u000140=1\u000159=0\u000110=191\u0001";                    
FixMessage message = FixMessage.Parse(rawMsg);
Console.WriteLine("message: " + message);
VB
Dim rawMsg As String = "8=FIX.4.4" & ChrW(1) & "9=86" & ChrW(1) & "35=D" & ChrW(1) & _
                        "49=0" & ChrW(1) & "56=0" & ChrW(1) & "34=1" & ChrW(1) & "52=99990909-17:17:17" & _
                        ChrW(1) & "11=90001008" & ChrW(1) & "21=1" & ChrW(1) & "55=IBM" & ChrW(1) & "54=1" & _
                        ChrW(1) & "38=10" & ChrW(1) & "40=1" & ChrW(1) & "59=0" & ChrW(1) & "10=191" & ChrW(1)

Dim msg As FixMessage = FixMessage.Parse(rawMsg)
Console.WriteLine("message: " & msg.ToString())
C++
String^ rawMsg = "8=FIX.4.4\x01""9=86\x01""35=D\x01""49=0\x01""56=0\x01"
            "34=1\x01""52=99990909-17:17:17\x01""11=90001008\x01""21=1\x01"
            "55=IBM\x01""54=1\x01""38=10\x01""40=1\x01""59=0\x01""10=191\x01";                    
FixMessage^ message = FixMessage::Parse(rawMsg);
Console::WriteLine("message: " + message);
Getting Field Value

To receive a field value, use the FixMessageGetField method.

This method returns field value by tag. If the tag exists for this type of message (according to the FIX Protocol) but is not present in this message, this method returns null. If the tag does not exist for this type of message, the method throws an ApplicationException exception.

For simplicity of use, standard FIX tags are enumerated in com.b2bits.FIXAntennaTag class.

Setting Field Value

To set a field value, use one of the overloaded FixMessageSetField methods.

This method returns "true" if the given tag is found and the old value is replaced with the new one, otherwise - "false" (the given tag was inserted).

It throws an ApplicationException exception if the method cannot be executed (e.g. the given tag is not defined for this message type).

Removing Field

To remove a field by tag, use the FixMessageRemoveField method.

This method returns "true" if the given tag is found and the field is removed, otherwise - "false".

Checking for Compliance

To examine a message for compliance with the FIX Protocol, use the FixMessageCheck method.

This method throws an exception if any required or conditionally required field is absent.

C#
FixMessage msg = FixMessage.Create( FixVersion.FIX44, "A");
try
{ 
    msg.Check(); 
    Console.WriteLine("Message is valid.");
}
catch( ApplicationException ex ) 
{
    Console.WriteLine("Message is invalid: " + ex.Message);
}
VB
Dim msg As FixMessage = FixMessage.Create(FixVersion.FIX44, "A")

Try
    msg.Check()
    Console.WriteLine("Message is valid.")
Catch ex As ApplicationException
    Console.WriteLine("Message is invalid: " & ex.Message)
End Try
C++
FixMessage^ msg = FixMessage::Create( FixVersion::FIX44, "A");
try
{ 
    msg->Check(); 
    Console::WriteLine("Message is valid.");
}
catch( ApplicationException^ ex ) 
{
    Console::WriteLine("Message is invalid: {0}", ex->Message);
}
Getting Field Enumeration

To get field enumeration, use the FixMessageFields property.

This property returns ArrayList based on DictionaryEntry elements.

C#
FixMessage msg = FixMessage.Create(FixVersion.FIX44, "D");  // New Order - Single
msg.SetField(Tag.ClOrdID, "90001008");             

Console.Write("Message: '");
foreach(DictionaryEntry fieldEntry in msg.Fields)
{ Console.Write( fieldEntry.Key + "=" + fieldEntry.Value + "\u0001" ); }
Console.WriteLine("'");
VB
Dim msg As FixMessage = FixMessage.Create(FixVersion.FIX44, "D") '  // New Order - Single
msg.SetField(Tag.ClOrdID, "90001008")

Console.Write("Message: '")

Dim fieldEntry As DictionaryEntry
For Each fieldEntry In msg.Fields
    Console.Write(fieldEntry.Key & "=" & fieldEntry.Value & ChrW(1))
Next

Console.WriteLine("'")
C++
FixMessage^ msg = FixMessage::Create(FixVersion::FIX44, "D");  // New Order - Single
msg->SetField(Tag::ClOrdID, "90001008");             

Console::Write("Message: '");

IEnumerator^ enumerator = msg->Fields->GetEnumerator();
while( enumerator->MoveNext() )
{ 
    DictionaryEntry^ fieldEntry = safe_cast<DictionaryEntry^>( enumerator->Current );
    Console::Write( fieldEntry->Key+ "=" + fieldEntry->Value + "\x01" ); 
}

Console::WriteLine("'");

or

C#
FixMessage msg = FixMessage.Create(FixVersion.FIX44, "D");  // New Order - Single

msg.SetField(Tag.ClOrdID, "90001008");             

System.Collections.IEnumerator fields = msg.Fields.GetEnumerator();
Console.Write("Message: '");
while( fields.MoveNext() )
{
    System.Collections.DictionaryEntry field = (System.Collections.DictionaryEntry) fields.Current;
    Console.Write( field.Key + "=" + field.Value + "\u0001" );
}
Console.WriteLine("'");
VB
Dim msg As FixMessage = FixMessage.Create(FixVersion.FIX44, "D") ' New Order - Single

msg.SetField(Tag.ClOrdID, "90001008")

Dim fields As IEnumerator = msg.Fields.GetEnumerator()

Console.Write("Message: '")
Do While fields.MoveNext()
    Dim field As DictionaryEntry = DirectCast(fields.Current, DictionaryEntry)
    Console.Write(field.Key & "=" & field.Value & ChrW(1))
Loop
Console.WriteLine("'")
Cloning

To copy a FIX message, use the FixMessageClone method.

C#
FixMessage originalMsg = FixMessage.Create(FixVersion.FIX44, "D");  // New Order - Single 
originalMsg.SetField(Tag.ClOrdID, "90001008");             

FixMessage clone = originalMsg.Clone();            
Console.WriteLine("OriginalMsg: " + originalMsg);
Console.WriteLine("Clone:       " + clone);
VB
Dim originalMsg As FixMessage = FixMessage.Create(FixVersion.FIX44, "D") ' New Order - Single 
originalMsg.SetField(Tag.ClOrdID, "90001008")

Dim clone As FixMessage = originalMsg.Clone()
Console.WriteLine("OriginalMsg: " & originalMsg.ToString())
Console.WriteLine("Clone:       " & clone.ToString())
C++
FixMessage^ originalMsg = FixMessage::Create(FixVersion::FIX44, "D");  // New Order - Single 
originalMsg->SetField(Tag::ClOrdID, "90001008");             

FixMessage^ clone = originalMsg->Clone();            
Console::WriteLine("OriginalMsg: {0}", originalMsg);
Console::WriteLine("Clone:       {0}", clone);
Repeating Groups

To work with Repeating Groups (see FIX Messages : Repeating Groups section) there is a com.b2bits.FIXAntennaGroup wrapper class. This class does not have a public constructor, but it is possible to get a reference to its object using the FixMessageGetGroup method, where tag parameter of this method is a FIX tag that defines the group - "Leading Tag". The value of this tag also shows the number of Repeating Group Entries. A group can also contain subgroups.

To create a Group, the FixMessage.SetField(int tag, int value) method must be used, where tag is a Repeating Group Leading Tag and value is a number of Repeating Group Entries. Then the created Group can be obtained using the FixMessage.GetGroup(int tag) method, where tag is a Repeating Group Leading Tag.

Note  Note

Be careful when changing the Leading Tag value. It is possible to increase its value safely (in this case new entries will be added to the back of the entries sequence without affecting data in other entries). However, when the value is decreased, the correspondent number of entries will be removed from the back of the entries sequence and all set values will be lost (for example if a value is changed from 5 to 3, the last 2 entries will be removed).

When assigning a new value to the Leading Tag, the Group object remains valid.

To remove a Repeating Group, the FixMessage.RemoveField(int tag) method must be used, where tag is a Repeating Group Leading Tag.

The com.b2bits.FIXAntennaGroup class contains methods for working with message fields, similar to those existing in the FixMessage class, in contrast to them, there is an additional argument that defines index (a sequence number starting with 0) of the group entry. For example:

  1. GroupGetField
  2. GroupSetField(int tag, string value, int index)
  3. GroupSetField(int tag, int value, int index)
  4. GroupRemoveField(int tag, int index)
  5. GroupGetGroup(int tag, int index)

The latter allows getting a cover class for embedded groups.

If non-existent or invalid values are specified for the arguments of these methods, the FE throws corresponding exceptions.

C#
// create a new message
FixMessage massQuote = FixMessage.Create(FixVersion.FIX44, "i");                                

Group group = massQuote.GetGroup(Tag.NoQuoteSets);   
// group is 'null' because this message does not contain a FIX group so far
Console.WriteLine("null == group is " + (null == group));         

// create a new group of three elements
massQuote.SetField(Tag.NoQuoteSets, 3);
group = massQuote.GetGroup(Tag.NoQuoteSets);

// group is not 'null' because now this message contains a FIX group
Console.WriteLine("null == group is " + (null == group)); 

string field = group.GetField(Tag.QuoteSetID, 0);
// field is 'null' because the group does not contain this field so far
Console.WriteLine("null == field is " + (null == field)); 

// rv is 'False' because the field was added rather than its value was changed
bool rv = group.SetField(Tag.QuoteSetID, "1" , 0);            
Console.WriteLine("rv: " + rv);

field = group.GetField(Tag.QuoteSetID, 0);
// field is "1" now
Console.WriteLine("field: " + field);
VB
' create a new message
Dim massQuote As FixMessage = FixMessage.Create(FixVersion.FIX44, "i")

Dim group As Group = massQuote.GetGroup(Tag.NoQuoteSets)

' group is 'null' because this message does not contain a FIX group so far
Console.WriteLine("null == group is " & (group Is Nothing))

' create a new group of three elements
massQuote.SetField(Tag.NoQuoteSets, 3)
group = massQuote.GetGroup(Tag.NoQuoteSets)

' group is not 'null' because now this message contains a FIX group
Console.WriteLine("null == group is " & (group Is Nothing))


Dim field As String = group.GetField(Tag.QuoteSetID, 0)
' field is 'null' because the group does not contain this field so far
Console.WriteLine("null == field is " & (field Is Nothing))

' rv is 'False' because the field was added rather than its value was changed
Dim rv As Boolean = group.SetField(Tag.QuoteSetID, "1", 0)
Console.WriteLine("rv: " & rv)

field = group.GetField(Tag.QuoteSetID, 0)
' field is "1" now
Console.WriteLine("field: " & field)
C++
// create a new message
FixMessage^ massQuote = FixMessage::Create(FixVersion::FIX44, "i");                                

Group^ group = massQuote->GetGroup(Tag::NoQuoteSets);   
// group is 'null' because this message does not contain a FIX group so far
Console::WriteLine("null == group is {0}", (nullptr == group));         

// create a new group of three elements
massQuote->SetField(Tag::NoQuoteSets, 3);
group = massQuote->GetGroup(Tag::NoQuoteSets);

// group is not 'null' because now this message contains a FIX group
Console::WriteLine("null == group is {0}", (nullptr == group)); 

String^ field = group->GetField(Tag::QuoteSetID, 0);
// field is 'null' because the group does not contain this field so far
Console::WriteLine("null == field is {0}", (nullptr == field)); 

// rv is 'False' because the field was added rather than its value was changed
bool rv = group->SetField(Tag::QuoteSetID, "1" , 0);            
Console::WriteLine("rv: {0}", rv);

field = group->GetField(Tag::QuoteSetID, 0);
// field is "1" now
Console::WriteLine("field: {0}", field);

Output:

Console
null == group is True
null == group is False
null == field is True
rv: False
field: 1
User Defined Fields

User Defined Fields (the tag numbers greater or euqwal then 5000) are handled like ordinary fields.

C#
int theCustomTag = 5000; // reserved for User Defined Fields

// create a new message
FixMessage msg = FixMessage.Create(FixVersion.FIX44, "D");

msg.SetField(theCustomTag , "0.15"); // set the tag's value
Console.WriteLine("msg: " + msg);
VB
Dim theCustomTag As Integer = 5000 ' reserved for User Defined Fields

' create a new message
Dim msg As FixMessage = FixMessage.Create(FixVersion.FIX44, "D")
msg.SetField(theCustomTag, "0.15") ' set the tag's value
Console.WriteLine("msg: " & msg.ToString())
C++
int theCustomTag = 5000; // reserved for User Defined Fields

// create a new message
FixMessage^ msg = FixMessage::Create(FixVersion::FIX44, "D");

msg->SetField(theCustomTag, "0.15"); // set the tag's value
Console::WriteLine("msg: {0}", msg);

This topic is discussed in detail in FIX Protocol Customization and Validation.

Sending FIX Messages

You need to open a Session to send a FIX message. Moreover, there should be a counterpart application that is ready to accept messages from you session. This will be discussed in detail in Sessions chapter.

See Also