Preface
This page contains information about Decorators, also known as Object Model - convenient wrappers around raw, "flat" FixMessages. By using Decorators developers gain strongly typed access to all available properties of a message, that increases development speed (you write less code to read/write to message properties) and reduces the number of validation errors (because each decorated message class contains only properties that are relevant to this class).
Decorators do not add any performance overhead and their performance is comparable with that of Engine::FixMessage class.
What is overhead of using FIX Object Model over raw FIX Messages?
In terms of memory every message in Object Model requires additional 12 bytes per message field. Repeating groups require additional 24 bytes, plus 8 additional bytes for every entry.
In terms of performance the overhead is negligible.
Getting started
Using decorators in your project
To use Decorator you should:
Generate decorator files for your set of dictionaries, as described in tools/decorator-generator/readme.txt;
In examples below it is assumed that Decorator for standard FIX.4.4 is used and it's generated sources are placed in 'generated' folder,
using following command: b2b_fix_msgs_generator2.exe -s FIX44 -a FIX44 -o ../generated -f ../../../data/fixdic44.xmlNote
In case of processing additional dictionary, the base dictionary should be place before additional one, e.g.:
b2b_fix_msgs_generator2.exe -s FIX44 -a FIX44 -o ../generated -f ../../../data/fixdic44.xml ../../../data/additional_fix44.xml
- Either add files from generated/src and generated/headers folders to your project, or build shared/static library from them;
- Optional. Add a folder for your convenience.
- Add generated files to project:
- Add path to generated headers as additional include directory:
- Add regular FIX Antenna library as dependency:
- Add preprocessor definitions:
- In case you are incorporating decorator sources in your application or static library, or if you are using decorator static library in your application, please add V12_DECORATOR_IMPL preprocessor definition.
- In case you are building shared library from decorator sources please add V12_DECORATOR_EXPORTS.
- In case you are building application with use of shared library from case ii - you need no additional definitions.
- Optional. Add a folder for your convenience.
- In your code add following includes:
#include <FixMessages/FIX44/AllMessages.h>
#include <FixMessages/FIX44/Tags.h>
#include <FixMessages/FIX44/Enums.h>
- Done! Now you can find FIX.4.4 Decorator API under
FixMessages::FIX44
namespace.
The b2b_fix_msgs_generator2 is available under Linux as well.
How do I...
... Put decorators under custom namespace?
The generated object model is put under same namespace as id attribute of fixdic element of corresponding xml dictionary.
For example, if you have defined your custom dictionary like that:
<fixdics> <update> <fixdic fixversion="4.2" id="MS_FIX42" parent_id="FIX42" title="Morgan Stanley FIX 4.2" date="20170303" revision="0.0.0.1"> ... </fixdic> </update> </fixdics>
Then run command: b2b_fix_msgs_generator2.exe -s MS_FIX42 -a MS_FIX42 -f ../../data/fixdic42.xml ../../data/additional_ms_42.xml,
and your generated code will be placed under MS_FIX42 namespace.
... Create new message using decorator?
You can use corresponding C++ classes to create message of specific FIX type.
You can set message's fields using named field accessors.
You can convert decorator message object to flat FIXMessage using get() method.
#include <FixMessages/FIX44/AllMessages.h> #include <FixMessages/FIX44/Tags.h> #include <FixMessages/FIX44/Enums.h> using namespace FixMessages::FIX44; //... NewOrderSingleMessage order; order.ClOrdID().set( "12304" ); order.Side().set( '1' ); order.Symbol().set( "MSFT" ); order.TransactTime().set( UTCTimestampType::now() ); order.OrderQty().set( 10 ); order.OrdType().set( '2' ); order.Price().set( 1.25 ); order.check(); cout << "To 'Buy 10 MSFT @ 1.25' use FIX message:" << endl << order.raw() << endl; pSession->put( order.get() );
Also please refer to BusinessScenariosExamples.cpp from samples/Decorator sample for more examples.
... Get data from received message using decorator?
You can construct corresponding C++ objects from flat FIXMessages.
You can get message's fields using named field accessors.
#include <FixMessages/FIX44/AllMessages.h> #include <FixMessages/FIX44/Tags.h> #include <FixMessages/FIX44/Enums.h> using namespace FixMessages::FIX44; //... virtual bool Engine::Application::process(const Engine::FIXMessage & msg, const Engine::Session &aSn) { if( MsgType::NEW_ORDER_SINGLE == msg.type() ) { NewOrderSingleMessage order ( &msg ); cout << "Got New Order - Single:" << " ClOrdID=" << order.ClOrdID().get() << "; Side=" << order.Side().get() << "; Symbol=" << order.Symbol().get() << "; TransactTime=" << order.TransactTime().get() << "; OrderQty=" << order.OrderQty().get() << "; OrdType=" << order.OrdType().get() << "; Price=" << order.Price().get() <<endl; // Don't forget to release flat FIXMessage 'msg', // since it was provided by 'process' callback, // and it's memory is managed by Engine. order.release(); } return true; }
... Operate Repeating Groups with decorator?
To access 'Abc' RepeatingGroup within 'Xyz' message, you should use Xyz::AbcGroupRef handle.
You can access group entries using index operator [] on GroupRef handle;
You can resize group using resize method.
Please see example below:
#include <FixMessages/FIX44/AllMessages.h> #include <FixMessages/FIX44/Tags.h> #include <FixMessages/FIX44/Enums.h> using namespace FixMessages::FIX44; //... MarketDataRequestMessage req; req.MDReqID().set( "100112" ); req.SubscriptionRequestType().set( SubscriptionRequestType::SNAPSHOT ); req.MarketDepth().set( MarketDepth::FULL_BOOK ); req.MDUpdateType().set( MDUpdateType::INCREMENTAL_REFRESH ); MarketDataRequestMessage::MDEntryTypesGroupRef typeGrp = req.MDEntryTypes(); typeGrp.resize( 2 ); typeGrp[0].MDEntryType().set( MDEntryType::BID ); typeGrp[1].MDEntryType().set( MDEntryType::OFFER ); MarketDataRequestMessage::RelatedSymGroupRef relData = req.RelatedSym(); relData.resize( 2 ); relData[0].Symbol().set( "IBM" ); relData[1].Symbol().set( "MSFT" ); req.check(); cout << "To 'Subscribe for Market Data updates' use FIX message:" << endl << req.raw() << endl;
Also please refer to BusinessScenariosExamples.cpp from samples/Decorator sample for more examples.
... Manage decorated message's memory?
The decorated message owns corresponding flat FIXMessage and will delete it in destructor.
You may release ownership of underlying flat message using release method of decorated message.