This sample demonstetes how to use FIX-like messaging.
class Configuration
: public ChannelConfiguration
, public ConnectivityConfiguration
, public FeedConfiguration
, public LoggerConfiguration
{
public:
Configuration(size_t qty, char** args)
: ConfigurationBase(qty, args)
, ChannelConfiguration(qty, args, 310)
, ConnectivityConfiguration(qty, args)
, FeedConfiguration(qty, args)
, LoggerConfiguration(qty, args, "FixMessaging.log")
{
}
private:
void showOptions(std::ostream& out) const ONIXS_CMEMDH_OVERRIDE
{
ChannelConfiguration::showOptions(out);
ConnectivityConfiguration::showOptions(out);
FeedConfiguration::showOptions(out);
LoggerConfiguration::showOptions(out);
}
};
void trace(std::ostream& output,
const FIX::Message& message)
{
if (message.
type() ==
"X")
{
output <<
"Transact time: " <<
toStr(transact.
cast<Timestamp>()) <<
"." << std::endl
<<
"Transact time (Ticks from Epoch): " <<
toStr(transact.
cast<
UInt64>()) <<
"." << std::endl
<<
"Event Indicator (Raw Numeric Value): " <<
toStr(indicator.
cast<
UInt32>()) <<
"." << std::endl;
if (entries)
{
{
std::cout << "[" << index << "] {Price=";
{
std::cout <<
toStr(px.cast<Decimal>());
}
{
std::cout << ",Size=" << size;
}
std::cout <<
",Side=" <<
toStr(side.
cast<EntryType>())
std::cout <<
",Action=" <<
toStr(action.
cast<UpdateAction>())
std::cout << "}" << std::endl;
}
}
}
else if (message.
type() ==
"d")
{
{
std::cout <<
"Maturity Month-Year for $" << securityId <<
": " <<
toStr(mmy) << std::endl;
}
}
}
class FixMessageTracer : FIX::MessageListener
{
public:
void bind(Handler& handler)
{
handler.settings().listeners().marketData(this);
}
private:
void onMessage(Handler&, const FIX::MessageArgs& args) ONIXS_CMEMDH_OVERRIDE
{
trace(std::cout, args.message());
}
};
class IssueTracer
{
public:
IssueTracer()
{
}
IssueTracer(std::ostream& output)
: out_(output)
{
}
~IssueTracer() {}
void bind(Handler& handler)
{
handler.settings().listeners().handler(this);
}
private:
void onWarning(Handler& handler,
const WarningArgs& warning) ONIXS_CMEMDH_OVERRIDE
{
std::stringstream message;
message << '[' << handler.settings().channel() << "] WARNING: " << warning << std::endl;
out_ << message.str();
}
void onError(Handler& handler,
const ErrorArgs& error) ONIXS_CMEMDH_OVERRIDE
{
std::stringstream message;
message << '[' << handler.settings().channel() << "] ERROR: " << error << std::endl;
out_ << message.str();
}
{
std::stringstream message;
message << "ALERT!!! "
"Issue occurred in working thread. "
<< issue << std::endl;
out_ << message.str();
}
void onFileLoggerIssue(
const FileLogger&,
const Char* issue) ONIXS_CMEMDH_OVERRIDE
{
std::stringstream message;
message << "ALERT!!! "
"Issue occurred while logging data. "
<< issue << std::endl;
out_ << message.str();
}
std::ostream& out_;
};
class Application
{
public:
Application(const Configuration& configuration)
: configuration_(configuration)
{
try
{
logger_.reset(constructFileLogger(configuration_, &issueTracer_));
feedEngine_.reset(constructFeedEngine());
handler_.reset(new Handler());
setLicense(settings);
settings.
channel(configuration_.channel()).connectivityConfigurationFile(configuration_.connectivityFile());
apply(settings.
feeds(), configuration);
apply(settings.
logging(), configuration, logger_.get());
fixMessageTracer_.bind(*handler_);
issueTracer_.bind(*handler_);
}
catch (...)
{
handler_.reset();
feedEngine_.reset();
logger_.reset();
throw;
}
}
~Application() {}
void run()
{
std::cout << "Starting processing market data.. " << std::endl << "Press Ctrl+C to stop exit. " << std::endl;
handler_->start();
while (!InterruptDetector::instance().detected())
{
try
{
}
catch (const std::exception& ex)
{
std::cerr << std::endl
<< "WARNING! Feed engine raised an "
"issue while processing incoming data. "
<< ex.what() << std::endl;
}
}
std::cout << "Stopping processing market data.. " << std::endl;
handler_->stop();
std::cout << std::endl << std::endl << "Done. " << std::endl << std::endl;
}
static void identify()
{
std::cout <<
"FIX Messaging for CME MDP Premium Market Data Handler, v" <<
toStr(
Version::current()) <<
". " << std::endl
<< std::endl;
}
private:
const Configuration& configuration_;
ScopedPtr<Logger> logger_;
ScopedPtr<NetFeedEngine> feedEngine_;
ScopedPtr<Handler> handler_;
FixMessageTracer fixMessageTracer_;
IssueTracer issueTracer_;
Application(const Application&);
Application& operator=(const Application&);
};
int main(int qty, char** args)
{
try
{
Application::identify();
const Configuration configuration(qty, args);
if (configuration.show())
{
configuration.show(std::cout);
}
else
{
checkNetworkSettings(configuration);
Application app(configuration);
app.run();
}
return 0;
}
catch (const std::exception& ex)
{
std::cerr << std::endl << "ERROR: " << ex.what() << std::endl;
return 1;
}
}