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);
This method retrives field value by tag number and stores it into instance of Engine::FIXFieldValue class. Field can be:
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; }
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; }
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; }
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 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.
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
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);
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);
1.5.6