CME GLOBEX Quick start
These chapters describe the creation of a simple CME application step-by step with samples.
Follow these instructions to get it to work:
- Initialize FIX engine
- Create MDApplication
- Subscribe to symbol
- Process incoming market data
- Unsubscribe from symbol
- Destroy MDApplication
- Destroy engine (release resources)
Engine initialization
Execute the following instruction to initialize FIX engine.
// Initializes engine. Engine::FixEngine::init();
The engine.properties file is required to read the engine configuration parameters. It must, by default, be present in the current directory. If the file is located elsewhere or has a different name specify the properties file name and path explicitly.
// Initializes engine.
Engine::FixEngine::init ("engine.properties");
If an error occurs during initialization (the properties file is not found, a required property is missing etc.) the exception will be thrown.
// Initializes engine.
try {
Engine::FixEngine::init("engine.properties");
}
catch( const Utils::Exception& ex ) {
cout << "ERROR: " << ex.what() << endl;
}
MDApplication creation
You can create an MDApplication in three steps:
- Create Listener
- Configure MDApplications parameters
- Create an MDApplication object
// Class Listener implements a MDApplicationListener interfaces
class Listener : public Globex::MDApplicationListener
{
Globex::MDApplication* application_;
public:
Listener() : application_(NULL)
{
// Initialize parameters
Globex::MDApplicationParams params;
params.templatesFn_ = "templates.xml";
params.configXml_ = "config.xml";
// Create MDApplication object
application_ = Engine::FixEngine::singleton()->createMDApplication( listener, params );
}
// MDApplicationListener interface implementation
// ...
};
- MDApplicationParams::templatesFn_ - Path to the CME FAST templates file. Should be downloaded from ftp://ftp.cmegroup.com
- MDApplicationParams::configXml_ - Path to the CME configuration file. Should be downloaded from ftp://ftp.cmegroup.com
Prior to calling createMDApplication, create a Listener, a class that implements Globex::MDApplicationListener interface. Usually this interface is implemented by classes that aggregate an MDApplication.
Subscribing and unsubscribing
You will start receiving market data from CME only after you subscribe to a symbol you want to receive. Use the MDApplication::subscribe(Symbol const& symbol) method for that:
application_->subscribe("ESZ8");
The Listener will be notified about subscription by calling the MDApplicationListener::onSubscribed callback:
Listner::onSubscribed( Globex::Symbol const& symbol ) {
std::cout << "Subscribed on " << symbol << std::endl;
}
Use MDApplication::unsubscribe(Symbol const& symbol) method to unsubscribe from symbol:
application_->unsubscribe("ESZ8");
When you unsubscribe from symbol, the engine calls the MDApplicationListener::onUnsubscribed( Globex::Symbol const& symbol ) notification method.
Listner::onUnsubscribed( Globex::Symbol const& symbol ) {
std::cout << "Unsubscribed from " << symbol << std::endl;
}
MDApplication::subscribeAll() and MDApplication::unsubscribeAll() methods are not implemented in the current version of FIX Antenna.
Processing incoming marketdata:
When MDApplication receives a message with market data, it calls one of the callback functions of the Listener object. A class should implement Globex::MDApplicationListener interface to be used as Listener:
class MDApplicationListener
{
public:
virtual void onSubscribed( Symbol const& symbol );
virtual void onUnsubscribed( Symbol const& symbol );
virtual void process( Engine::FIXMessage const& msg );
virtual void onIncrement( Symbol const& symbol, Engine::TagValue const& entry ) = 0;
virtual void onSnapshot( Symbol const& symbol, Engine::FIXMessage const& msg ) = 0;
virtual void onSecurityDefinition( Symbol const& symbol, Engine::FIXMessage const& msg ) = 0;
virtual ~MDApplicationListener();
};
- void onSubscribed() - called when successfully subscribed to symbol
- void onUnsubscribed() - called when successfully unsubscribed from symbol
- void onSnapshot() - called when a Market Data Snapshot Full Refresh (35=W) FIX message received.
- void onIncrement() - called when a Market Data Incremental Refresh (35=X) FIX Message received. According to FIX Messages specification, each incremental message can include information about several instruments. MDApplicationListener::onIncrement will be called separately for each instrument received.
- void onSecurityDefinition() - called when a Security Definition (35=d) FIX Message received.
- process() - called when any other FIX Message type received.
The Listener must be destroyed after MDApplication. It is recommended to turn a class-holder for MDApplication into the Listener. That will ensure a correct destruction order.
Releasing resources
Use the MDApplication::release() method to release the resources consumed by MDApplication. Calling MDApplication::unsubscribe(const std::string& symbol) is optional.
Full sample
The sample below illustrates all above mentioned instructions combined in one application.
#include <iostream>
#include <string>
#include <B2BITS_FixEngine.h>
#include <B2BITS_MDApplication.h>
class CmeClient : public Globex::MDApplicationListener {
Globex::MDApplication* application_;
CmeClient()
: application_( NULL )
{
Globex::MDApplicationParams params;
params.templatesFn_ = "templates.xml";
params.configXml_ = "config.xml";
application_ = Engine::FixEngine::singleton()->createMDApplication( this, params );
}
void subscribe( std::string const& symbol )
{
application_->subscribe( symbol );
}
void unsubscribe( std::string const& symbol )
{
application_->unsubscribe( symbol );
}
CmeClient::~CmeClient()
{
application_->release();
application_ = NULL;
}
void onSubscribed( Globex::Symbol const& symbol )
{
std::cerr << "Subscribed to " << symbol << std::endl;
}
void onUnsubscribed( Globex::Symbol const& symbol )
{
std::cerr << "Unsubscribed from " << symbol << std::endl;
}
void process( Engine::FIXMessage const& msg )
{
std::cerr << "Incoming message " << msg.type().toString() << std::endl;
std::cerr << std::endl;
}
void onSecurityDefinition( Globex::Symbol const& symbol, Engine::FIXMessage const& msg )
{
std::cerr << "SecurityDefinition for '" << symbol << "' received" << std::endl;
}
void onSnapshot( Globex::Symbol const& symbol, Engine::FIXMessage const& W_msg )
{
std::cerr << "Snapshot for '" << symbol << "' received" << std::endl;
}
void onIncrement( Globex::Symbol const& symbol, Engine::TagValue const& entry )
{
std::cerr << "Increment for '" << symbol << "' received" << std::endl;
}
};
int main( int argc, char* argv[] )
{
try
{
// Initialize engine.
Engine::FixEngine::init();
// Create Application instance
CmeClient application;
// Subscribe for symbol
application.subscribe("ESZ8");
// Waiting
char c;
std::cin >> c;
// Unsubscribe from symbol
application.unsubscribe("ESZ8");
// release resources
application.release();
Engine::FixEngine::destroy();
}
catch( const Utils::Exception& ex )
{
cout << " ERROR: " << ex.what() << endl;
return -1;
}
return 0;
}