Page tree
Skip to end of metadata
Go to start of metadata

These chapters describe the creation of a simple MICEX application step-by step with samples.

Follow these instructions to get it to work:

  • Initialize FIX engine
  • Create micex_mfix_application
  • Subscribe to symbol
  • Process incoming market data
  • Unsubscribe from symbol
  • Destroy micex_mfix_application
  • 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;
}

 

micex_mfix_application creation

You can create an micex_mfix_application in three steps:

  • Create a listener
  • Configure micex_mfix_application parameters
  • Create a micex_mfix_application object

 

// Class application_listener_impl implements a micex_mfix_application_listener interface
class application_listener_impl
    : public micex_mfix::micex_mfix_application_listener 
{
public:
    application_listener_impl()
    : app_(NULL)
    {
        micex_mfix::micex_mfix_application_params app_params;
        app_params.templates_fn_ = "./FIX50SP2.xml";
        app_params.config_xml_ = "./config.xml";
        app = Engine::FixEngine::singleton()->createMICEXApplication(app_params, this);
    }
    virtual void on_error(const std::string &error)
    {
        //add your processing code here
    }
    virtual void on_process(const Engine::FIXMessage &msg, const std::string &channel_id)
    {
        //add your processing code here
    }
    virtual void on_feed_reset(const std::string &channel_id, micex_mfix::mfix_feed_type feed_type)
    {
        //add your processing code here
    }
    virtual void on_heartbeat(const std::string &channel_id, micex_mfix::mfix_feed_type feed_type)
    {
        //add your processing code here
    }
    
private:
    micex_mfix::micex_mfix_application *app_;
};

 

  • micex_mfix::micex_mfix_application_params::templates_fn_ - Path to the MICEX FAST templates file. It can be specified as an URL address to the MICEX FTP server.
  • micex_mfix::micex_mfix_application_params::config_xml_ - Path to the MICEX configuration file. It can be specified as an URL address to the MICEX FTP server.

Prior to calling createMICEXApplication, create a listener, a class that implements micex_mfix::micex_mfix_application_listener interface. Usually this interface is implemented by classes that aggregate a micex_mfix::micex_mfix_application.

Subscribing and unsubscribing

MICEX uses four feeds to distribute the market data. Use

 

micex_mfix::micex_feed &order_book_feed = app->get_orderbook_feed();

 

or

 

micex_mfix::micex_feed &orders_feed = app->get_orders_feed();

 

or

 

micex_mfix::micex_feed &trades_feed = app->get_trades_feed();

 

or

 

micex_mfix::micex_feed &statistics_feed = app->get_statistics_feed();

 

to get a reference to a object that represents corresponding feed. Next, create an instument listener:

 

// Class instrument_listener_impl implements a micex_mfix::instrument_listener interface
class instrument_listener_impl
    : public micex_mfix::instrument_listener {
public:
    virtual bool on_security_definition(const micex_mfix::security_description &sec_desc,
                                        const micex_mfix::security_id &sec_id,
                                        const micex_mfix::symbol &symb,
                                        const std::string &board,
                                        const Engine::FIXMessage &d_msg,
                                        const std::string &channel_id)
    { 
        //add your processing code here, return your result true or false
        return false;
    }
    virtual void on_subscribed(const micex_mfix::symbol &symb, 
                               const std::string &board,
                               micex_mfix::mfix_feed_type feed_type)
    {
        //add your processing code here
    }
    virtual void on_unsubscribed(const micex_mfix::symbol &symb,
                                 const std::string &board,
                                 micex_mfix::mfix_feed_type feed_type)
    {
        //add your processing code here
    }
    virtual void on_increment(const micex_mfix::symbol &symb,
                              const std::string &board,
                              const micex_mfix::increments &msgs,
                              micex_mfix::mfix_feed_type feed_type)
    {
        //add your processing code here
    }
    virtual void on_security_status(const micex_mfix::symbol &symb,
                                    const std::string &board,
                                    const Engine::FIXMessage &msg,
                                    micex_mfix::mfix_feed_type feed_type)
    {
        //add your processing code here
    }
    virtual bool on_natural_refresh(const micex_mfix::symbol &symb,
                                    const std::string &board,
                                    const micex_mfix::increments &nr_msgs,
                                    micex_mfix::mfix_feed_type feed_type)
    {
        //add your processing code here, return your result true or false
        return true;
    }
    virtual void on_snapshot(const micex_mfix::symbol &symb,
                             const std::string &board,
                             const micex_mfix::snapshots &msgs,
                             micex_mfix::mfix_feed_type feed_type)
    {
        //add your processing code here
    }
    virtual void on_recovery_started(const micex_mfix::symbol &symb,
                                     const std::string &board,
                                     micex_mfix::mfix_feed_type feed_type)
    {
        //add your processing code here
    }
    virtual void on_recovery_stopped(const micex_mfix::symbol &symb,
                                     const std::string &board,
                                     micex_mfix::mfix_recovery_reason reason,
                                     micex_mfix::mfix_feed_type feed_type)
    {
        //add your processing code here
    }
    virtual void on_error(const micex_mfix::symbol &symb,
                          const std::string &board,
                          const std::string &error,
                          micex_mfix::mfix_feed_type feed_type)
    {
        //add your processing code here
    }
};

 

Once created use

 

micex_mfix::micex_feed::subscribe_by_symbol(const symbol &symb,
                                            const std::string &board,
                                            instrument_listener &listener,
                                            const std::string &channel_id,
                                            mfix_recovery_mode recovery = RM_USE_MARKET_RECOVERY);

 

method to subscribe to an any necessary symbol:

 

instrument_listener_impl ins_listener;
some_feed.subscribe_by_symbol("AFLT", "EQBR", ins_listener, "FOND", micex_mfix::RM_USE_MARKET_RECOVERY);

 

The listener will be notified about the subscription by calling the instrument_listener_impl::on_subscribed callback:

 

void instrument_listener_impl::on_subscribed(const micex_mfix::symbol &symb, 
                                             const std::string &board,
                                             micex_mfix::mfix_feed_type feed_type)
{
   std::cout << "Subscribed at '" << symb << "' symbol on '" << board << "' board." << std::endl;
}

 

Use

 

void instrument_listener_impl::unsubscribe_by_symbol(const symbol &symb, const std::string &board, const std::string &channel_id);

 

method to unsubscribe from the symbol:

 

some_feed.unsubscribe_by_symbol("AFLT", "EQBR", "FOND");

 

After you call the method, the engine notify listener by calling the instrument_listener_impl::on_unsubscribed callback:

 

void instrument_listener_impl::on_unsubscribed(const micex_mfix::symbol &symb, 
                                               const std::string &board,
                                               micex_mfix::mfix_feed_type feed_type)

 

Use micex_mfix::micex_feed::subscribe_all and micex_mfix::micex_feed::unsubscribe_all to subscribe/unsubscribe for all MICEX symbols:

 

void micex_mfix::micex_feed::subscribe_all(instrument_listener &listener, const std::string &channel_id, mfix_recovery_mode recovery = RM_USE_MARKET_RECOVERY)
void micex_mfix::micex_feed::unsubscribe_all(instrument_listener &listener, const std::string &channel_id, mfix_recovery_mode recovery = RM_USE_MARKET_RECOVERY)

 

Processing incoming marketdata

When a some fix message was received, the engine notifies a corresponding listener by calling one of the following callbacks:

 

// Faired when a Market Data Incremental Refresh (35=X) FIX message was received
void instrument_listener_impl::on_increment(const symbol &symb, const std::string &board, const increments &msgs, mfix_feed_type feed_type);

 

 

// Faired when a Security Status (35=f) FIX message was received
void instrument_listener_impl::on_security_status(const symbol &symb, const std::string &board, const Engine::FIXMessage &msg, mfix_feed_type feed_type);

 

 

// Faired in case when a recovery was started and all Market Data Snapshot Full Refresh (35=W) FIX messages were received
void instrument_listener_impl::on_snapshot(const symbol &symb, const std::string &board, const snapshots &msgs, mfix_feed_type feed_type);

 

 

// Faired when a Security Definition (35=d) FIX message was received
bool instrument_listener_impl::on_security_definition(const security_description &sec_desc,
                                                      const security_id &sec_id,
                                                      const symbol &symb,
                                                      const std::string &board,
                                                      const Engine::FIXMessage &d_msg,
                                                      const std::string &channel_id);

 

Add your own code into the corresponding method to process the received data.

Releasing resources

Use the micex_mfix::micex_mfix_application::release() method to release the resources consumed by micex_mfix::micex_mfix_application. The listeners have the same method and must be released too once micex_mfix::micex_mfix_application is released. Calling micex_mfix::micex_feed::unsubscribe is optional.

Full sample

The sample below illustrates all abovementioned instructions combined in one application.

 

#pragma once

#include <iostream>
#include <B2BITS_FixEngine.h>
#include <B2BITS_micex_mfix_listeners.h>
#include <B2BITS_micex_mfix_application.h>
class instrument_listener_impl
    : public micex_mfix::instrument_listener 
{
public:
    virtual bool on_security_definition(const micex_mfix::security_description &sec_desc,
                                        const micex_mfix::security_id &sec_id,
                                        const micex_mfix::symbol &symb,
                                        const std::string &board,
                                        const Engine::FIXMessage &d_msg,
                                        const std::string &channel_id)
    {
        //add your processing code here, return your result true or false
        return false;
    }
    virtual void on_subscribed(const micex_mfix::symbol &symb,
                               const std::string &board,
                               micex_mfix::mfix_feed_type feed_type)
    {
        //add your processing code here
    }
    virtual void on_unsubscribed(const micex_mfix::symbol &symb,
                                 const std::string &board,
                                 micex_mfix::mfix_feed_type feed_type)
    {
        //add your processing code here
    }
    virtual void on_increment(const micex_mfix::symbol &symb,
                              const std::string &board,
                              const micex_mfix::increments &msgs,
                              micex_mfix::mfix_feed_type feed_type)
    {
        //add your processing code here
    }
    virtual void on_security_status(const micex_mfix::symbol &symb,
                                    const std::string &board,
                                    const Engine::FIXMessage &msg,
                                    micex_mfix::mfix_feed_type feed_type)
    {
        //add your processing code here
    }
    virtual bool on_natural_refresh(const micex_mfix::symbol &symb,
                                    const std::string &board,
                                    const micex_mfix::increments &nr_msgs,
                                    micex_mfix::mfix_feed_type feed_type)
    {
        //add your processing code here, return your result true or false
        return true;
    }
    virtual void on_snapshot(const micex_mfix::symbol &symb,
                             const std::string &board,
                             const micex_mfix::snapshots &msgs,
                             micex_mfix::mfix_feed_type feed_type)
    {
        //add your processing code here
    }
    virtual void on_recovery_started(const micex_mfix::symbol &symb,
                                     const std::string &board,
                                     micex_mfix::mfix_feed_type feed_type)
    {
        //add your processing code here
    }
    virtual void on_recovery_stopped(const micex_mfix::symbol &symb,
                                     const std::string &board,
                                     micex_mfix::mfix_recovery_reason reason,
                                     micex_mfix::mfix_feed_type feed_type)
    {
        //add your processing code here
    }
    virtual void on_error(const micex_mfix::symbol &symb,
                          const std::string &board,
                          const std::string &error,
                          micex_mfix::mfix_feed_type feed_type)
    {
        //add your processing code here
    }
};
class application_listener_impl
    : public micex_mfix::micex_mfix_application_listener {
public:
    virtual void on_error(const std::string &error)
    {
        //add your processing code here
    }
    virtual void on_process(const Engine::FIXMessage &msg, const std::string &channel_id)
    {
        //add your processing code here
    }
    virtual void on_feed_reset(const std::string &channel_id, micex_mfix::mfix_feed_type feed_type)
    {
        //add your processing code here
    }
    virtual void on_heartbeat(const std::string &channel_id, micex_mfix::mfix_feed_type feed_type)
    {
        //add your processing code here
    }
};
void subscribe_and_wait(micex_mfix::micex_mfix_application *app, instrument_listener_impl *&ins_listener)
{
    //get channels id
    micex_mfix::channel_ids channels(app->get_channel_ids());
    //get orderbook feed
    micex_mfix::micex_feed &order_book_feed = app->get_statistics_feed();
    ins_listener = new instrument_listener_impl();
    //subscribe to known instrument in channel[1], with market recovery as recovery type
    order_book_feed.subscribe_by_symbol("AFLT", "EQBR", *ins_listener, channels[1], micex_mfix::RM_USE_MARKET_RECOVERY);
    while (true) 
    {
        std::cout << "Type 'q' for exit\n\n";
        char c(0);
        std::cin >> c;
        if ('q' == c || 'Q' == c) 
        {
            break;
        }
    }
    order_book_feed.unsubscribe_by_symbol("AFLT", "EQBR", channels[1]);
}
int main(int argc, char *agrv[])
{
    micex_mfix::micex_mfix_application *app = NULL;
    application_listener_impl *app_listener = NULL;
    instrument_listener_impl *ins_listener = NULL;
    try 
    {
        Engine::FixEngine::init("./engine.properties");
        //configure parameters
        micex_mfix::micex_mfix_application_params app_params;
        app_params.templates_fn_ = "./FIX50SP2.xml";
        app_params.config_xml_ = "./config.xml";
        app_listener = new application_listener_impl();
        app = Engine::FixEngine::singleton()->createMICEXApplication(app_params, app_listener);
        subscribe_and_wait(app, ins_listener);
    } 
    catch (const Utils::Exception &ex) 
    {
        std::cerr << "Exception: " << ex.what() << "\n";
        if (NULL != app_listener) 
        {
            app_listener->release();
        }
        if (NULL != ins_listener) 
        {
            ins_listener->release();
        }
        if (NULL != app) 
        {
            app->release();
        }
        
        return 100;
    }
    // release the listeners
    app_listener->release();
    ins_listener->release();
    // release micex_mfix_application
    app->release();
    return 0;
}
  • No labels