#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;
}
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:
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
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
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.
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).
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.
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.
Subscribe to:
Posts (Atom)