Sunday, May 13, 2012

Boost::Variant as a union-like container for thread messages

How Boost::Variant can be used to carry messages to a thread:

#include <stdint.h>
#include <string>
#include <iostream>
#include <boost/variant.hpp>

using namespace std;

class WorkerMessageBase
{
public:
    typedef enum
    {
        INIT_REQ = 1,
        LOGIN_REQ,
        CLOSE_REQ,

    } MessageType;

    WorkerMessageBase();
    virtual ~WorkerMessageBase();

    inline const MessageType getMessageType(void) const
    {
        return m_msg_type;
    }

protected:
    MessageType m_msg_type;
};

WorkerMessageBase::WorkerMessageBase(){}
WorkerMessageBase::~WorkerMessageBase(){}

class InitReq : public WorkerMessageBase
{
public:
    InitReq()
    {
        m_msg_type = InitReq::INIT_REQ;
    }
protected:
    uint32_t    m_current_time;
};

class LoginReq : public WorkerMessageBase
{
public:
    LoginReq()
    {
        m_msg_type = LoginReq::LOGIN_REQ;
    }
protected:
    bool        m_authenticate;
    string      m_login;
    string      m_password;
};

class CloseReq : public WorkerMessageBase
{
public:
    CloseReq()
    {
        m_msg_type = CloseReq::CLOSE_REQ;
    }
protected:
    uint32_t    m_timeout;
};

typedef boost::variant<
    InitReq,
    LoginReq,
    CloseReq
    > WorkerMessage;

typedef struct
{
    uint32_t        header;
    WorkerMessage   msg;
} message_t;

class Extractor : public boost::static_visitor<WorkerMessageBase *>
{
    public:
    WorkerMessageBase * operator()(InitReq & req) const {return &req;}
    WorkerMessageBase * operator()(LoginReq & req) const {return &req;}
    WorkerMessageBase * operator()(CloseReq & req) const {return &req;}
};

void handler(Extractor & extractor, message_t *ptr)
{
    WorkerMessageBase   *msg_p;

    msg_p = boost::apply_visitor(extractor, ptr->msg);

    cout << "Handler received msg type: " << msg_p->getMessageType() << endl;
}

int main()
{
    InitReq         init_req;
    LoginReq        login_req;
    CloseReq        close_req;
    message_t       m;
    Extractor       extractor;

    m.msg = init_req;
    handler(extractor, &m);

    m.msg = login_req;
    handler(extractor, &m);

    m.msg = close_req;
    handler(extractor, &m);

    return 0;
}

Monday, January 23, 2012

Quickfix

1. CFLAGS="-march=pentium4 -O2 -pipe -fomit-frame-pointer -msse2 -mfpmath=sse -s" CXXFLAGS="-march=pentium4 -O2 -pipe -msse2 -mfpmath=sse -s" ./configure --enable-static --with-mysql=/usr
2. make -j2
3. create quickfix mysql user
4. quickfix/src/sql/mysql/create.sh quickfix
5. CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)

INCLUDE_DIRECTORIES( include )
LINK_DIRECTORIES( ext_libs )

ADD_EXECUTABLE( main main.cpp )

TARGET_LINK_LIBRARIES( main pthread xml2 z libquickfix.a )
6. main.cpp
#include <cstdio>

#include "quickfix/FileStore.h"
#include "quickfix/NullStore.h"

#include "quickfix/FileLog.h"
#include "quickfix/Session.h"
#include "quickfix/SocketAcceptor.h"
#include "quickfix/SocketInitiator.h"
#include "quickfix/SessionSettings.h"
#include "quickfix/Application.h"

#include "quickfix/SessionID.h"

namespace FIX
{

class MyApplication : public FIX::Application
{
public:

~MyApplication()
{
    puts("MyApp dtor called");
};

void onCreate( const SessionID& )
{
    puts("MyApp onCreate called");
};

void onLogon( const SessionID& )
{
    puts("MyApp onLogon called");
};

void onLogout( const SessionID& )
{
    puts("MyApp onLogout called");
};

void toAdmin( Message&, const SessionID& )
{
    puts("MyApp toAdmin called");
};

void toApp( Message&, const SessionID& )
    throw( DoNotSend )
{
    puts("MyApp toApp called");
};

void fromAdmin( const Message&, const SessionID& )
    throw( FieldNotFound, IncorrectDataFormat, IncorrectTagValue, RejectLogon )
{
    puts("MyApp fromAdmin called");
};

void fromApp( const Message&, const SessionID& )
    throw( FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType )
{
    puts("MyApp fromApp called");
};

}; /* class */

} /* namespace FIX */

int main(int argc, char **argv)
{
    printf("hello world\n");


    try
    {
      if (argc < 2)
      {
          return 1;
      }

      std::string fileName = argv[1];

      FIX::SessionSettings settings(fileName);

      FIX::MyApplication application;

      FIX::FileStoreFactory storeFactory(settings);
      FIX::FileLogFactory logFactory(settings);

      FIX::SocketInitiator initiator
        (application, storeFactory, settings, logFactory /*optional*/);
      initiator.start();
      // while( condition == true ) { do something; }

      sleep(5);

      initiator.stop();

    }
    catch(FIX::ConfigError& e)
    {
      std::cout << e.what();
            return 1;
    }



    return 0;
}

7. cmake . ; make
8. app.ini
 # default settings for sessions
[DEFAULT]
#DefaultApplVerID=FIX.4.4
ConnectionType=initiator
ReconnectInterval=60
SenderCompID=hhhhhhhhhhh
FileStorePath=logs
FileLogPath=logs
MySQLLogUser=bbbbbbbbb
MySQLLogPassword=aaaaaaaaaaa
#SocketUseSSL=Y
TimeZone=Europe
StartTime=00:00:00
EndTime=23:59:59

# session definition
[SESSION]
# inherit ConnectionType, ReconnectInterval and SenderCompID from default
BeginString=FIX.4.4
TargetCompID=MBT
StartTime=12:30:00
EndTime=23:30:00
HeartBtInt=20
# non-SSL
SocketConnectPort=xyz
# SSL
#SocketConnectPort=xyz
SocketConnectHost=111.222.333.444
DataDictionary=spec/FIX44.xml

9. emerge stunnel

Sunday, January 15, 2012

FIX Programming

For my reference:
Boost.Thread - http://www.boost.org/doc/libs/1_34_0/doc/html/thread.html
Boost.Interprocess - http://www.boost.org/doc/libs/1_35_0/doc/html/interprocess.html
Boost Message Queue - http://www.boost.org/doc/libs/1_35_0/doc/html/boost/interprocess/message_queue.html
DJJ - What's New in Boost Threads - http://drdobbs.com/cpp/211600441

Wednesday, January 11, 2012

FIX API Support forum on dailyfx.com

Bookmarking: http://forexforums.dailyfx.com/fix-api-support/
looks very promising.

Forex FIX brokers - dukascopy

The Dukascopy website confirms support for FIX trading, however their requirements for enabling FIX API say that you need at least 100,000 USD deposit.
Nonetheless, it is very nice on their side to provide this basic FIX Trading manua (PDF).

[Forex] OpenForexPlatform

GPL-licensed OpenForexPlatform, offers MetaTrader4 integration among others, but is written in C#. Might be a source of ideas (also FIX-related) for C/C++ forex trading application.

[Forex] Search for brokers with FIX Protocol enabled accounts

First I spotted this website: http://www.100forexbrokers.com/. They do have brokers grouped according to ECN, STP, and DMA support. I tried to evaluate broker by broker, but this is tedious - maybe I'll get back to this later.


But then I googled and found this:
http://www.forexfactory.com/showthread.php?p=1970525#post1970525

a bit dated (April 2008) list, but has explicit annotations on offered APIs, including FIX.
HotSpotFX link is broken but their website still works and proved to be an extremely valuable source of practical manuals on FIX trading.