FIX Message

Create

Message can be created two different ways:
  1. Create skeleton and set fields
  2. Parse raw FIX message (byte array)

To create a framework for a FIX application-level message, use Engine::FIXMsgFactory::newSkel(Engine::FIXVersion ver, const char *aMsgType) method. Thereafter you can set the desired field values of the message and send it to the counter-party.

For example:

#include <assert.h>
#include <B2BITS_V12.h>
   
using namespace std;

// New Order - Single (MsgType D)
Engine::FIXMessage* pFIXMessage = Engine::FIXMsgFactory::singleton()->newSkel(FIX42, "D");
pFIXMessage->set(FIXField::ClOrdID, "90001008"); 
pFIXMessage->set(FIXField::Side, "1"); 
//...
pFIXMessage->set(FIXField::TimeInForce, "0");

To parse a string containing a raw FIX message into the FIXMessage class, use the FIXMsgProcessor::parse(...) method.

For example:

Engine::FIXMessage* pMsg = Engine::FIXMsgProcessor::singleton()->parse(aRawMessage);

Get field

To get FIX field value, use the bool Engine::FIXMessage::get(int tag, Engine::FIXFieldValue *value) method.

This method retrives field value by tag number and stores it into instance of Engine::FIXFieldValue class. Field can be:

  1. Not defined for this message type by specification.
  2. Defined as optional for this message type by specification and absent in this message instance.
  3. Define for this message type by specification and present in this message instance.

In the 1st case method throws an Utils::Exception exception. In the 2nd case method returns "false". In the 3rd case method returns "true" and value is stored in out parameter.

try {
    Engine::FIXMessage* pMsg = Engine::FIXMsgProcessor::singleton()->parse(aRawMessage);

    // ...

    Engine::FIXFieldValue val;
    if( pMsg->get( FIXField::ClOrdID, &val ) ) {
        cout << std::string(val.data_, val.length_) << endl;
}
catch( const Utils::Exception& ex ) {
    cout << "ERROR: " << ex.what() << endl;
}

Set field

To set a field value, use the bool Engine::FIXMessage::set(int tag, const Engine::FIXFieldValue &value) method.

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

Method throws Utils::Exception exception if it cannot be executed (e.g. the given tag is not defined for this message type).

try {
    Engine::FIXMessage* pMsg = Engine::FIXMsgProcessor::singleton()->parse(aRawMessage);

    // ...

    pMsg->set(FIXField::ClOrdID, "90001008"); 
}
catch( const Utils::Exception& ex ) {
    cout << "ERROR: " << ex.what() << endl;
}

Remove field

To remove a field by tag, use the bool Engine::FIXMessage::remove(int tag) method.

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

try {
    Engine::FIXMessage* pMsg = Engine::FIXMsgProcessor::singleton()->parse(aRawMessage);

    // ...

    pMsg->remove(FIXField::ClOrdID); 
}
catch( const Utils::Exception& ex ) {
    cout << "ERROR: " << ex.what() << endl;
}

Repeating group

To work with Repeating Groups there is Engine::FIXGroup cover class. This class does not have public constructor, but it is possible to get a pointer to its object using the Engine::FIXGroup::getGroup(int aTag) method of the Engine::FIXMessage class object, where aTag is a tag, corresponding to the group (leading tag), a pointer to which can be obtained. On completing the work with the object, it can be removed using the Engine::FIXGroup::release(Engine::FIXGroup* apGroup) static method of the Engine::FIXGroup class, where apGroup is a pointer to the object.

When setting the new value to the tag determining group size, the object is re-created and old field values inside the group are erased.

Example:

// create a new message
Engine::FIXMessage* pMsg = Engine::FIXMsgFactory::singleton()->newSkel(Engine::FIX42, "i");
// ...
// get the pointer to the group object
Engine::FIXGroup *pGroup = pMsg->getGroup(Engine::FIXField::NoQuoteSets);  // tag 296
// pGroup is NULL because this message does not contain a FIX group so far
clog << "pGroup=" << pGroup << endl;
// ...
// create a new group of three elements
pMsg->set(Engine::FIXField::NoQuoteSets, 3); 
pGroup = pMsg->getGroup(Engine::FIXField::NoQuoteSets);// pGroup is not NULL because now this message contains a FIX group

clog << "pGroup=" << pGroup << endl;
The Engine::FIXGroup class contains methods to work with message fields, similar to those existing in the Engine::FIXMessage class, however in contrast to them, there is the additional argument defining index (a sequence number starting with 0) of the group entry, for example:

The listed methods allow getting cover class for embedded groups.

To remove Repeating Group the method Engine::FIXMessage::remove(int tag) must be used, where tag is a Repeating Group Leading Tag. Setting corresponding tag to zero is not allowed (Parser Exception is thrown).

In case of specifying non-existing or invalid values for the arguments of these methods, corresponding exceptions are thrown.

User defined fields

User Defined Fields (the tag numbers 5000 to 9999) are handled like ordinary fields.

For example:

int theCustomTag = 5000; // reserved for user defined fields
// generates a new skeleton for a FIX message
Engine::FIXMessage* pFIXMessage = Engine::FIXMsgFactory::singleton()->newSkel(Engine::FIX42, "D");
pFIXMessage->set(theCustomTag , "0.15"); // sets the tag's value

Clone message

To clone FIX message, use the Engine::FIXMsgProcessor::clone(const Engine::FIXMessage &inMsg) method.
Engine::FIXMessage* pMessage = Engine::FIXMsgFactory::singleton()->newSkel(Engine::FIX42, "D");
Engine::FIXMessage* pMessageCopy = Engine::FIXMsgProcessor::singleton()->clone(*pMessage);
Engine::FIXMessage::release(pMessage);
Engine::FIXMessage::release(pMessageCopy);

Release message

To deallocate resources used by FIX message, use the Engine::FIXMessage::release(Engine::FIXMessage *apMsg) method.

For example:

FIXMessage *pFIXMessage = FIXMsgProcessor::singleton()->parse(rawMsg);
cout << "pFIXMessage: " << *pFIXMessage->toString() << endl;
   
// Cloning FIXMessage
FIXMessage *pClonedFIXMessage = FIXMsgProcessor::singleton()->clone(*pFIXMessage);
cout << "pClonedFIXMessage: " << *pClonedFIXMessage->toString() << endl;
    
// The user is responsible for the deallocation
FIXMessage::release(pClonedFIXMessage);
FIXMessage::release(pFIXMessage);

Utils::AutoPtr can be used to get rid of manual reallocation.

Engine::FIXMessage* pMessage = Engine::FIXMsgFactory::singleton()->newSkel(Engine::FIX42, "D");
{
    Utils::AutoPtr<FIXMessage> apMessageCopy( Engine::FIXMsgProcessor::singleton()->clone(*pMessage), &FIXMessage::release );
    int size = 0;
    const char *buf = apMessageCopy->toRaw(&size);
    cout << "Copied message will be destroyed automatically. " << std::string(buf, size) << endl;
}
Engine::FIXMessage::release(pMessage);

Generated on Fri Apr 17 12:26:09 2009 for B2BITS FIX Antenna C++ by  doxygen 1.5.6