// Initializes engine.
FixEngine::init();
By default the engine.properties file is tried to be located to read the engine configuration parameters. If file is not in the current directory or has different name it is possible to specify explicitely properties file name and path
// Initializes engine. FixEngine::init("engine.properties");
If error appears during initialization (properties file is not found, required property is missing, etc.) then exception is thrown.
// Initializes engine. try { FixEngine::init("engine.properties"); } catch( const Utils::Exception& ex ) { cout << "ERROR: " << ex.what() << endl; }
// Declare Application - FIX session observer class MyApplication : public Engine::Application { // set of virtual methods them must be overriden virtual bool process(const FIXMessage& msg, const Session& sn) { return true; } virtual bool onResend(const FIXMessage& msg, const Session& sn) { return true; } virtual void onLogonEvent(const LogonEvent* event, const Session& sn) {} virtual void onLogoutEvent(const LogoutEvent* event, const Session& sn) {} virtual void onUnexpectedMessageEvent(const UnexpectedMessageEvent* apEvent, const Session& aSn) {} virtual void onSequenceGapEvent(const SequenceGapEvent* event, const Session& sn) {} virtual void onSessionLevelRejectEvent(const SessionLevelRejectEvent* event, const Session& sn) {} virtual void onMsgRejectEvent(const MsgRejectEvent* event, const Session& sn) {} virtual void onHeartbeatWithTestReqIDEvent(const HeartbeatWithTestReqIDEvent& event, const Session& sn) {} virtual void onResendRequestEvent(const ResendRequestEvent& event, const Session& sn) {} virtual void onNewStateEvent(const NewStateEvent& event, const Session& sn) {} virtual void onUnableToRouteMessage(const UnableToRouteMessageEvent& event, const Session& sn) {} }; // Create Application instance MyApplication application; // Create FIX session instance Engine::Session* pSA = Engine::FixEngine::singleton()->createSession(&application, "Sender", "Target", Engine::FIX44); // Connect session as acceptor pSa->connect();
// Declare Application - FIX session observer class MyApplication : public Engine::Application { // set of virtual methods them must be overriden virtual bool process(const FIXMessage& msg, const Session& sn) { return true; } virtual bool onResend(const FIXMessage& msg, const Session& sn) { return true; } virtual void onLogonEvent(const LogonEvent* event, const Session& sn) {} virtual void onLogoutEvent(const LogoutEvent* event, const Session& sn) {} virtual void onUnexpectedMessageEvent(const UnexpectedMessageEvent* apEvent, const Session& aSn) {} virtual void onSequenceGapEvent(const SequenceGapEvent* event, const Session& sn) {} virtual void onSessionLevelRejectEvent(const SessionLevelRejectEvent* event, const Session& sn) {} virtual void onMsgRejectEvent(const MsgRejectEvent* event, const Session& sn) {} virtual void onHeartbeatWithTestReqIDEvent(const HeartbeatWithTestReqIDEvent& event, const Session& sn) {} virtual void onResendRequestEvent(const ResendRequestEvent& event, const Session& sn) {} virtual void onNewStateEvent(const NewStateEvent& event, const Session& sn) {} virtual void onUnableToRouteMessage(const UnableToRouteMessageEvent& event, const Session& sn) {} }; // Create Application instance MyApplication application; // Create FIX session instance Engine::Session* pSI = Engine::FixEngine::singleton()->createSession(&application, "Sender", "Target", Engine::FIX44); // Connect session as initiator pSI->connect(30, "127.0.0.1", 9106);
The flat model is based on single FIXMessage interfaces and exports high performance.
// create FIX 4.4 New Order Single Engine::FIXMessage* pOrder = Engine::FIXMsgFactory::singleton()->newSkel(Engine::FIX44, "D"); // set ClOrdID pMessage->set( FIXField::ClOrdID, "USR20000101" ); // get ClOrdID Engine::FIXFieldValue clOrdID; bool isPresent = pMessage->set( FIXField::ClOrdID, &clOrdID );
The object model is a typified interface less efficient than flat model however more user-friendly.
// create FIX 4.4 New Order Single FIX44::NewOrderSingle order( Engine::FIXMsgFactory::singleton()->newSkel(Engine::FIX44, "D") ); // set ClOrdID order.ClOrdID().set( "USR20000101" ); // get ClOrdID bool isPresent = !order.ClOrdID().isEmpty(); string clOrdID = order.ClOrdID();
// Send order to session initiator pSI->put( pOrder); // Send order to session acceptor pSA->put( order.get() );
virtual bool Engine::Application::process(const FIXMessage &, const Session &aSn)
virtual void Engine::Application::onResendRequestEvent(const ResendRequestEvent &,const Session &) ...
To process incoming messages, create a class that is the Application class heir, and override the Application::process method in this class. If the incoming message is successfully processed, the method must return "true", if the message cannot be processed at the moment, it must return "false".
If the Engine::Application::process method does not return "true" (i.e. returns "false" or throws an exception), the FIX engine tries to deliver the first unprocessed message a specified number of times (DelayedProcessing.MaxDeliveryTries) in the interval, specified in the FE configuration (DelayedProcessing.DeliveryTriesInterval). If the number of unsuccessful attempts is exceeded the MaxDeliveryTries, the Logout message with the "Application is not available" cause indication is sent back.
It is also necessary to override the onLogonEvent, onLogoutEvent, onSequenceGapEvent, onSessionLevelRejectEvent and other methods. These are the call-back methods called to notify about the corresponding session-level events.
The Engine::Application::process method is called only in case of the delivery of an incoming application-level message or a Reject message. All other session-level messages are handled inside the FE.
Note: If it is necessary to use the received application message outside the Engine::Application::process method, use a clone of the original message (see the Engine::FIXMsgProcessor::clone method).
For example:
class Appl : public Engine::Application{ public: virtual bool process(const FIXMessage & aMsg, const Engine::Session& aSn) { clog << "aMsg: " << *aMsg.toString() << endl; return true; } virtual void onLogonEvent(const LogonEvent* apEvent, const Session& aSn) { clog << "LogonEvent, the Logon message was received: " << apEvent->m_pLogonMsg->toString() << endl; } virtual void onLogoutEvent(const LogoutEvent* apEvent, const Session& aSn) { clog << "LogoutEvent, the Logout message was received: " << apEvent->m_pLogoutMsg->toString() << endl; } virtual void onSequenceGapEvent(const SequenceGapEvent* apEvent, const Session& aSn) { clog << "SequenceGapEvent" << endl; } virtual void onSessionLevelRejectEvent(const SessionLevelRejectEvent* apEvent, const Session& aSn) { clog << "SessionLevelRejectEvent" << endl; } virtual void onMsgRejectEvent(const MsgRejectEvent* event, const Session& sn){ clog << "MsgRejectEvent" << endl; } virtual void onResendRequestEvent(const ResendRequestEvent &,const Session &) { clog << "ResendRequestEvent" << endl; } virtual void onNewStateEvent(const NewStateEvent &,const Session &) { clog << "NewStateEvent" << endl; } virtual void onUnableToRouteMessage(const UnableToRouteMessageEvent &,const Session &) { clog << "UnableToRouteMessage" << endl; } virtual bool onResend(const FIXMessage &,const Session &) { clog << "Resend" << endl; return true; } virtual void onHeartbeatWithTestReqIDEvent(const HeartbeatWithTestReqIDEvent &,const Session &) { clog << "HeartbeatWithTestReqIDEvent" << endl; } };
Note: The Application::process method must not be dead-locked or perform time-demanding operations.
Note: If a pointer to the same Application is transmitted to several sessions, being established, it is necessary to make the Application::process() method synchronised.
Warning: Do not delete the registered Application until you unregister it.
Session::disconnect( bool aMarkAsTerminated = true)
Session::disconnect( const std::string &aLogoutText, bool aMarkAsTerminated = true )
#include "B2BITS_V12.h" using namespace std; class MyApp : public Engine::Application { public: MyApp() {}; virtual bool process(const Engine::FIXMessage& fixMsg, const Engine::Session& aSn) { cout << fixMsg.toRaw() << endl; return true; } virtual void onLogonEvent(const Engine::LogonEvent* apEvent, const Engine::Session& aSn) {} virtual void onLogoutEvent(const Engine::LogoutEvent* apEvent, const Engine::Session& aSn) {} virtual void onMsgRejectEvent(const Engine::MsgRejectEvent* event, const Engine::Session& sn) {} virtual void onSequenceGapEvent(const Engine::SequenceGapEvent* apEvent, const Engine::Session& aSn) {} virtual void onSessionLevelRejectEvent(const Engine::SessionLevelRejectEvent* apEvent, const Engine::Session& aSn) {} virtual void onHeartbeatWithTestReqIDEvent(const Engine::HeartbeatWithTestReqIDEvent& event, const Engine::Session& sn) {} virtual void onResendRequestEvent(const Engine::ResendRequestEvent& event, const Engine::Session& sn) {} virtual void onNewStateEvent(const Engine::NewStateEvent& event, const Engine::Session& sn) {} virtual void onUnableToRouteMessage(const Engine::UnableToRouteMessageEvent& event, const Engine::Session& sn) {} virtual bool onResend(const Engine::FIXMessage& msg, const Engine::Session& sn) { return true;} }; int main( int argc, char* argv[] ) { try { // Initialize engine. Engine::FixEngine::init(); // Create Application instance MyApp application; // Create FIX session instance Engine::Session* pSA = Engine::FixEngine::singleton()->createSession(&application, "Sender", "Target", Engine::FIX44); // Connect session as acceptor pSa->connect(); // Create FIX session instance Engine::Session* pSI = Engine::FixEngine::singleton()->createSession(&application, "Target", "Sender", Engine::FIX44); // Connect session as initiator pSI->connect(30, "127.0.0.1", 9106); // create FIX 4.4 New Order Single Engine::FIXMessage* pOrder = Engine::FIXMsgFactory::singleton()->newSkel(Engine::FIX44, "D"); // set ClOrdID pMessage->set( Engine::FIXField::ClOrdID, "USR20000101" ); pMessage->set( Engine::FIXField::HandlInst, "2"); pMessage->set( Engine::FIXField::Symbol, "IBM"); pMessage->set( Engine::FIXField::OrderQty, "200"); pMessage->set( Engine::FIXField::Side, "1"); pMessage->set( Engine::FIXField::OrdType, "5"); pMessage->set( Engine::FIXField::TimeInForce, "0"); // Send order to session initiator pSI->put( pOrder); // Close sessions pSI->disconnect(); pSA->disconnect(); // release resources Engine::FIXMessage::release(pMessage); pSA->registerApplication(NULL); pSI->release(); pSA->registerApplication(NULL); pSA->release(); Engine::FixEngine::destroy(); } catch( const Utils::Exception& ex ) { cout << " ERROR: " << ex.what() << endl; return -1; } catch( const std::exception& ex ) { cout << " ERROR: " << ex.what() << endl; return -1; } }
1.5.6