Creating a FIX application is as easy as implementing the
QuickFIX Application interface. The C++ interface is defined in
the following code segment:
See this code in
PYTHON,
RUBY
namespace FIX
{
class Application
{
public:
virtual ~Application() {};
virtual void onCreate( const SessionID& ) = 0;
virtual void onLogon( const SessionID& ) = 0;
virtual void onLogout( const SessionID& ) = 0;
virtual void toAdmin( Message&, const SessionID& ) = 0;
virtual void toApp( Message&, const SessionID& )
throw( DoNotSend ) = 0;
virtual void fromAdmin( const Message&, const SessionID& )
throw( FieldNotFound, IncorrectDataFormat, IncorrectTagValue, RejectLogon ) = 0;
virtual void fromApp( const Message&, const SessionID& )
throw( FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType ) = 0;
};
}
These methods act as callbacks from your FIX
sessions.
onCreate is called when quickfix creates a new
session. A session comes into and remains in existence for
the life of the application. Sessions exist whether or not a
counter party is connected to it. As soon as a session is
created, you can begin sending messages to it. If no one is
logged on, the messages will be sent at the time a connection
is established with the counterparty.
onLogon notifies you when a valid logon has
been established with a counter party. This is called when a
connection has been established and the FIX logon process has
completed with both parties exchanging valid logon
messages.
onLogout notifies you when an FIX session is no
longer online. This could happen during a normal logout
exchange or because of a forced termination or a loss of
network connection.
toAdmin provides you with a peek at the
administrative messages that are being sent from your FIX
engine to the counter party. This is normally not useful for
an application however it is provided for any logging you may
wish to do. Notice that the FIX::Message is not const. This
allows you to add fields to an adminstrative message before
it is sent out.
toApp is a callback for application messages
that are being sent to a counterparty. If you throw a
DoNotSend exception in this function, the application
will not send the message. This is mostly useful if the
application has been asked to resend a message such as an
order that is no longer relevant for the current market.
Messages that are being resent are marked with the
PossDupFlag in the header set to true; If a
DoNotSend exception is thrown and the flag is set to
true, a sequence reset will be sent in place of the message.
If it is set to false, the message will simply not be sent.
Notice that the FIX::Message is not const. This allows you to
add fields to an application message before it is sent
out.
fromAdmin notifies you when an administrative
message is sent from a counterparty to your FIX engine. This
can be usefull for doing extra validation on logon messages
like validating passwords. Throwing a RejectLogon
exception will disconnect the counterparty.
fromApp receives application level request. If
your application is a sell-side OMS, this is where you will
get your new order requests. If you were a buy side, you
would get your execution reports here. If a
FieldNotFound exception is thrown, the counterparty
will receive a reject indicating a conditionally required
field is missing. The Message class will throw this exception
when trying to retrieve a missing field, so you will rarely
need the throw this explicitly. You can also throw an
UnsupportedMessageType exception. This will result in
the counterparty getting a reject informing them your
application cannot process those types of messages. An
IncorrectTagValue can also be thrown if a field
contains a value you do not support.
The sample code below shows how you might start up a FIX
acceptor which listens on a socket. If you wanted an initiator,
you would replace the acceptor in this code fragment with a
SocketInitiator.
See this code in
PYTHON,
RUBY
#include "quickfix/FileStore.h"
#include "quickfix/FileLog.h"
#include "quickfix/SocketAcceptor.h"
#include "quickfix/Session.h"
#include "quickfix/SessionSettings.h"
#include "quickfix/Application.h"
int main( int argc, char** argv )
{
try
{
if(argc < 2) return 1;
std::string fileName = argv[1];
FIX::SessionSettings settings(fileName);
MyApplication application;
FIX::FileStoreFactory storeFactory(settings);
FIX::FileLogFactory logFactory(settings);
FIX::SocketAcceptor acceptor
(application, storeFactory, settings, logFactory /*optional*/);
acceptor.start();
// while( condition == true ) { do something; }
acceptor.stop();
return 0;
}
catch(FIX::ConfigError& e)
{
std::cout << e.what();
return 1;
}
}