OnixS C++ FIX Engine  4.12.0
API Documentation
Sell Side Sample

This sample waits for incoming connections on the pre-defined port (acts as a FIX Acceptor). If the incoming application-level message is SingleOrder - New then the ExecutionReport message is send to the counterparty. Otherwise the Email message is sent back.


Source code:


Listener.h:

class Listener : public OnixS::FIX::ISessionListener
{
public:
Listener(void);
/// Is called when the application-level message is received from the counterparty.
void onInboundApplicationMsg(Message & msg, Session * sn) ONIXS_FIXENGINE_FINAL;
/// Is called when the session-level message is received from the counterparty.
void onInboundSessionMsg(Message & msg, Session * sn) ONIXS_FIXENGINE_FINAL;
void onStateChange(SessionState::Enum newState, SessionState::Enum prevState,Session * sn) ONIXS_FIXENGINE_FINAL;
void onError(ErrorReason::Enum reason, const std::string & description, Session * sn) ONIXS_FIXENGINE_FINAL;
void onWarning(WarningReason::Enum reason, const std::string & description, Session * sn) ONIXS_FIXENGINE_FINAL;
private:
int ordersCounter_;
};

Listener.cpp:

#include "Listener.h"
#include "../../Common/Settings.h"
#include "../../Common/Helpers.h"
using namespace Settings;
Listener::Listener() : ordersCounter_(0) {}
void Listener::onInboundApplicationMsg(Message & msg, Session * sn)
{
std::clog << "\nIncoming application-level message:\n" << msg << std::endl;
try {
Message * reply = ONIXS_FIXENGINE_NULLPTR;
if(msg.type() == MsgType::Order_Single) { // New Order - Single
const Message & order = msg;
Message * execReport = new Message(MsgType::Execution_Report, FixProtocolVersion);
execReport->set(Tags::OrderID, order.get(Tags::ClOrdID).toString());
const int EXEC_ID_SIZE = 128;
char execID[EXEC_ID_SIZE];
xsnprintf(execID, EXEC_ID_SIZE - 1, "ExecID_%d", ++ordersCounter_);
execReport->set(Tags::ExecID, execID)
.set(Tags::ExecType, "0")
.set(Tags::ExecTransType, "0") // New
.set(Tags::OrdStatus, "0") // New
.set(Tags::Symbol, order.get(Tags::Symbol).toString())
.set(Tags::Side, order.get(Tags::Side).toString())
.set(Tags::OrderQty, order.get(Tags::OrderQty).toString())
.set(Tags::CumQty, order.get(Tags::OrderQty).toString())
.set(Tags::AvgPx, 100.0)
.set(Tags::LastShares, 0)
.set(Tags::LastPx, 0)
.set(Tags::LeavesQty, order.get(Tags::OrderQty).toString());
reply = execReport;
}
else {
Message * email = new Message(MsgType::Email, FixProtocolVersion);
email->set(Tags::EmailType, 0);
Group group = email->setGroup(Tags::LinesOfText, 1);
group[0].set(Tags::Text, "The message with MsgType=" + msg.type().toString() + " was received");
reply = email;
}
if(ONIXS_FIXENGINE_NULLPTR != reply) {
sn->send(reply);
std::clog << "\nSent to the counterparty:\n" << *reply << std::endl;
}
delete reply;
}
catch(const std::exception & ex) {
std::clog << "Exception during the processing of incoming message: " << ex.what() << std::endl;
}
}
void Listener::onInboundSessionMsg(Message & msg, Session * /*sn*/)
{
std::clog << "\nIncoming session-level message:\n" << msg << std::endl;
}
void Listener::onStateChange(SessionState::Enum newState, SessionState::Enum prevState,
Session * /*sn*/)
{
std::clog << "\nSession's state is changed, prevState=" << SessionState::toString(prevState)
<< ", newState=" << SessionState::toString(newState) << std::endl;
}
void Listener::onError(ErrorReason::Enum /*reason*/, const std::string & description, Session * /*sn*/)
{
std::cerr << "\nSession-level error:" << description << std::endl;
}
void Listener::onWarning(WarningReason::Enum /*reason*/, const std::string & description,
Session * /*sn*/)
{
std::cerr << "\nSession-level warning:" << description << std::endl;
}

SellSide.cpp:

#include "Listener.h"
#include "../../Common/Helpers.h"
#include "../../Common/Settings.h"
using namespace Settings;
// Uncomment if you'd like to test SSL feature.
//#define SSL_ENCRYPTION 1
namespace {
class MyEngineListener : public OnixS::FIX::IEngineListener
{
public:
void onUnknownIncomingConnection(const FlatMessage & /*incomingLogon*/, const int /*istenPort*/,
const int /*counterpartyPort*/, const std::string & /*counterpartyIpAddress*/,
std::string * /*rejectReason*/) ONIXS_FIXENGINE_OVERRIDE {};
void onError(EngineErrorReason::Enum /*reason*/, const std::string & description) ONIXS_FIXENGINE_OVERRIDE {
std::cerr << "\nEngine-level error: " << description << std::endl;
}
void onWarning(EngineWarningReason::Enum /*reason*/, const std::string & description) ONIXS_FIXENGINE_OVERRIDE {
std::cerr << "\nEngine-level warning: " << description << std::endl;
}
};
}
int main()
{
std::clog << "SellSide sample." << std::endl << std::endl;
try {
EngineSettings settings;
manageLinuxSignals();
#ifdef SSL_ENCRYPTION
std::clog << "SSL Mode." << std::endl;
settings.sslListenPort(Settings::SslListenPort)
.sslCertificateFile("test.pem")
.sslPrivateKeyFile("test.pem");
#else
settings.listenPort(ListenPort);
#endif
settings.licenseStore(LicenseStore)
.sendLogoutOnInvalidLogon(true)
.sendLogoutOnException(true); // E.g. to send a Logout when the sequence number of the incoming Logon (A) message is less than expected.
Engine::init(settings);
MyEngineListener engineListener;
Engine::instance()->registerListener(&engineListener);
Listener listener;
Session session(TargetCompId, SenderCompId, FixProtocolVersion, &listener);
#ifdef SSL_ENCRYPTION
session.encryptionMethod(EncryptionMethod::SSL);
#endif
session.logonAsAcceptor();
std::clog << "Awaiting session-initiator on port " << settings.listenPort() << "..." << std::endl;
getchar();
session.logout().shutdown();
Engine::instance()->unregisterListener();
Engine::shutdown();
}
catch(const std::exception & ex) {
processSampleException(ex.what());
return 1;
}
return 0;
}