OnixS ICE iMpact Multicast Price Feed Handler C++ library 8.20.0
Users' manual and API documentation
Loading...
Searching...
No Matches
Event Listeners

Events in the Handler

The Handler exposes the following major events: Exchange message received, Order Book Changed, Handler (Feed) state changed, and Error occurred.

The Exchange message received event is fired by the Handler when a subscription is started. The Handler calls the associated listener (event handler) for each message it receives. Invocation of the event handler is not guaranteed to occur on a single thread: product-definition messages retrieved during security-definition recovery are delivered from an internal security-definition thread, while messages received over multicast are delivered from the Feed Engine worker thread(s). See the Threading Model topic for details. The product-definition messages retrieved during security-definition recovery (over TCP) stop once that recovery finishes. Option, strategy, and expiry definitions that arrive over multicast, along with all other market-data messages, keep being delivered on the subscribed markets for as long as the subscription remains active.

The Order Book changed event is raised by the Handler in response to notifications from the Multicast Price Feed about added or modified orders, changes in price levels, executed trades, and other events. Events of this type occur only when the subscription is active. The associated listener will never be called before Handler::start succeeds, and after the subscription is stopped using the Handler::stop member. These callbacks are delivered on the Feed Engine worker thread(s); see the Threading Model topic for the synchronization guarantees when more than one worker thread is used.

The Handler (Feed) state changed event is raised by the Handler when the handler's or feed's state changes.

The Error occurred event is fired by the Handler when an error condition is met. This could be a generic error, such as an inability to write to a log file, or a failure scenario, such as receiving a message from the Multicast Price Feed with an invalid sequence number. This event is raised by the Handler only when a subscription is active.

Listening for a particular event

For each of these events, Handler provides an interface (C++ class with virtual members) like ErrorListener, which has to be implemented to handle the event and a member like Handler::registerErrorListener, which allows an instance of the event handler to be associated with an appropriate event in the scope of a particular ICE iMpact Handler.

The table below depicts the correspondence between events and listeners interface:

Event Listener interface to be implemented
Futures/OTC Product Definition Received ExchangeListener::onFuturesProductDefinition
Strip Info received ExchangeListener::onStripInfo
Options Product Definition Received ExchangeListener::onOptionsProductDefinition
Options Strategy Definition Received ExchangeListener::onOptionsStrategyDefinition
Market Snapshot Message Received ExchangeListener::onMarketSnapshot
Trade Message Received ExchangeListener::onTrade
Investigated Trade Message Received ExchangeListener::onInvestigatedTrade
Cancelled Trade Message Received ExchangeListener::onCancelledTrade
Market Statistics Message Received ExchangeListener::onMarketStatistics
Market State Message Received ExchangeListener::onMarketStateChange
System Text Message Received ExchangeListener::onSystemText
Open Interest Message Received ExchangeListener::onOpenInterest
Open Price Message Received ExchangeListener::onOpenPrice
Settlement Price Message Received ExchangeListener::onSettlementPrice
Sequence ID Rollover Message Received ExchangeListener::onSequenceIdRollover
Marker/Index Prices Message Received ExchangeListener::onMarkerIndexPrices
End Of Day Market Summary Received ExchangeListener::onEndOfDayMarketSummary
Market Event Message Received ExchangeListener::onMarketEvent
Pre-Open Price Indicator Message Received ExchangeListener::onPreOpenPriceIndicator
Market Snapshot Order Message Received ExchangeListener::onMarketSnapshotOrder
Add/Modify Order Message Received ExchangeListener::onAddModifyOrder
Delete Order Message Received ExchangeListener::onDeleteOrder
Bundle Marker Message Received ExchangeListener::onBundleMarker
Market Snapshot Price Level Message Received ExchangeListener::onMarketSnapshotPriceLevel
Add Price Level Message Received ExchangeListener::onAddPriceLevel
Change Price Level Message Received ExchangeListener::onChangePriceLevel
Delete Price Level Message Received ExchangeListener::onDeletePriceLevel
New Options Strategy Definition Message Received ExchangeListener::onNewOptionsStrategyDefinition
New Options Market Definition Message Received ExchangeListener::onNewOptionsMarketDefinition
RFQ Message received ExchangeListener::onRfq
Option Open Interest Message received ExchangeListener::onOptionOpenInterest
Option Settlement Price Message received ExchangeListener::onOptionSettlementPrice
Order Book updated OrderBookUpdateListener::onOrderBookUpdated
Order Book updated after message bundle OrderBookBundleUpdateListener::onOrderBookBundleUpdated
Handler state change HandlerStateChangeListener::onHandlerStateChange
Feed started FeedListener::onFeedStarted
Feed stopped FeedListener::onFeedStopped
Multicast message block begin FeedListener::onMulticastMessageBlockBegin
Multicast message block end FeedListener::onMulticastMessageBlockEnd
Error occurred ErrorListener
Log replay finished LogReplayListener::onReplayFinished

To register a particular listener there are corresponding registerListener() member of the Handler class:

Listener interface Registrar member
ExchangeListener Handler::registerExchangeListener
OrderBookUpdateListener Handler::registerOrderBookUpdateListener
OrderBookBundleUpdateListener Handler::registerOrderBookBundleUpdateListener
HandlerStateChangeListener Handler::registerHandlerStateChangeListener
FeedListener Handler::registerFeedListener
ErrorListener Handler::registerErrorListener
LogReplayListener Handler::registerLogReplayListener

Empty Multicast Message Blocks

The exchange groups market data messages into multicast message blocks. Every block starts with a header reporting the feed session number, the sequence number, the number of messages in the block, and the time the exchange sent the block.

When a feed has no market data to publish, the exchange keeps sending blocks that consist of a header only. Such blocks are called empty blocks, or heartbeats. They carry no messages, but their headers still report the exchange send time, so they remain a source of feed timing information for markets that trade rarely.

By default, the Handler does not report empty blocks: FeedListener::onMulticastMessageBlockBegin and FeedListener::onMulticastMessageBlockEnd are raised only for blocks that contain at least one message.

Set HandlerSettings::notifyOnEmptyMulticastMessageBlocks to true before constructing the Handler to have both events raised for empty blocks as well. In that case:

An empty block does not advance the sequence number the feed expects, so consecutive empty blocks all carry the same sequence number. While a feed is delivering normally the Handler reports each of them, including copies of the same block received over more than one network interface. Use MessageInfo::rawSentTime to tell them apart; do not treat the number of events as a count of what the exchange sent.

The option applies to live, snapshot and replayed feeds alike. Enabling it increases the number of event invocations on the Feed Engine worker threads, because every feed keeps sending empty blocks while it is idle.

A feed is not always delivering normally, and an empty block carries nothing the Handler can recover from, so it is dropped rather than deferred whenever the feed has something more pressing in hand:

  • once the Handler has detected a sequence gap on the feed, which happens when the blocks waiting behind it exceed HandlerSettings::sequenceGapMargin or when HandlerSettings::gapTimeoutInMilliseconds elapses, and lasts until the gap is reported and recovery begins. A heartbeat that arrives while any block is missing is not reported either: it carries the sequence number the exchange has reached, which is ahead of the one the Handler is still waiting for;
  • when a message block the Handler had been waiting for arrives in the same step and supersedes the heartbeat;
  • while the feed is in queue mode, which the Handler applies to both feeds when it starts recovering the books and lifts for each feed as it becomes usable again: the snapshot feed once the live feed has delivered its first block, and the live feed once the books are back in sync or once the Handler falls back to live-only operation. A queued feed buffers only the first empty block of a run, so it reports at most one per run, when its queue is replayed.

So on a feed that is delivering normally, every empty block it receives is reported, and the send time each one carries is the exchange's own timestamp for a block that has only just arrived. That is the property the option exists to provide. It does not extend to a queued feed, whose one buffered block is reported when the queue is replayed and carries a send time as old as the recovery.

Example

The following sample demonstrates how to receive notifications about errors that occur in the Handler:

// `ErrorListener` interface can be hidden from publicity
// to make Handler 'exclusive' user of the `onError` member.
class ErrorDumper : ErrorListener
{
public:
// Assigns itself to the given handler as error listener.
ErrorDumper(Handler* handler)
{
handler->registerErrorListener(this);
}
private:
// Implements base interface to dump errors to the console.
void onError(const Error& error)
{
std::cerr << "Error occurred: " << error.description() << std::endl;
}
};
HandlerSettings settings;
Handler handler(settings);
ErrorDumper errorDumper(&handler);