The Certification sample runs a single handler with verbose event tracing for CME certification and connectivity checks. It records recovery transitions, security definitions, book updates, trade and statistics events, warnings, and errors so that handler behavior can be inspected against expected market-data scenarios.
The channel argument is required. The sample runs until interrupted with Ctrl+C.
class Configuration
: public ChannelConfiguration
, public SessionConfiguration
, public BookManagementConfiguration
, public ConnectivityConfiguration
, public FeedConfiguration
, public LoggerConfiguration
{
public:
Configuration(size_t qty, char** args)
: ConfigurationBase(qty, args)
, ChannelConfiguration(qty, args)
, SessionConfiguration(qty, args)
, BookManagementConfiguration(qty, args)
, ConnectivityConfiguration(qty, args)
, FeedConfiguration(qty, args)
, LoggerConfiguration(qty, args, "Certification.log")
{
}
private:
void showOptions(std::ostream& out) const override
{
ChannelConfiguration::showOptions(out);
SessionConfiguration::showOptions(out);
BookManagementConfiguration::showOptions(out);
ConnectivityConfiguration::showOptions(out);
FeedConfiguration::showOptions(out);
LoggerConfiguration::showOptions(out);
}
};
class EventHandler
, SecurityListenerAdapter<EventHandler>
, public FileLoggerEventTracer
{
public:
EventHandler(std::ostream& out)
: FileLoggerEventTracer(out)
, out_(out)
{
}
void bind(Handler& handler)
{
}
private:
friend class SecurityListenerAdapter<EventHandler>;
std::ostream& out_;
void onStarted(Handler&) override
{
out_ << "Market data processing started. " << std::endl;
}
void onStopped(Handler&) override
{
out_ << "Market data processing stopped. " << std::endl;
}
void onInstrumentRecovery(Handler&) override
{
outRecoveryBegin(out_, "Instrument");
}
void onEndOfInstrumentRecovery(Handler&, const RecoveryCompletionArgs& args) override
{
outRecoveryEnd(out_, "Instrument", args);
}
void onMarketRecovery(Handler&) override
{
outRecoveryBegin(out_, "Market");
}
void onEndOfMarketRecovery(Handler&, const RecoveryCompletionArgs& args) override
{
outRecoveryEnd(out_, "Market", args);
}
void onTcpRecovery(Handler&) override
{
outRecoveryBegin(out_, "TCP");
}
void onEndOfTcpRecovery(Handler&, const RecoveryCompletionArgs& args) override
{
outRecoveryEnd(out_, "TCP", args);
}
void onRealtimeProcessing(Handler&) override
{
out_ << "Real-time processing started. " << std::endl << std::endl;
}
void onEndOfRealtimeProcessing(Handler&) override
{
out_ << "Real-time processing suspended. " << std::endl << std::endl;
}
void onWarning(Handler&, const WarningArgs& warning) override
{
out_ << "WARNING! " << warning << std::endl << std::endl;
}
void onError(Handler&, const ErrorArgs& error) override
{
out_ << "ERROR! " << error << std::endl << std::endl;
}
void onChannelReset(Handler&)
{
out_ << "MDP has spawned Book Reset on the channel. " << std::endl << std::endl;
}
template <class Args>
void onSecurityDefinition(Handler&, const Security&, const Args& args)
{
outDefinition(out_, args.message());
}
void onSecurityUndefined(Handler&, Security&) {}
template <class Args>
void onSecurityRecovery(Handler&, const Security&, const Args&)
{
}
template <class Args>
void onSecurityBookAtomic(Handler&, const Security&, const Args&)
{
}
template <class Book>
void onSecurityBook(Handler&, const Security& security, const Book& book)
{
outBook(out_, security.
id(), book);
}
template <class Args>
void onSecurityBookError(Handler&, const Security& security, const Args& args)
{
out_ <<
"BOOK [" << security.
id() <<
"] UPDATE ERROR! " << args << std::endl << std::endl;
}
template <class Args>
void onSecurityTrade(Handler&, const Security& security, const Args& args)
{
outStatistics(out_,
"Trade", security.
id(), args.entry(), TradeExtras());
}
template <class Args>
void onSecurityVolume(Handler&, const Security& security, const Args& args)
{
outStatistics(out_,
"ElectronicVolume", security.
id(), args.entry());
}
template <class Args>
void onSecuritySettlementPrice(Handler&, const Security& security, const Args& args)
{
outStatistics(out_,
"SettlementPrice", security.
id(), args.entry(), SettlementPriceExtras());
}
template <class Args>
void onSecurityClearedVolume(Handler&, const Security& security, const Args& args)
{
outStatistics(out_,
"ClearedVolume", security.
id(), args.entry());
}
template <class Args>
void onSecurityOpenInterest(Handler&, const Security& security, const Args& args)
{
outStatistics(out_,
"OpenInterest", security.
id(), args.entry());
}
template <class Args>
void onSecurityFixingPrice(Handler&, const Security& security, const Args& args)
{
outStatistics(out_,
"FixingPrice", security.
id(), args.entry());
}
template <class Args>
void onSecurityOpeningPrice(Handler&, const Security& security, const Args& args)
{
outStatistics(out_,
"OpeningPrice", security.
id(), args.entry());
}
template <class Args>
void onSecurityHighTradePrice(Handler&, const Security& security, const Args& args)
{
outStatistics(out_,
"HighTradePrice", security.
id(), args.entry());
}
template <class Args>
void onSecurityLowTradePrice(Handler&, const Security& security, const Args& args)
{
outStatistics(out_,
"LowTradePrice", security.
id(), args.entry());
}
template <class Args>
void onSecurityHighestBid(Handler&, const Security& security, const Args& args)
{
outStatistics(out_,
"HighestBid", security.
id(), args.entry());
}
template <class Args>
void onSecurityLowestOffer(Handler&, const Security& security, const Args& args)
{
outStatistics(out_,
"LowestOffer", security.
id(), args.entry());
}
template <class Args>
void onSecurityLimitsAndBanding(Handler&, const Security& security, const Args& args)
{
outLimitsAndBanding(out_, security.
id(), args.entry());
}
void onSecurityQuoteRequest(Handler&, const Security&, const QuoteRequest39RelatedSymArgs& args)
{
outQuoteRequest(out_, args.
entry());
}
template <class Args>
void onSecurityStatus(Handler&, const Security& security, const Args& args)
{
outStatus(out_, args.message(), &security);
}
void onSecurityGroupStatus(Handler&, const SecurityStatus30Args& args)
{
}
void onSecurityGap(Handler&, const Security& security, Messaging::UInt32 incoming)
{
out_ << "Gap detected in the incoming data "
"for the given security [id="
<< security.
id() <<
",lastProcessed=" << security.
seqNumber() <<
",incoming=" << incoming <<
"]."
<< std::endl;
}
};
void identify()
{
std::cout <<
"Certification Application for CME MDP Premium Market Data Handler, v" <<
toStr(
Version::current())
<< ". "
<< std::endl
<< std::endl;
}
int main(int qty, char** args)
{
try
{
identify();
const Configuration configuration(qty, args);
if (configuration.show())
{
configuration.show(std::cout);
}
else
{
checkNetworkSettings(configuration);
EventHandler events(std::cout);
const ScopedPtr<Logger> logger(constructFileLogger(configuration, &events));
const ScopedPtr<NetFeedEngine> feedEngine(constructFeedEngine(logger.get()));
const ScopedPtr<TcpRecoveryService> tcpRecovery(constructTcpRecovery(configuration));
setLicense(settings);
settings.
channel(configuration.channel()).connectivityConfigurationFile(configuration.connectivityFile());
apply(settings.
feeds(), configuration);
apply(settings.
session(), configuration, tcpRecovery.get());
apply(settings.
logging(), configuration, logger.get());
events.bind(handler);
std::cout << std::endl << "Press Ctrl+C to stop and exit. " << std::endl << std::endl;
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 << std::endl << "Done. " << std::endl << std::endl;
}
return 0;
}
catch (const std::exception& ex)
{
std::cerr << std::endl << "ERROR: " << ex.what() << std::endl;
return 1;
}
}