Onix Solutions Logo

ICE iMpact Multicast Price Feed Handler — Programming Guide

Version 1.18.0

TOC

Introduction

The Onix Solutions Java ICE iMpact Multicast Price Feed Handler (JIFH) is a Java library that provides an access to the ICE iMpact market data using multicast feed protocol. The JIFH exposes a high-level Java API that enables developers to efficiently build and maintain applications without expending time and effort supporting the raw low level API protocol.

Below are the key features of the ICE iMpact Market Data Feed Handler (JIFH):

Note
To fully comprehend the core concepts of the ICE iMpact Market Data System, we recommend reading the "ICE iMpact Multicast Feed Technical Specification" documentation prior to continuing with this guide. We also recommend viewing the source code of the sample project included within the software distribution package provided.

System Requirements

Getting Started

For those who are unfamiliar with the JIFH we recommend that you take the following actions in priority sequence:

Advanced Programming

JIFH State Transition Graph

The following diagram illustrates how the JIFH can change its state.

Handler State Graph

Connectivity Configuration Structure

All JIFH options are exposed and edited within the biz.onixs.ice.impact.handler.HandlerOptions class and this contains a path to the connectivity configuration file. This file contains definitions of multicast groups and the network addresses of corresponding servers with which the JIFH has to connect so as to receive market data. There are three major logical groupings of parameters which combine to make the configuration: the TCP connection information, Multicast groups and Market types.

TCP Connection Information

The TCP connection information section defines the attributes of the remote system to which a server connects to request primary information such as product definitions for selected markets. This section also defines security information such as username and password which are mandatory for the JIFH instance.
Typical TCP connection information section looks as follows:
<tcp ip="63.247.113.163" port="3000" userName="username from ICE" password="Password from ICE"/>
The values of IP address and port attributes define the connection to the remote system. The userName and password are the logon-related attributes.

Switch off order book processing

Order book processing is disabled when OrderBookListener is not registered via biz.onixs.ice.impact.handler.Handler#registerOrderBookListener. Otherwise it is enabled.

Incremental updates processing

The JIFH provides the ability to receive and process incremental updates to order books.

To process incremental updates to a Full Order Depth (FOD) book, a client should implement an interface of FullOrderDepthBookChangeListener and register a listener using Handler#registerFullOrderDepthBookChangeListener.

To process incremental updates to a Price Level (PL) Book, a client should implement an interface of PriceLevelBookChangeListener and register a listener using Handler#registerPriceLevelBookChangeListener.

The table below shows the BookChangeType enum values and corresponding ICE iMpact messages for FOD with their short description.

BookChangeType Full Order Depth message Description
UNKNOWN n\a Default value
SNAPSHOT Market Snapshot Order Message This message is for orders in snapshot only. It is different to order message for incremental updates.
ADD Add/Modify Order Message Both add and modify order notifications use one message format. A client should add the order to book if it is not already there. Otherwise, just overwrite the existing order.
CHANGE Add/Modify Order Message Both add and modify order notifications use one message format. A client should add the order to book if it is not already there. Otherwise, just overwrite the existing order.
REMOVE Delete Order Message Upon receipt of this message, a client should remove the order from it local book. Under certain scenarios, the message could be sent from the backend with an OrderID that does not exist on the client's book, in which case the client can just ignore it.

The table below shows the BookChangeType enum values ​​and corresponding ICE iMpact messages for PL with their short description.

BookChangeType Price Level message Description
UNKNOWN n\a Default value
SNAPSHOT Market Snapshot Price Level Message This message is for price level in snapshot only. For a given market, these messages follow directly after Market Snapshot Message.
ADD Add Price Level Message Upon receipt of this message, a client should add/insert a price level into the requisite position in the order book for the market specified. Existing price levels move down the stack if they were previously at or worse than the new entry. When the total number of levels with an order book exceeds what is supported (e.g. Top 5), the client should remove the bottom level. The exchange doesn't send out Delete Price Level message in this scenario.
CHANGE Change Price Level Message Upon receipt of this message, a client should update the price level at the specified position in its book for the given market.
REMOVE Delete Price Level Message Upon receipt of this message, a client should remove the price level in the order book for the market specified. All the levels that were worse that the level removed climb up the stack.

Feed identification

For every subscription the JIFH starts two feeds - a snapshot and a live. This pair of feeds has a unique integer identifier - feed ID. Some messages (like a Bundle Marker message) can be identified only by feed ID. To get the feed ID, a client should implement the FeedStateChangeListener interface. If the client wants to query if messages are being received by a specific feed ID, it should invoke MessageInfo#getFeedId().

Controlling Logging

By default, the JIFH logs all aspects of its activity whilst processing market data. The SLF4J (Simple Logging Facade for Java) is used internally by the JIFH. The SLF4J detects and uses the concrete logging implementation configured by user. By default, the Logback logging implementation is recommended.

The Logback (or any other logging implementation) must be configured prior to use. Examples of Logback configuration can be found within the JIFH samples. Details about Logback configuration are found here.

Listening to events of the ICE iMpact Handler

Events in the JIFH

There are five major events exposed by the JIFH:

Once the JIFH is started, it listens to market data from the network, processes it (decodes messages, validates message order, updates order books) and invokes the client code for further processing.

The JIFH processes market data asynchronously and uses a concept of events and event listeners to notify the client code about particular activity such as receipt of security definitions or book updates.

Listening for a specific events

For every event type such as Error Occurred the JIFH exposes a corresponding interface such as biz.onixs.ice.impact.handler.event.ErrorListener. The client code must implement this interface to be able to receive events of each type. The JIFH also exposes a member such as biz.onixs.ice.impact.handler.Handler#registerErrorListener. Thus an instance of the event handler may be associated with an appropriate inbound event of a particular instance of the biz.onixs.ice.impact.handler.Handler class.

Note
Associating a listener for a particular event with an instance of the biz.onixs.ice.impact.handler.Handler class must be performed while the Handler is in stopped stated. Once the JIFH has started then modifying the listener-event associations is not permitted, it may lead to unpredictable behaviour and cause unexpected errors..

Associating an event listener with an instance of the biz.onixs.ice.impact.handler.Handler class is also called subscribing to an event.

All listener interfaces are in the biz.onixs.ice.impact.handler.event namespace.

Event Listener interface to be implemented JIFH member to register listener Description
Futures/OTC Product Definition Received FuturesProductDefinitionListener registerFuturesProductDefinitionListener Fired by the JIFH when subscription is started. The JIFH calls an associated listener (an event handler) for each product definition it receives. Invocation of the event handler is performed in the same thread in which the Handler#start member was called. Once the subscription has successfully started events of this type will not be fired for subscribed markets again (until the next restart).
Strip Info Received StripInfoListener registerStripInfoListener Fired by the JIFH when subscription is started. The JIFH calls an associated listener (an event Handler) for each strip info messages it receives. Invocation of the event handler is performed in different threads.
Options Product Definition Received OptionsProductDefinitionListener registerOptionsProductDefinitionListener Fired by the JIFH when subscription is started. The JIFH calls an associated listener (an event handler) for each product definition it receives. Invocation of the event handler is performed in the same thread in which Handler#start member was called. Once the subscription has successfully started events of this type will not be fired for subscribed markets again (until the next restart).
Options Strategy Definition Received OptionsStrategyDefinitionListener registerOptionsStrategyDefinitionListener Fired by the JIFH when subscription is started. The JIFH calls an associated listener (an event handler) for each product definition it receives. Invocation of the event handler is performed in the same thread in which Handler#start member was called. Once the subscription has successfully started events of this type will not be fired for subscribed markets again (until the next restart).
Order Book Changed OrderBookListener registerOrderBookListener Fired by the JIFH when order book is changed. Invocation of the event handler is performed in different threads.
Price Level Book Change Received PriceLevelBookChangeListener registerPriceLevelBookChangeListener Fired by the JIFH when PL order book change is received. Invocation of the event handler is performed in different threads.
Full Order Depth Book Change Received FullOrderDepthBookChangeListener registerFullOrderDepthBookChangeListener Fired by the JIFH when FOD order book change is received. Invocation of the event handler is performed in different threads.
Market State Changed MarketStateListener registerMarketStateListener Fired by the JIFH when market state is changed. Invocation of the event handler is performed in different threads.
Trade Occurred TradeListener registerTradeListener Fired by the JIFH when trade occurred. Invocation of the event handler is performed in different threads.
End of Day Market Summary Message Received EndOfDayMarketSummaryListener registerEndOfDayMarketSummaryListener Fired by the JIFH when End of Day Market Summary message is received. Invocation of the event handler is performed in different threads.
RFQ Message Received RfqListener registerRfqListener Fired by the JIFH when RFQ message is received. Invocation of the event handler is performed in different threads.
Interval Price Limit Notification Message Received IntervalPriceLimitNotificationListener registerIntervalPriceLimitNotificationListener Fired by the JIFH when IPL Notification message is received. Invocation of the event handler is performed in different threads.
System Text Message Received SystemTextListener registerSystemTextListener Fired by the JIFH when System Text message is received. Invocation of the event handler is performed in different threads.
Handler State Changed HandlerStateListener registerHandlerStateListener Fired by the JIFH when it's state is changed. Invocation of the event handler is performed in different threads.
Error Occured ErrorListener registerErrorListener Fired by the JIFH when error occurred. Invocation of the event handler is performed in different threads.
Warning Occured WarningListener registerWarningListener Fired by the JIFH when warning occurred. Invocation of the event handler is performed in different threads.
Log-replay Error Occured LogReplayListener registerLogReplayListener Fired by the JIFH when log-replay error occurred. Invocation of the event handler is performed in different threads.
Log-replay Finished LogReplayListener registerLogReplayListener Fired by the JIFH when replay log is finished. Invocation of the event handler is performed in different threads.

Example

The following sample demonstrates how to listen to notifications for the receipt of security definitions.
public class MyListener implements FuturesProductDefinitionListener {
    private static final Logger LOG = LoggerFactory.getLogger(MyListener.class);

    public void onFuturesProductDefinition(FuturesProductDefinitionEventArgs args) {
        LOG.debug("onFuturesProductDefinition(): {}", args);
    }
}

public class Sample {
    private void run() throws Exception {
      final HandlerOptions handlerOptions = new HandlerOptions();
        final Handler handler = new Handler(handlerOptions);
        // ...
        final MyListener listener = new MyListener();
        handler.registerFuturesProductDefinitionListener(listener);
    }
}

Error Handling

Error Handling Concept

Being a Java library, the JIFH uses exceptions to report any errors arising. For example, the JIFH will raise a regular exception to report the inability to find a current license for the product. However, the JIFH processes market data asynchronously therefore is not able to report any further errors after market data processing is started. For this reason, the JIFH has to expose the biz.onixs.ice.impact.handler.event.ErrorListener interface and the biz.onixs.ice.impact.handler.Handler#registerErrorListener member to be able to subscribe to and handle errors.

Once an instance of the biz.onixs.ice.impact.handler.event.ErrorListener is assigned to the JIFH, it will invoke the biz.onixs.ice.impact.handler.event.ErrorListener#onError member every time an error occurs. The biz.onixs.ice.impact.handler.event.ErrorListener#onError member has several configurable parameters one of which defines a human-readable explanation (description) of the error.

An important aspect of the JIFH behaviour is that in normal use there is nothing special required to handle errors. In particular, once the subscription to market data has started successfully then the JIFH will process incoming market data and handle all recovery failures without any additional user action being required. There is no need to restart a subscription for market data manually as the JIFH recovery logic is designed for optimal recovery and will address non-fatal errors. Also, the JIFH recovers from detected errors in the optimal way. For example, in the event of a network-related issue the JIFH will rebuild only those books and market states which are based on market data from the problematic multicast feed channel. It will not invalidate and rebuild entire subscription for non-impacted channels.

Example

The following sample demonstrates how to receive error notifications.

public class MyListener implements ErrorListener {
    private static final Logger LOG = LoggerFactory.getLogger(MyListener.class);

    public void onError(ErrorEventArgs args) {
        LOG.debug("onError(): {}", args);
    }
}

public class Sample {
    private void run() throws Exception {
    final HandlerOptions handlerOptions = new HandlerOptions();
        final Handler handler = new Handler(handlerOptions);
        // ...
        final MyListener listener = new MyListener();
        handler.registerErrorListener(listener);
    }
}

Supported ICE iMpact Multicast Feed Message Specification

ICE iMpact Multicast Price Feed Handler supports ICE iMpact Multicast Feed Message Specification version 1.1.31.

FAQ

What is the difference between "Book Changed" and "Book Change Received" events?

If you subscribe to Order Book Changed, you will always have a consistent book. Price Level Book Change Received and Full Order Depth Book Change Received callbacks are designed for those who want to build and maintain books by themselves. Order Book Changed is an elementary action over the order book. As a rule there are multiple changes inside single snapshot and/or incremental refresh. For this reason, a book may not be valid between two changes. Only when all the changes are processed from the single network data (message like a snapshot and incremental refresh), the book is considered as valid. Book Change Received callbacks are called precisely at the time when all changes have been processed and a book appears to be valid and up-to-date.


© Onix Solutions