The FIX Messaging sample demonstrates the tag-value view of decoded CME MDP market data. It is useful when an application wants to consume handler events through the FIX messaging API and inspect fields, repeating groups, timestamps, enumerations, and numeric values without binding directly to each SBE message type.
The sample uses the feed engine in external processing mode and runs until interrupted with Ctrl+C.
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 override
{
ChannelConfiguration::showOptions(out);
ConnectivityConfiguration::showOptions(out);
FeedConfiguration::showOptions(out);
LoggerConfiguration::showOptions(out);
}
};
{
if (message.
type() ==
"X")
{
if (entries)
{
{
std::cout << "[" << index << "] {Price=";
{
}
{
std::cout << ",Size=" << size;
}
std::cout << "}" << std::endl;
}
}
}
else if (message.
type() ==
"d")
{
{
}
}
}
{
public:
void bind(Handler& handler)
{
}
private:
void onMessage(Handler&, const Messaging::FIX::MessageArgs& args) override
{
}
};
class IssueTracer
{
public:
IssueTracer()
: out_(std::cout)
{
}
IssueTracer(std::ostream& output)
: out_(output)
{
}
~IssueTracer() {}
void bind(Handler& handler)
{
}
private:
void onWarning(Handler& handler, const WarningArgs& warning) override
{
std::stringstream message;
message <<
'[' << handler.
settings().
channel() <<
"] WARNING: " << warning << std::endl;
out_ << message.str();
}
void onError(Handler& handler, const ErrorArgs& error) override
{
std::stringstream message;
message <<
'[' << handler.
settings().
channel() <<
"] ERROR: " << error << std::endl;
out_ << message.str();
}
void onFeedEngineThreadIssue(const FeedEngineThreadPool&, const Messaging::Char* issue) override
{
std::stringstream message;
message << "ALERT!!! "
"Issue occurred in working thread. "
<< issue << std::endl;
out_ << message.str();
}
void onFileLoggerIssue(const FileLogger&, const Messaging::Char* issue) 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(logger_.get()));
handler_.reset(new Handler());
HandlerSettings& settings = handler_->settings();
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
{
feedEngine_->process();
}
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;
}
}