Elektron SDK - Java

API Family: Elektron

ETA Tutorial 5 - Retrieving and decoding level 2 content

Download tutorial source code

Click here to download

Last update May 2018
Environment Windows, Linux
Compilers JDK 1.7 or greater
Prerequisite ETA Tutorial 4 - Retrieving and decoding level 1 content

Introduction

Extending from Tutorial 4, this tutorial will support additional RDM (Reuters Data Models) types such as the Symbol List as well as level 2 content - MBP (Market By Price) and MBO (Market By Order) models.

Description

Within our implementation, we extend the functionality defined within basicMsgHandler.java to include additional message structure parsing algorithms to manage the new models of data we can retrieve from the OMM-based data Provider. In addition, we will demonstrate the alternative way to load our dictionary fields used to parse RWF messages from our provider that we outlined within ETA Tutorial 4 - Retrieving and decoding level 1 content.

Implementation Overview - Requesting and parsing additional RDM message

In tutorial 4, we put in place the basic framework to request, process and decode level 1 Market Price data. Within this framework, a generic request routine sendItemRequest was designed to not only allow for level 1 requests, but also allow for multiple message model types. In addition, the framework to parse multiple message types was also established to identify message structure as opposed to message model types. In the case of Symbol List and level 2 data, they all utilize the same message structure thus allowing for a single processing algorithm to parse.

As in the case of Tutorial 4, we can issue our request for new models of data upon a CHANNEL_READY event as defined in the following:

// Service name
private static final String serviceName = "ELEKTRON_AD";

// Item name
private static final List itemNames = Arrays.asList("BB.TO");

// Domain Type
private static final int domainType = DomainTypes.MARKET_BY_PRICE;

...

RsslReactorCallbackRet channelEventCallback(RsslReactor *pReactor, RsslReactorChannel *pReactorChannel, RsslReactorChannelEvent *pConnEvent)
{
    switch (pConnEvent->channelEventType)
    {
        ...

        case ReactorChannelEventTypes.CHANNEL_READY:
        {
            // The Reactor has successfully completed the main session establishment with our provider
            if ( directoryHandler.isRequestedServiceAvailable() )
            {
                if ( msgHandler.sendItemRequest(event.reactorChannel(), itemNames,
                                                directoryHandler.getService(),
                                                domainType, errorInfo) != ReactorCallbackReturnCodes.SUCCESS )
                {
                    System.out.println(errorInfo.error().text());
                }
            }
            else
                System.out.println("Unable to request data.  Service: " + serviceName + " is unavailble");

            break;
        }

        ...
    }
}

In the above code segment, the domainType was changed to a level 2 message model. In our example, we chose the MBP, but could also have set MBO or Symbol List - so long as the specified service supports that model.

The above request will result in a MBP response that will contain a Map as the core of its message structure. Each element within the Map will contain a FieldList. In some cases, the messages will contain a SUMMARY section at the beginning of the message. The SUMMARY is a nested FieldList structure. Because we have already defined a FieldList structure for our level 1 (Market Price) message in Tutorial 4, the Map can piggyback off of the FieldList processing to handle its nested structures.

To recognize the new structure of data, we extend the functionality within the processRDMResponse function defined within the basicMsgHandler.java file:

int processRDMResponse(Msg msg, DecodeIterator dIter, DataDictionary dictionary)
{
    int retval = CodecReturnCodes.SUCCESS;

    ...

    switch (msg.msgClass())
    {
        case MsgClasses.REFRESH:
        case MsgClasses.UPDATE:
        {
            switch (msg.containerType())
            {
                case DataTypes.FIELD_LIST:
                    retval = decodeFieldList(msg, dIter, dictionary);
                    break;
                case DataTypes.MAP:
                    retval = decodeMap(msg, dIter, dictionary);
                    break;
                default:
                    output.append("Unable to process RDM msg with container type: " + msg.containerType());
                    break;
            }
            break;
        }

        ...
    }

    return( retval );
}

The decodeMap routine processes map elements and utilizes our existing FieldList processing to handle nested list structures. While the processing details are important, it is beyond the scope of this tutorial.

Setup and Configuration

Refer to Setup and Configuration section within the ETA Tutorial 2 - Establishing a connection to a Provider prior to building and running this tutorial.

Build and run

Refer to the Build and run section within the ETA Tutorial 1 - Creating a starter consumer application for instructions to successfully execute this tutorial.

Note: The build instructions for this tutorial include an additional step to enable us to load our dictionary from local files. The build instructions will copy the files from your ETA installation to be automatically used when you run this tutorial.

Eg (Windows):

> buildConsumer 5

> runConsumer 5

In our execution, because we have included the dictionary files locally when we built the tutorial, the application will not attempt to download from the OMM-based Provider.

Note: We issued a streaming request for a MBP item which will result in an initial refresh followed by updates showing change based on market events. It is worth noting that very large structures are normally broken down into multiple messages. This is especially common for both MBP and MBO models.


Running tutorial 5...
Ultra Performance API (UPA), Java Edition, LibraryVersionInfo
        productVersion: etaj3.0.0.L1.all.rrg
        productInternalVersion: etaj3.0.0.L1
        productDate: Fri April 29 12:24:15 CST 2016 Thomson Reuters
basicConsumer initializing...

Successfully loaded local dictionaries

Connection up!  Registering our connection within our event loop

Received Login Refresh for Username: U8007876
Received serviceName: DDN_SSL. State:           StateFilter:
                        ServiceState: 1
                        AcceptingRequests: 1

Received serviceName: ELEKTRON_AD. State:               StateFilter:
                        ServiceState: 1
                        AcceptingRequests: 1

Found service of Interest: ELEKTRON_AD.  Using serviceId: 356

Received serviceName: DDN_RDF. State:           StateFilter:
                        ServiceState: 1
                        AcceptingRequests: 1

Received serviceName: EZD_RSSL. State:          StateFilter:
                        ServiceState: 1
                        AcceptingRequests: 1

Received serviceName: EZD_SSL. State:           StateFilter:
                        ServiceState: 1
                        AcceptingRequests: 1

Channel is ready. Subscribing to item(s): [BB.TO]

BB.TO
DOMAIN: MARKET_BY_PRICE
REFRESH: State: Open/Ok/None - text: "All is well"
SUMMARY DATA
        1/PROD_PERM: 3044
        3/DSPLY_NAME: BLACKBERRY LTD
        15/CURRENCY: CAD(124)
        17/ACTIV_DATE: 16 JUN 2016
        131/PRC_QL2: 
        198/LOT_SIZE_A: 100.0
        259/RECORDTYPE: 113
        1080/PREF_DISP: 
        1709/RDN_EXCHD2: TOR(10)
        3183/LIST_MKT: TOR
        3422/PROV_SYMB: BB
        3423/PR_RNK_RUL: NOR(1)
        3425/OR_RNK_RUL: PTS (2)
        3694/MNEMONIC: BB
        3915/MKT_STATUS: S
        4148/TIMACT_MS: 49381890
        5357/CONTEXT_ID: 2171.0
        6401/DDS_DSO_ID: 8244
        6480/SPS_SP_RIC: .[SPSTL2TRL2
        6516/BOOK_STATE: N(1)
        6517/HALT_REASN: 
        6518/ORD_ENT_ST: E(1)
        6519/MKT_OR_RUL:  (0)
        6614/TRD_STATUS: N (1)
        6615/HALT_RSN: 

ORDER ID: 8.860000A
ACTION: ADD
BB.TO
DOMAIN: MARKET_BY_PRICE
REFRESH: State: Open/Ok/None - text: "All is well"
        3427/ORDER_PRC: 8.86
        3428/ORDER_SIDE: ASK(2)
        3430/NO_ORD: 11
        4356/ACC_SIZE: 8000.0
        6527/LV_TIM_MS: 49275078
        6528/LV_TIM_MSP: 13
        6529/LV_DATE: 16 JUN 2016

ORDER ID: 22.000000A
ACTION: ADD
BB.TO
DOMAIN: MARKET_BY_PRICE
REFRESH: State: Open/Ok/None - text: "All is well"
        3427/ORDER_PRC: 22.0
        3428/ORDER_SIDE: ASK(2)
        3430/NO_ORD: 1
        4356/ACC_SIZE: 600.0
        6527/LV_TIM_MS: 44940434
        6528/LV_TIM_MSP: 404
        6529/LV_DATE: 16 JUN 2016

...

ORDER ID: 12.500000A
ACTION: ADD
BB.TO
DOMAIN: MARKET_BY_PRICE
REFRESH: State: Open/Ok/None - text: "All is well"
        3427/ORDER_PRC: 12.5
        3428/ORDER_SIDE: ASK(2)
        3430/NO_ORD: 12
        4356/ACC_SIZE: 11900.0
        6527/LV_TIM_MS: 61822404
        6528/LV_TIM_MSP: 379
        6529/LV_DATE: 27 APR 2016

ORDER ID: 9.800000A
ACTION: ADD
BB.TO
DOMAIN: MARKET_BY_PRICE
REFRESH: State: Open/Ok/None - text: "All is well"
        3427/ORDER_PRC: 9.8
        3428/ORDER_SIDE: ASK(2)
        3430/NO_ORD: 6
        4356/ACC_SIZE: 9500.0
        6527/LV_TIM_MS: 39619864
        6528/LV_TIM_MSP: 123
        6529/LV_DATE: 31 MAY 2016

ORDER ID: 7.060000B
ACTION: ADD
BB.TO
DOMAIN: MARKET_BY_PRICE
REFRESH: State: Open/Ok/None - text: "All is well"
        3427/ORDER_PRC: 7.06
        3428/ORDER_SIDE: BID(1)
        3430/NO_ORD: 1
        4356/ACC_SIZE: 300.0
        6527/LV_TIM_MS: 56767412
        6528/LV_TIM_MSP: 651
        6529/LV_DATE: 13 JUN 2016


-----------------------------------------------------------------------------------
BB.TO
DOMAIN: MARKET_BY_PRICE
REFRESH: State: Open/Ok/None - text: "All is well"

ORDER ID: 8.660000B
ACTION: ADD
BB.TO
DOMAIN: MARKET_BY_PRICE
REFRESH: State: Open/Ok/None - text: "All is well"
        3427/ORDER_PRC: 8.66
        3428/ORDER_SIDE: BID(1)
        3430/NO_ORD: 12
        4356/ACC_SIZE: 2500.0
        6527/LV_TIM_MS: 49293441
        6528/LV_TIM_MSP: 439
        6529/LV_DATE: 16 JUN 2016

ORDER ID: 17.750000A
ACTION: ADD
BB.TO
DOMAIN: MARKET_BY_PRICE
REFRESH: State: Open/Ok/None - text: "All is well"
        3427/ORDER_PRC: 17.75
        3428/ORDER_SIDE: ASK(2)
        3430/NO_ORD: 1
        4356/ACC_SIZE: 100.0
        6527/LV_TIM_MS: 45133059
        6528/LV_TIM_MSP: 398
        6529/LV_DATE: 16 MAY 2016

...

ORDER ID: 9.350000A
ACTION: ADD
BB.TO
DOMAIN: MARKET_BY_PRICE
REFRESH: State: Open/Ok/None - text: "All is well"
        3427/ORDER_PRC: 9.35
        3428/ORDER_SIDE: ASK(2)
        3430/NO_ORD: 2
        4356/ACC_SIZE: 3400.0
        6527/LV_TIM_MS: 51259779
        6528/LV_TIM_MSP: 681
        6529/LV_DATE: 10 JUN 2016


-----------------------------------------------------------------------------------
DOMAIN: MARKET_BY_PRICE
UPDATE
SUMMARY DATA
        4148/TIMACT_MS: 49382436

ORDER ID: 8.790000B
ACTION: UPDATE
DOMAIN: MARKET_BY_PRICE
UPDATE
        3427/ORDER_PRC: 8.79
        3428/ORDER_SIDE: BID(1)
        4356/ACC_SIZE: 9300.0
        3430/NO_ORD: 11
        6527/LV_TIM_MS: 49382436
        6528/LV_TIM_MSP: 539
        6529/LV_DATE: 16 JUN 2016

------------------------------------------------------------------------------------
DOMAIN: MARKET_BY_PRICE
UPDATE
SUMMARY DATA
        4148/TIMACT_MS: 49384226

ORDER ID: 8.810000A
ACTION: UPDATE
DOMAIN: MARKET_BY_PRICE
UPDATE
        3427/ORDER_PRC: 8.81
        3428/ORDER_SIDE: ASK(2)
        4356/ACC_SIZE: 14400.0
        3430/NO_ORD: 16
        6527/LV_TIM_MS: 49383682
        6528/LV_TIM_MSP: 879
        6529/LV_DATE: 16 JUN 2016


------------------------------------------------------------------------------------
DOMAIN: MARKET_BY_PRICE
UPDATE
SUMMARY DATA
        4148/TIMACT_MS: 49384226

ORDER ID: 8.810000A
ACTION: UPDATE
DOMAIN: MARKET_BY_PRICE
UPDATE
        3427/ORDER_PRC: 8.81
        3428/ORDER_SIDE: ASK(2)
        4356/ACC_SIZE: 15000.0
        3430/NO_ORD: 17
        6527/LV_TIM_MS: 49383682
        6528/LV_TIM_MSP: 879
        6529/LV_DATE: 16 JUN 2016


------------------------------------------------------------------------------------

References

For more information, refer to the ETA Java Development Guides.

Tutorial Group: 
ETA Consumer