Image Added
This section describes how to create a simple application step-by-step with code examples.
Follow instructions below to write, compile and run your first application with FIX Antenna C++. The main steps are:
- Initialize FIX engine
- Create session (initiator or acceptor)
- Send messages, process incoming messages
- Close session
- Destroy engine (release resources)
Engine initialization
Use the instruction below to initialize FIX engine.
Code Block |
---|
|
// Initialize engine.
FixEngine::init(); |
The "engine.properties" file contains common FIX engine configuration parameters. If full path is not specified FIX engine is looking in the current directory otherwise FIX engine uses full path to locate properties file.
codeOverview
This article will be of interest to those who are coming face to face with FIX Antenna for the first time, and want to get a hands-on understanding of it.
It will help those building their first FIX Antenna-based application be aware of the possibilities FIX Antenna provides.
Application
Typically, the FIX application provides FIX connectivity to multiple clients through transport protocols and offers possibilities to install, configure, administer and monitor trading information flows.
For example, assume that a user needs to build an app that will be able to establish and terminate sessions, and support a simple Order Flow, presented below:
Image Added
The main steps that need to be implemented in order to cover these functionalities are:
- Initialize the FIX Engine
- Create a session (initiator or acceptor)
- Send messages
- Process incoming messages
- Close the session
- Destroy the Engine (release resources)
The following section describes how to create the application step-by-step with code examples. Follow the instructions below to write, compile, and run your first application with FIX Antenna C++.
Engine initialization
Use the instruction below to initialize FIX Engine.
InitializesInitialize engine.
FixEngine::init(); |
The "engine.properties" file contains common FIX Engine configuration parameters. If the full path is not specified, the FIX Engine is looking in the current directory. Otherwise, the FIX Engine uses the full path to locate the properties file.
Code Block |
---|
|
// Initializes engine.
FixEngine::init("engine.properties"); |
If an error occurs during initialization (
e.g. for example, the properties file cannot not be found, or a required property is missing, etc.), the exception is thrown.
Code Block |
---|
|
// Initialize engine.
try {
FixEngine::init("engine.properties");
}
catch( const Utils::Exception& ex ) {
cout << "ERROR: " << ex.what() << endl;
} |
For more information about FIX
engine Session creation
Creation of session-acceptor
You can create a session acceptor in three steps:
Code Block |
---|
|
// Declare Application - FIX session observer
class MyApplication : public Engine::Application {
// Override several virtual methods
virtual bool process(const Engine::FIXMessage& msg, const Engine::Session& sn) {
return true;
}
virtual bool onResend(const Engine::FIXMessage& msg, const Engine::Session& sn) {
return true;
}
virtual void onLogonEvent(const Engine::LogonEvent* event, const Engine::Session& sn) {}
virtual void onLogoutEvent(const Engine::LogoutEvent* event, const Engine::Session& sn) {}
virtual void onUnexpectedMessageEvent(const Engine::UnexpectedMessageEvent* apEvent, const Engine::Session& aSn) {}
virtual void onSequenceGapEvent(const Engine::SequenceGapEvent* event, const Engine::Session& sn) {}
virtual void onSessionLevelRejectEvent(const Engine::SessionLevelRejectEvent* event, const Engine::Session& sn) {}
virtual void onMsgRejectEvent(const Engine::MsgRejectEvent* event, const Engine::Session& sn) {}
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) {}
};
// Create instance of Application
MyApplication application;
// Create instance of FIX session
Engine::Session* pSA = Engine::FixEngine::singleton()->createSession(&application, "Sender", "Target", Engine::FIX44);
// Connect session as acceptor
pSA->connect(); |
For more information about FIX session in general and FIX session acceptors description refer to the sections Session description and Creating FIX session acceptor.
Creation of session-initiator
You can create a session initiator in three steps:
Code Block |
---|
|
// Declare Application - FIX session observer
class MyApplication : publicThe sample below shows how to create a session acceptor if you need to use a custom FIX protocol version. Please note, that the same logic could be applied to a session initiator creation.
Code Block |
---|
|
{
Engine::Application* {pApp = nullptr;
// OverrideSet severalpApp virtualto methodsthe app instance pointer
virtual bool process(const Engine::FIXMessage& msg, const Engine::Session& sn) {
return true;
}
virtual bool onResend(const Engine::FIXMessage& msg, const Engine::Session& sn) {
return true;
}
virtual void onLogonEvent(const Engine::LogonEvent* event, const Engine::Session& sn) {}
virtual void onLogoutEvent(const Engine::LogoutEvent* event, const Engine::Session& sn) {}
virtual void onUnexpectedMessageEvent(const Engine::UnexpectedMessageEvent* apEvent, const Engine::Session& aSn) {}
virtual void onSequenceGapEvent(const Engine::SequenceGapEvent* event, const Engine::Session& sn) {}
virtual void onSessionLevelRejectEvent(const Engine::SessionLevelRejectEvent* event, const Engine::Session& sn) {}
virtual void onMsgRejectEvent(const Engine::MsgRejectEvent* event, const Engine::Session& sn) {}
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) {}
};
// Create instance of Application
MyApplication application;
// Create instance of FIX session
Engine::Session* pSI = Engine::SessionExtraParameters params;
params.sessionRole_ = Engine::ACCEPTOR_SESSION_ROLE;
Utils::ReferenceCounterSharedPtr<Engine::Session> pSession;
int method = 4;
switch (method)
{
case 0:
// Use the engine created standard FIXT11 parser created with the dictionaries provided with DictionariesFilesList property inside engine.properties file.
// Here are Engine::FIXT11 - scp version and Engine::FIX50SP2 default application version to use.
pSession = FixEngine::singleton()->createSession(pApp, "Sender", "Target", Engine::FIXT11, ¶ms, Engine::default_storageType, Engine::FIX50SP2);
break;
case 1:
// The same as 0 but chooses parser with its name.
pSession = FixEngine::singleton()->createSession(pApp, "Sender", "Target", "FIXT11", ¶ms, Engine::default_storageType, Engine::FIX50SP2);
break;
case 3:
// engine.properties contains parameter: AdditionalParsersList= MyParser@FIXT11:FIX50SP2.
// Use the engine on load created parser named 'MyParser' that has FIXT11 as scp and FIX50SP2 as a single application protocol.
pSession = FixEngine::singleton()->createSession(&applicationpApp, "Sender", "Target", "MyParser", ¶ms, Engine::FIX44default_storageType, Engine::FIX50SP2);
// Connect session as initiator
pSI->connect(30, "127.0.0.1", 9106); |
For more information about FIX session in general and FIX session initator description refer to the sections Session description and Creating FIX session initiator.
Creating new order
FIX Antenna provides two interfaces for FIX messages manipulations:
- Flat model
- Object model
The flat model is based on a simple get/set FIXMessage interface and demonstrates high performance.
Code Block |
---|
|
// create FIX 4.4 New Order Single skeleton
Engine::FIXMessage* pOrder = Engine::FIXMsgFactory::singleton()->newSkel(Engine::FIX44, "D");
// set ClOrdID
pOrder->set( FIXField::ClOrdID, "USR20000101" );
// get ClOrdID
Engine::FIXFieldValue clOrdID;
bool isPresent = pOrder->set( FIXField::ClOrdID, &clOrdID );
assert( isPresent );
// set trading session
// create repeating group with 1 entry
pOrder->set( FIXField::NoTradingSessions, 1 );
// get pointer to the repeating group
Engine::FIXGroup *pGroup = pOrder->getGroup(FIXFields::NoTradingSessions);
// set trading session ID for the 1st entry
pGroup->set( FIXField::TradingSessionID, "PRE-OPEN", 0 );
// set all required fields ... |
The object model is a typified interface that is less efficient but more user-friendly than the flat one.
Code Block |
---|
|
// 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(); |
For more information about FIX message and repeating groups refer to the sections Message description, Repeating Groups description and FIX Message.
Sending order
To send a message to the session you should call Engine::Session::put method. In fact this method does not send message but puts it to the queue, from which message will be sent out by separate thread. The method in its turn returns imeddiately. In other words sending is an asynchronous process in FIX Antenna, which also means that after method returns message is not necessaruly sent yet.
Code Block |
---|
|
// Send order (flat model) to session initiator
pSI->put( pOrder);
// Send order (object model) to session acceptor
pSA->put( order.get() ); |
For more information about sending messages refer to the sections Send message and Send message.
Processing incoming message
The Application class is responsible for:
- Processing incoming messages from the remote FIX Engine
Code Block |
---|
|
virtual bool Engine::Application::process(const Engine::FIXMessage &, const Engine::Session &aSn) |
- Processing session events (required only if default behavior is not suitable)
Code Block |
---|
|
virtual void Engine::Application::onResendRequestEvent(const Engine::ResendRequestEvent &,const Engine::Session &)
... |
Create a new class derived from the Application class and override the Application::process method in this class to process incoming messages. If an incoming message is successfully processed, the method should return "true", if the message cannot be processed at the moment, it should return "false". If the Engine::Application::process method does not return "true" (i.e. returns "false" or throws an exception), the engine passes the same incoming message to the Application::process again and again until either Engine::Application::process returns "true" or number of attempts is exceeded (DelayedProcessing.MaxDeliveryTries, refer to Common parameters for more information). The interval between attempts is specified by property DelayedProcessing.DeliveryTriesInterval (refer to Common parameters for more information). If the number of unsuccessful attempts exceeds the MaxDeliveryTries, a Logout message with the reason "Application is not available" is sent to the counterparty and session is closed. Other useful methods to override are: Engine::Application::onLogonEvent, Engine::Application::onLogoutEvent,Engine::Application::onSequenceGapEvent, Engine::Application::onSessionLevelRejectEvent, etc. These are the call-back methods called to notify about the corresponding session-level events. Note that all pure virtual methods of Application must be overridden (implementation can be just empty body). The Engine::Application::process method is called only when application-level message is received. All session-level messages (Heartbeats, Test Requests, Resend Requests, etc.) are handled by FIX Antenna. However you can modify default behavior overriding call-back methods in Application and providing your own logic.
Note |
---|
if you need to keep FIX message for future processing create a copy of the message and save a copy instead of saving original message (refer to the Engine::FIXMsgProcessor::clone method). Below is an example of custom implementation of Engine::Application interface:
Code Block |
---|
|
class Appl : public Engine::Application{
public:
virtual bool process(const Engine::FIXMessage & aMsg, const Engine::Session& aSn break;
case 4:
{
// Create parser manually which is named 'MyFIXT11Parser' and has FIXT11 as scp and FIX50SP2 as a single application protocol.
// Here are:
// "MyFIXT11Parser" is name of the parser being created,
// "FIXT11" is id (id attribute in xml) of the scp(session control protocol) to be used,
// "FIX50SP2" is id (id attribute in xml) of the application protocol to be used.
auto parserID = FixEngine::singleton()->createFixParser("MyFIXT11Parser", "FIXT11", "FIX50SP2");
pSession = FixEngine::singleton()->createSession(pApp, "Sender", "Target", parserID, ¶ms, Engine::default_storageType, Engine::FIX50SP2/*base protocol version FIX50SP2EP is based on FIX50SP2 in this case*/);
break;
}
case 5:
// Pass desired protocols configuration via SessionExtraPrameters.
// The engine tries to find out suitable parser among already existing and chooses the first matching the requirements.
// The default application protocol is the first one declared, FIX50SP2 in this case.
params.parserVersion_ = "FIXT11:FIX50SP2";
pSession = FixEngine::singleton()->createSession(pApp, "Sender", "Target", Engine::NA, ¶ms);
break;
case 6:
// The same as 5 but with two possible application protocols FIX50SP2 and FIX44
params.parserVersion_ = "FIXT11:FIX50SP2,FIX44";
pSession = FixEngine::singleton()->createSession(pApp, "Sender", "Target", Engine::NA, ¶ms);
break;
case 7:
// The same as 3 but pass parser name via SessionExtraPrameters, plesae note @ at the end, it indicate that it is parser name but not protocols configuration.
// The default application protocol is the first one declared for the 'MyParser', FIX50SP2 in this case.
params.parserVersion_ = "MyParser@";
pSession = FixEngine::singleton()->createSession(pApp, "Sender", "Target", Engine::NA, ¶ms);
break;
case 8:
// Get session parameters from engine.properties
pSession = FixEngine::singleton()->createSession(pApp, "Sender", "Target", Engine::NA);
break;
}
pSession->connect();
}
|
For more information about FIX sessions in general and a FIX session acceptor description, refer to the sections: Session description and Creating FIX session acceptor.
Creation of session-initiator
You can create a session initiator in three steps:
Code Block |
---|
|
// Declare Application - FIX session observer
class MyApplication : public Engine::Application {
// Override several virtual methods
virtual bool process(const Engine::FIXMessage& msg, const Engine::Session& sn) {
return true;
}
virtual bool onResend(const Engine::FIXMessage& msg, const Engine::Session& sn) {
return true;
}
virtual void onLogonEvent(const Engine::LogonEvent* event, const Engine::Session& sn) {}
virtual void onLogoutEvent(const Engine::LogoutEvent* event, const Engine::Session& sn) {}
virtual void onUnexpectedMessageEvent(const Engine::UnexpectedMessageEvent* apEvent, const Engine::Session& aSn) {}
virtual void onSequenceGapEvent(const Engine::SequenceGapEvent* event, const Engine::Session& sn) {}
virtual void onSessionLevelRejectEvent(const Engine::SessionLevelRejectEvent* event, const Engine::Session& sn) {}
virtual void onMsgRejectEvent(const Engine::MsgRejectEvent* event, const Engine::Session& sn) {}
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) {}
};
// Create instance of Application
MyApplication application;
// Create instance of FIX session
Engine::Session* pSI = Engine::FixEngine::singleton()->createSession(&application, "Sender", "Target", Engine::FIX44);
// Connect session as initiator
pSI->connect(30, "127.0.0.1", 9106); |
For more information about FIX sessions in general and a FIX session initiator description, refer to the sections: Session description and Creating FIX session initiator.
Creating new order
FIX Antenna provides two interfaces for FIX message manipulations:
- Flat model
- Object model
The flat model is based on a simple get/set FIX Message interface and demonstrates high performance.
Code Block |
---|
|
// create FIX 4.4 New Order Single skeleton
Engine::FIXMessage* pOrder = Engine::FIXMsgFactory::singleton()->newSkel(Engine::FIX44, "D");
// set ClOrdID
pOrder->set( FIXField::ClOrdID, "USR20000101" );
// get ClOrdID
Engine::FIXFieldValue clOrdID;
bool isPresent = pOrder->set( FIXField::ClOrdID, &clOrdID );
assert( isPresent );
// set trading session
// create repeating group with 1 entry
pOrder->set( FIXField::NoTradingSessions, 1 );
// get pointer to the repeating group
Engine::FIXGroup *pGroup = pOrder->getGroup(FIXFields::NoTradingSessions);
// set trading session ID for the 1st entry
pGroup->set( FIXField::TradingSessionID, "PRE-OPEN", 0 );
// set all required fields ... |
The object model is a typified interface that is less efficient but more user-friendly than the flat one.
Code Block |
---|
|
// 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(); |
Sending order
To send a message to a session you should call on the Engine::Session::put method. This method does not send a message but instead puts it in a queue, from which the message will be sent out via a separate thread. The method in its turn returns immediately. In other words, sending is an asynchronous process in FIX Antenna, which also means that after the method returns the message it is not necessarily sent yet.
Code Block |
---|
|
// Send order (flat model) to session initiator
pSI->put( pOrder);
// Send order (object model) to session acceptor
pSA->put( order.get() ); |
Processing incoming message
The application class is responsible for:
- Processing incoming messages from a remote FIX Engine
Code Block |
---|
|
virtual bool Engine::Application::process(const Engine::FIXMessage &, const Engine::Session &aSn) |
- Processing session events (required only if default behavior is not suitable)
Code Block |
---|
|
virtual void Engine::Application::onResendRequestEvent(const Engine::ResendRequestEvent &,const Engine::Session &)
... |
To process incoming messages, create a new class derived from the Application class and override the Application::process method. If an incoming message is successfully processed, the method should return "true". If a message cannot be processed at the moment, it should return "false". If the Engine::Application::process method does not return "true" (i.e. returns "false" or throws an exception), the engine passes the same incoming message to the Application::process again and again until either the Engine::Application::process returns "true", or the permitted number of attempts is exceeded (DelayedProcessing.MaxDeliveryTries, refer to Common parameters for more information). The interval between attempts is specified by the DelayedProcessing.DeliveryTriesInterval property (refer to Common parameters for more information). If the number of unsuccessful attempts exceeds the amount specified by MaxDeliveryTries, a Logout message stating "Application is not available" is sent to the counter-party and the session is closed.
Other useful methods to override are: Engine::Application::onLogonEvent, Engine::Application::onLogoutEvent,Engine::Application::onSequenceGapEvent, Engine::Application::onSessionLevelRejectEvent, etc. These are the callback methods called on to notify about the corresponding session-level events. Note that all pure virtual methods of Application must be overridden (implementation can just be empty body). The Engine::Application::process method is called only when an application-level message is received. All session-level messages (Heartbeats, Test Requests, Resend Requests, etc.) are handled by FIX Antenna. However, you can modify default behavior and override callback methods in Application and provide your own logic.
Note |
---|
If you need to keep a FIX message for future processing, create and save a copy of the message instead of saving the original message. (Refer to the Engine::FIXMsgProcessor::clone method). Below is an example of a custom implementation of the Engine::Application interface: Code Block |
---|
| class Appl : public Engine::Application{
public:
virtual bool process(const Engine::FIXMessage & aMsg, const Engine::Session& aSn) {
std::clog << "aMsg: " << *aMsg.toString('|') << std::endl;
return true;
}
virtual void onLogonEvent(const Engine::LogonEvent* apEvent, const Engine::Session& aSn) {
std::clog << "LogonEvent, the Logon message was received: " << apEvent->m_pLogonMsg->toString() << std::endl;
}
virtual void onLogoutEvent(const Engine::LogoutEvent* apEvent, const Engine::Session& aSn) {
std::clog << "LogoutEvent, the Logout message was received: " << apEvent->m_pLogoutMsg->toString() << std::endl;
}
virtual void onSequenceGapEvent(const Engine::SequenceGapEvent* apEvent, const Engine::Session& aSn) {
std::clog << "SequenceGapEvent" << std::endl;
}
virtual void onSessionLevelRejectEvent(const Engine::SessionLevelRejectEvent* apEvent, const Engine::Session& aSn) {
std::clog << "SessionLevelRejectEvent" << std::endl;
}
virtual void onMsgRejectEvent(const Engine::MsgRejectEvent* event, const Engine::Session& sn){
std::clog << "MsgRejectEvent" << std::endl;
}
virtual void onResendRequestEvent(const Engine::ResendRequestEvent &,const Engine::Session &) {
std::clog << "ResendRequestEvent" << std::endl;
}
virtual void onNewStateEvent(const Engine::NewStateEvent &,const Engine::Session &) {
std::clog << "NewStateEvent" << std::endl;
}
virtual void onUnableToRouteMessage(const Engine::UnableToRouteMessageEvent &,const Engine::Session &) {
std::clog << "UnableToRouteMessage" << std::endl;
}
virtual bool onResend(const Engine::FIXMessage &,const Engine::Session &) {
std::clog << "Resend" << std::endl;
return true;
}
virtual void onHeartbeatWithTestReqIDEvent(const Engine::HeartbeatWithTestReqIDEvent &,const Engine::Session &) {
std::clog << "aMsg: " << *aMsg.toString('|') << "HeartbeatWithTestReqIDEvent" << std::endl;
return true;
}
virtual void onLogonEvent(const Engine::LogonEvent* apEvent, const Engine::Session& aSn) {
std::clog << "LogonEvent, the Logon message was received: " << apEvent->m_pLogonMsg->toString() << std::endl;
}
}; |
|
Warning |
---|
Do not delete the registered Application until you unregister it. For more information about processing incoming messages and the Application class, refer to the section with the Application description. |
Closing session
Use the following methods to close the session:
Code Block |
---|
|
Engine::Session::disconnect( bool forcefullyMarkAsTerminated = false ) |
Code Block |
---|
|
Engine::Session::disconnect( const std::string &logoutText, bool forcefullyMarkAsTerminated = false ) |
For more information about disconnecting, refer to the sections: Session description, Disconnect, and Disconnect.
Full sample
The sample below illustrates all instructions mentioned above, combined into one application.
Code Block |
---|
|
#include <iostream>
#include <memory>
#include <B2BITS_V12.h>
using namespace std;
class MyApp : public Engine::Application {
public:
MyApp() {}
virtual voidbool onLogoutEventprocess(const Engine:: LogoutEvent*FIXMessage& apEventfixMsg, const Engine::Session& aSn) {
std::clog cout << "LogoutEvent, the Logout message was received: " << apEvent->m_pLogoutMsg->toString() << std::endl;
} *fixMsg.toString('|') << endl;
return true;
}
virtual void onSequenceGapEventonLogonEvent(const Engine:: SequenceGapEventLogonEvent* apEvent, const Engine::Session& aSn) {
std::clogcout << " SequenceGapEventonLogonEvent" << std::endl;
}
virtual void onSessionLevelRejectEventonLogoutEvent(const Engine:: SessionLevelRejectEventLogoutEvent* apEvent, const Engine::Session& aSn) {
std::clogcout << " SessionLevelRejectEventonLogoutEvent" << std::endl;
}
virtual void onMsgRejectEvent(const Engine::MsgRejectEvent* event, const Engine::Session& sn) {
std::clogcout << " MsgRejectEventonMsgRejectEvent" << std::endl;
}
virtual void onResendRequestEventonSequenceGapEvent(const Engine:: ResendRequestEventSequenceGapEvent* &apEvent, const Engine::Session& &aSn) {
std::clogcout << " ResendRequestEventonSequenceGapEvent" << std::endl;
}
virtual void onNewStateEventonSessionLevelRejectEvent(const Engine:: NewStateEventSessionLevelRejectEvent* &apEvent, const Engine::Session& &aSn) {
std::clogcout << " NewStateEventonSessionLevelRejectEvent" << std::endl;
} }
virtual void onUnableToRouteMessageonHeartbeatWithTestReqIDEvent(const Engine:: UnableToRouteMessageEventHeartbeatWithTestReqIDEvent& &event, const Engine::Session& &sn) {
std::clogcout << " UnableToRouteMessageonHeartbeatWithTestReqIDEvent" << std::endl;
}
virtual boolvoid onResendonResendRequestEvent(const Engine:: FIXMessageResendRequestEvent& &event, const Engine::Session& &sn) {
std::clogcout << " ResendonResendRequestEvent" << std::endl;
return true;
}
virtual void onHeartbeatWithTestReqIDEventonNewStateEvent(const Engine:: HeartbeatWithTestReqIDEventNewStateEvent& &event, const Engine::Session& &sn) {
std::clogcout << " HeartbeatWithTestReqIDEventonNewStateEvent" << std::endl;
}
}; |
Warning |
---|
Do not delete the registered Application until you unregister it. For more information about processing incoming messages and Application class refer to the section Application description. |
Closing session
Use the following methods to close the session:
Code Block |
---|
|
Engine::Session::disconnect(boolforcefullyMarkAsTerminated=false ) Code Block |
---|
|
Engine::Session::disconnect( const std::string &logoutText, bool forcefullyMarkAsTerminated = false ) |
for more information about disconnect refer to the sections Session description, Disconnect, and Disconnect.
Full sample
The sample below illustrates all abovementioned instructions combined in one application.
Code Block |
---|
|
#include <iostream>
#include <memory>
#include <B2BITS_V12.h>
using namespace std;
class MyApp : public Engine::Application {
public:
MyApp() {virtual void onUnableToRouteMessage(const Engine::UnableToRouteMessageEvent& event, const Engine::Session& sn) {
cout << "onUnableToRouteMessage" << endl;
}
virtual bool |
processonResend(const Engine::FIXMessage& |
fixMsgmsg, const Engine::Session& |
aSn*fixMsg.toString('|') virtual void onLogonEvent(const Engine::LogonEvent* apEvent, const Engine::Session& aSn)int main( int argc, char* argv[] )
{
try
|
cout<<"onLogonEvent"<<endl;}virtualvoidonLogoutEvent(constLogoutEvent* apEvent, const Engine::Session& aSn) {
FixEngine::init();
// Create Application instance
|
cout<<"onLogoutEvent"<<endl;
}application;
// Create FIX session instance
|
virtualvoidonMsgRejectEvent(constMsgRejectEventevent,constSession& sn) {
cout << "onMsgRejectEvent" << endlsingleton()->createSession(&application, "Sender", "Target", Engine::FIX44);
|
}virtualvoidonSequenceGapEvent(const Engine::SequenceGapEvent* apEvent, const Engine::Session& aSn) {as acceptor
pSA->connect();
|
cout<<"onSequenceGapEvent"<<endl;// Create FIX session instance
|
}virtualvoidonSessionLevelRejectEvent(constSessionLevelRejectEventapEvent,constSession& aSn) {
cout << "onSessionLevelRejectEvent" << endl;
}singleton()->createSession(&application, "Target", "Sender", Engine::FIX44);
|
virtualvoidonHeartbeatWithTestReqIDEvent(constEngine::HeartbeatWithTestReqIDEvent& event, const Engine::Session& sn) { // Connect session as initiator
|
cout << "onHeartbeatWithTestReqIDEvent" << endlpSI->connect(30, "127.0.0.1", Engine::FixEngine::singleton()->getListenPort());
|
}virtualvoid onResendRequestEvent(const Engine::ResendRequestEvent& event, const Engine::Session& sn) {// create FIX 4.4 New Order Single
|
cout << "onResendRequestEvent" << endl; auto_ptr<Engine::FIXMessage> pOrder(pSI->newSkel("D"));
|
}virtualvoidonNewStateEvent(constEngine::NewStateEvent&event,constEngineSession& sn) {ClOrdID, "USR20000101" );
pOrder->set(FIXField::HandlInst, |
cout<<onNewStateEvent" << endl} virtual void onUnableToRouteMessage(const Engine::UnableToRouteMessageEvent& event, const Engine::Session& sn) {pOrder->set(FIXField::Symbol, "IBM");
|
cout <<pOrder->set(FIXField::OrderQty, " |
onUnableToRouteMessage" << endl} virtual bool onResend(const Engine::FIXMessage& msg, const Engine::Session& sn) {pOrder->set(FIXField::Side, "1");
pOrder->set(FIXField::OrdType, |
cout<<onResend<<endl; return true;pOrder->set(FIXField::TimeInForce, "0");
|
}
};
int main( int argc, char* argv[] )
{
//+++++++++++++++++++++
// Send order to session initiator
|
try{pSI->put(pOrder.get());
// |
Initializeengine.Engine::FixEngine::init// Create Application instancepSA->disconnect();
// release resources
|
MyAppapplication; // Create FIX session instancepSA->registerApplication(NULL);
pSI->release();
|
Engine::Session*pSA=Engine::FixEngine::singleton()->createSession(&application,"Sender","Target", Engine::FIX44 pSA->registerApplication(NULL);
|
// Connect session as acceptor pSA->connectEngine::FixEngine::destroy();
}
|
// Create FIX session instance catch(std::exception const& ex)
{
|
Engine::Session*pSI=Engine::FixEngine::singleton()->createSession(&application, "Target", "Sender", Engine::FIX44);
cout << " ERROR: " << ex.what() << endl;
|
//Connectsessionasinitiator pSI->connect(30, "127.0.0.1", Engine::FixEngine::singleton()->getListenPort());
// create FIX 4.4 New Order Single
auto_ptr<Engine::FIXMessage> pOrder(pSI->newSkel("D"));
// set ClOrdID
pOrder->set(FIXField::ClOrdID, "USR20000101" );
pOrder->set(FIXField::HandlInst, "2");
pOrder->set(FIXField::Symbol, "IBM");
pOrder->set(FIXField::OrderQty, "200");
pOrder->set(FIXField::Side, "1");
pOrder->set(FIXField::OrdType, "5");Scheduler QuickStart Guide
FIX Antenna Scheduler is a main events execution component to carry out scheduled actions, usually periodic ones (for example, every day at 9:30 AM), that defines the timeline of events. This component schedules events as required and notifies schedules when needed about the events that have occurred (refer to the Scheduler section of the FA Programmer's Guide).
The sample below shows how a FIX Antenna C++ user can create and configure the FIX Scheduler.
Code Block |
---|
|
// Initialize FE
...
// Get engine's maintained scheduler instance.
Scheduler* pScheduler = FixEngine::singleton()->getScheduler();
// Get configured sessions list.
Engine::FAProperties::ConfiguredSessionsMap sessions = FixEngine::singleton()->getProperties()->getConfiguredSessions();
// Iterate over sessions configured and bind them to schedules defined.
for(Engine::FAProperties::ConfiguredSessionsMap::const_iterator it = sessions.begin(); it != sessions.end(); ++it)
{
// Find Schedule
SessionsSchedulePtr pSchedule;
try
{
pSchedule = |
pOrderSessionsSchedulePtr(pScheduler- |
>set(FIXField::TimeInForce, "0">getSchedule(it->second.scheduleId_));
}catch(const |
//+++++++++++++++++++++System::SchedulerException&)
{
// |
SendordertosessioninitiatorpSI->put(pOrder.get());//ClosesessionspSI->disconnect();
pSA->disconnect();// The schedule is not Sessions schedule derived instance.
continue;
|
//releaseresources pSA->registerApplication(NULL); //Get session controller
FixEngineSessionsControllerPtr pSessionController = FixEngineSessionsControllerPtr |
pSI>release>getSessonsController());
if(!pSessionController)
|
pSA->registerApplication(NULL);pSA->release();
Engine::FixEngine::destroy();
// Sessions controller is not FixEngineSessionsController derived instance. So we can't use it.
|
}catch(std::exception const& ex){ // Register the session within |
cout<<"ERROR:"<< ex.what() << endl;
return -1;
}
}// myApp - instance of Engine::Application derived class that handles session callbacks.
pSessionController->registerSession(it->first, myApp, it->second);
} |
To use sessions scheduling, one should configure schedule(s) via the engine.properties file or via API.For more details see: Programmers Guide