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

This sample listens an incoming connection on the pre-defined interface and port (acts as a FIX Acceptor). When the session is established, and the SingleOrder - New is received, the ExecutionReport FIX message is sent to the counterparty. This is done using Solarflare TCPDirect© technology.


Source code:


TcpDirectListener.h:

#include "../Common/Settings.h"
using namespace Settings;
class TcpDirectListener : public OnixS::FIX::ISessionListener
{
public:
TcpDirectListener() ONIXS_FIXENGINE_NOTHROW : started_(false), finished_(false) {}
~TcpDirectListener() ONIXS_FIXENGINE_OVERRIDE ONIXS_FIXENGINE_DEFAULT;
bool started() const ONIXS_FIXENGINE_NOTHROW
{
return started_;
}
bool finished() const ONIXS_FIXENGINE_NOTHROW
{
return finished_;
}
/// Is called when the application-level message is received from the counterparty.
void onInboundApplicationMsg(Message & msg, Session * sn) ONIXS_FIXENGINE_FINAL
{
std::clog << "\nIncoming application-level message:\n" << msg << std::endl;
try
{
if(msg.type() == MsgType::Order_Single)
{ // New Order - Single
const Message & order = msg;
Message execReport(MsgType::Execution_Report, FixProtocolVersion);
execReport.set(Tags::OrderID, order.get(Tags::ClOrdID).toString())
.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());
sn->send(&execReport);
std::clog << "\nSent to the counterparty:\n" << execReport << std::endl;
}
}
catch(const std::exception & ex)
{
std::clog << "Exception during the processing of incoming message: " << ex.what() << std::endl;
}
}
/// Is called when the session-level message is received from the counterparty.
void onInboundSessionMsg(Message & msg, Session *) ONIXS_FIXENGINE_FINAL
{
std::clog << "\nIncoming session-level message:\n" << msg << std::endl;
}
void onStateChange(SessionState::Enum newState, SessionState::Enum prevState, Session *) ONIXS_FIXENGINE_FINAL
{
std::clog
<< "\nSession's state is changed, prevState="
<< SessionState::toString(prevState)
<< ", newState="
<< SessionState::toString(newState)
<< std::endl;
if(newState == SessionState::Active)
started_ = true;
else if(newState == SessionState::Disconnected)
finished_ = true;
}
void onError(ErrorReason::Enum, const std::string & description, Session *) ONIXS_FIXENGINE_FINAL
{
std::cerr << "\nSession-level error:" << description << std::endl;
finished_ = true;
}
void onWarning(WarningReason::Enum, const std::string & description, Session *) ONIXS_FIXENGINE_FINAL
{
std::cerr << "\nSession-level warning:" << description << std::endl;
}
private:
bool started_;
bool finished_;
};

TCPDirectSellSide.cpp:

#include "../../Common/Helpers.h"
#include "../../Common/Settings.h"
#include "../../Common/TcpDirectListener.h"
using namespace Settings;
int main()
{
std::clog << "TCPDirect SellSide sample." << std::endl << std::endl;
const std::string listenAddress = "";
const std::string networkInterfaceName = "";
if(listenAddress.empty() || networkInterfaceName.empty())
{
std::cerr << "Please perform the setup." << std::endl;
return 1;
}
try
{
manageLinuxSignals();
ifaces.push_back(listenAddress);
EngineSettings settings;
settings.licenseStore(LicenseStore);
settings.localNetworkInterface(ifaces);
settings.listenPort(ListenPort);
TCPDirect::Attributes attr;
attr.networkInterface(networkInterfaceName);
TCPDirect::Stack stack(attr);
Engine::init(settings, &stack);
TcpDirectListener listener;
Session session(&stack, TargetCompId, SenderCompId, FixProtocolVersion, &listener);
session.logonAsAcceptor();
std::clog << "Awaiting session-initiator on port " << settings.listenPort() << "..." << std::endl;
// The TCPDirect middleware is NOT thread-safe.
// Therefore, the event dispatching and message sending should be performed from the same thread.
while(!listener.started())
stack.dispatchEvents();
std::clog << "Press any key to disconnect the session and terminate the application." << std::endl;
// The TCPDirect middleware is NOT thread-safe.
// Therefore, the event dispatching and message sending should be performed from the same thread.
while(!listener.finished() && !keyPressed())
stack.dispatchEvents();
session.logoutAsync("The session is disconnected by TCPDirect");
while(!listener.finished())
stack.dispatchEvents();
session.shutdown();
Engine::shutdown();
while(!stack.isQuiescent())
stack.dispatchEvents();
}
catch(const std::exception & ex)
{
processSampleException(ex.what());
return 1;
}
return 0;
}