Introduction

In this article we will visit contributions and explore different mechanisms to contribute your data to Refinitiv. It is focused around the new Thomson Reuters Contribution Channel (TRCC), which is a replacement for the legacy Market Link IP (MLIP) system.

Data Contribution is a means to send your pricing data to Refinitiv, from where it can fan out globally. Leading market participants, such as banks and brokers, use Refinitiv to publish and distribute their information to the community of financial professions, in order to advertise their prices to clients and prospects.

The Contributed Data is sent directly from the client to Refinitiv and not via a financial exchange. A client can contribute data either using a Desktop Product like:

  • Insertlink for Eikon
  • Eikon Excel
  • Thomson Reuters Spreadsheet Publisher (TRSP)

or by writing their own contribution applications using the Elektron SDK in C++ or Java.

In this article we will focus on latter - contribution of data using the API and the TR Contribution Channel. The reader must have an understanding of Elektron SDK, and be familiar with OMM Market Price data. You should also have a basic understanding of Thomson Reuters market data infrastructure components like ADS, ADH etc. The code snippets in this article are shown for EMA - Java SDK.

Contribution setups

There are two key options, through which an API developer can contribute data to Refinitiv head-end:

This option is to use and configure the Thomson Reuters Enterprise Platform (TREP), to take care of contribution specific connection and login details.

The option is suited for clients, who do not have an on-site TREP installation, and it utilizes an encrypted tunnel connection to connect to TRCC servers.

The diagram below shows the complete data contribution and subscription cycle. The contributor applications on the bottom left quadrant connect through TREP (ADS and ADH), or a direct connection. The contributed data makes its way upstream to the Elektron core, from where it can be distributed out to any Elektron data subscriber globally (shown on the right).

Contribution through TREP

The Thomson Reuters Enterprise Platform (TREP) can be configured to take care of contribution specific connection and login details. It entails configuring the Tunnel Stream Aggregator (TSA) in the ADH. Once TREP configuration is complete, ADH takes care of the work required to connect to contribution head-end, and all an API application does is off-stream posting. The TREP infrastructure connects to TRCC through the delivery direct network, which is a private network between a client site and Thomson Reuters. The TSA adapter is already packaged with the ADH version 3.2, and needs to be configured.

Here is a sample TSA configuration for Advanced Distribution Hub (ADH):

hostname*adh*primeTopology : True
hostname*adh*routeList : trcc
hostname*adh*trcc.route*TRCC*Interactive*groupList : 1, 3, 4, 6
hostname*adh*trcc.route*TRCC*appServiceName : DDS_TRCE
hostname*adh*trcc.route*TRCC*commLinks : Interactive
hostname*adh*trcc.route*TRCC*dacsAttributes :
hostname*adh*trcc.route*TRCC*datastreamMonitor*interruptionDetection : False
hostname*adh*trcc.route*TRCC*datastreamMonitor*interruptionDuration : 4
hostname*adh*trcc.route*TRCC*datastreamMonitor*trafficWindow : 10
hostname*adh*trcc.route*TRCC*downloadCriteriaName :
hostname*adh*trcc.route*TRCC*hashIDs :
hostname*adh*trcc.route*TRCC*initialOpenLimit : 256
hostname*adh*trcc.route*TRCC*lockedDumpFile :
hostname*adh*trcc.route*TRCC*maxCache : 10000
hostname*adh*trcc.route*TRCC*primaryProvider : True
hostname*adh*trcc.route*TRCC*serverCost : 0
hostname*adh*trcc.route*TRCC*serverId : 287
hostname*adh*trcc.route*TRCC*serverPartitionList :
hostname*adh*trcc.route*TRCC*serverPartitionNegationList :
hostname*adh*trcc.route*TRCC*tunnelStream*numIpcOutputBuffers : 400
hostname*adh*trcc.route*TRCC*tunnelStream*userName :  ****
hostname*adh*trcc.route*TRCC*tunnelStream*userPassword : ****
hostname*adh*trcc.route*TRCC*updateRateThreshold : 200
hostname*adh*trcc.route*TRCC.enableTunnelStreamAggregation : True
hostname*adh*trcc.route*allowSuspectData : False
hostname*adh*trcc.route*applicationId : 256
hostname*adh*trcc.route*compressionType : 0
hostname*adh*trcc.route*encryptionProtocol : TLSv1.2
hostname*adh*trcc.route*hostList : **** 
hostname*adh*trcc.route*maxIncomingBytesPerSecond : 0
hostname*adh*trcc.route*maxIncomingMessagesPerSecond : 0
hostname*adh*trcc.route*minCompressionThreshold : 0
hostname*adh*trcc.route*numIpcInputBuffers : 10
hostname*adh*trcc.route*numIpcOutputBuffers : 400
hostname*adh*trcc.route*pingInterval : 2
hostname*adh*trcc.route*port : 443
hostname*adh*trcc.route*protocol : rssl
hostname*adh*trcc.route*proxyHost :
hostname*adh*trcc.route*proxyPort :
hostname*adh*trcc.route*recoveryInterval : 10
hostname*adh*trcc.route*routeEnabled : True
hostname*adh*trcc.route*rsslConnectionType : encrypted
hostname*adh*trcc.route*serviceList : TRCC
hostname*adh*trcc.route*singleOpen : True
hostname*adh*trcc.route*tcpNoDelay : False
hostname*adh*trcc.route*tcpRecvBufSize : 524288
hostname*adh*trcc.route*tcpSendBufSize : 64240
hostname*adh*trcc.route*useReactor : True
hostname*adh*trcc.route*userName : rmds
hostname*ads*admin*sharedMemorySize : 12000000
hostname*ads*bindAggStatsThread :

Here we configured the Service Name as TRCC and provided the TRCC login userName and userPassword. We also defined a route with name trcc and configured it with the server hostList and port. TSA adapter will use rssl protocol and encrypted rssl connection. All this configuration information is available from the TR Account Manager. It is not advisable to change the ADH configuration, if you are not familiar with the configuration procedures. Please consult your Market Data administrator for any questions regarding this.

When the ADH is restarted with this configuration, the log file entries show the status of tunnel stream aggregator:

<torsrmds11.1.adh.serviceGenerator.trcc.route.TRCC: Debug: Thu May 17  07:00:11 2018>
Server (TRCC, 276)  has been restarted on network.
<END>

<torsrmds11.1.adh.sourceSSLDistribution.sslDispatcher.trcc.route.DDS_TRCE: Info: Thu May 17  07:00:11 2018>
Server "TRCC" started for RSSL application "DDS_TRCE:10" on route "trcc". Tunnel stream is open.
<END>

<torsrmds11.1.adh.sourceSSLDistribution.sslDispatcher.trcc.route.DDS_TRCE: Info: Thu May 17  07:00:11 2018>
Tunnel stream is open with maxMsgSize = 614400; maxFragmentSize = 6144; flow control type = 1; Tunnel stream recv window size = 12288; Tunnel stream send window size = 750000; Tunnel stream authentication type = 1; Tunnel stream data integrity type = 1
<END>

Once this configuration is complete and the Contribution service TRCC is available to the user, as shown in the Service-Up state in ADH console.

Now, an EMA application can be used to POST data to this service in TREP. Following snippet of code is taken/modified from EMA consumer example series300\example341__MarketPrice__OffStreamPost, available in the SDK package. Complete TREP contribution posting sample is attached here.

A successful login to TREP, results in the Login-Refresh message.

public void onRefreshMsg(RefreshMsg refreshMsg, OmmConsumerEvent event)	{
	if(refreshMsg.domainType() == EmaRdm.MMT_LOGIN && 
		refreshMsg.state().streamState() == OmmState.StreamState.OPEN && 
		refreshMsg.state().dataState() == OmmState.DataState.OK )	{
		// login successful, save variables
		_postStreamID = refreshMsg.streamId();
		_ommConsumer = (OmmConsumer) event.closure();
		_streamHandle = event.handle();
		// start posting
		postMessage();
	}

The method postMessage which populates and sends the contribution fields is as follows:

public void postMessage()	{
	// update the contributed fields
	FieldList nestedFieldList = EmaFactory.createFieldList();
	nestedFieldList.add(EmaFactory.createFieldEntry().real(22, _bid++, OmmReal.MagnitudeType.EXPONENT_NEG_1));
	nestedFieldList.add(EmaFactory.createFieldEntry().real(25, _ask++, OmmReal.MagnitudeType.EXPONENT_NEG_1));

	// create an update message for our item
	UpdateMsg nestedUpdateMsg = EmaFactory.createUpdateMsg()
		.streamId(_postStreamID)
		.name("CONTRIBUTION_RIC")
		.payload(nestedFieldList);
	
	// create a post message, and embed the update
	PostMsg postMsg = EmaFactory.createPostMsg()
		.postId(_postID++)
		.serviceName("TRCC")
		.name("CONTRIBUTION_RIC")
		.solicitAck(true)
		.payload(nestedUpdateMsg)	
		.complete(true);
		
	// send to TREP
	_ommConsumer.submit(postMsg, _streamHandle);
}		

This posted data will automatically be forwarded to TRCC and thus contributed to Thomson Reuters. The output from this EMA sample shows a successful login to ADS, followed by initial contribution upon login-refresh and multiple contributions upon receiving an acknowledgment:

Jul 03, 2018 2:33:27 PM com.thomsonreuters.ema.access.ChannelCallbackClient reactorChannelEventCallback
INFO: loggerMsg
    ClientName: ChannelCallbackClient
    Severity: Info
    Text:    Received ChannelUp event on channel Channel
        Instance Name EmaConsumer_1
        Component Version ads3.2.1.L1.linux.tis.rrg 64-bit
loggerMsgEnd


----- Refresh message ----
RefreshMsg
    streamId="1"
    domain="Login Domain"
    solicited
    RefreshComplete
    state="Open / Ok / None / 'Login accepted by host ***.'"
    itemGroup="00 00"
    name="user"
    nameType="1"
    Attrib dataType="ElementList"
        ElementList
            ElementEntry name="AllowSuspectData" dataType="UInt" value="1"
            ElementEntry name="ApplicationId" dataType="Ascii" value="256"
            ElementEntry name="ApplicationName" dataType="Ascii" value="ADS"
            ElementEntry name="Position" dataType="Ascii" value="10.116.81.180/Carbon2"
            ElementEntry name="ProvidePermissionExpressions" dataType="UInt" value="1"
            ElementEntry name="ProvidePermissionProfile" dataType="UInt" value="0"
            ElementEntry name="SingleOpen" dataType="UInt" value="1"
            ElementEntry name="SupportEnhancedSymbolList" dataType="UInt" value="1"
            ElementEntry name="SupportOMMPost" dataType="UInt" value="1"
            ElementEntry name="SupportPauseResume" dataType="UInt" value="0"
            ElementEntry name="SupportStandby" dataType="UInt" value="0"
            ElementEntry name="SupportBatchRequests" dataType="UInt" value="7"
            ElementEntry name="SupportViewRequests" dataType="UInt" value="1"
            ElementEntry name="SupportOptimizedPauseResume" dataType="UInt" value="0"
        ElementListEnd
    AttribEnd
RefreshMsgEnd

System refresh, starting posting...
----- Ack message ----
AckMsg
    streamId="1"
    domain="MarketPrice Domain"
    ackId="1"
    name="CONTRIBUTION_RIC"
    nameType="1"
    serviceId="290"
AckMsgEnd

Continue posting...
----- Ack message ----
AckMsg
    streamId="1"
    domain="MarketPrice Domain"
    ackId="2"
    name="CONTRIBUTION_RIC"
    nameType="1"
    serviceId="290"
AckMsgEnd

Contribution without TREP

When using the API to contribute without using the TREP infrastructure, the application also has to deal with additional complexity of connecting and establishing an encrypted tunnel to one of the TRCC servers in the cloud. This is more suited for clients, who do not have an on-site TREP installation. These customers will have the option to connect to TRCC through either Internet or Delivery Direct network.

To contribute directly to TRCC, an EMA application undertakes following three steps:

  1. Establish an encrypted Tunnelstream connection to one of the TRCC hosts. For production applications, it is recommended to establish two simultaneous connections, to two different servers.
  2. Upon establishing the tunnel stream, send the login request.
  3. Once the login is accepted, the application is ready to start contributing on the login substream.

An application should only contribute to a single stream at any given time. The second stream is for redundancy purposes, and should only be used if there are issues with the first one. Once the encrypted connection is established, the process of posting data for contribution is quite similar to the code snippet shown earlier.

The EMA sample: series400\example440__System__TunnelStream which ships with the SDK distribution, forms the basis of establishing the encrypted tunnel. Please refer to EMA Java Contributions tutorial and EMA C++ Contributions tutorial, to view the step by step process, and complete code sample to build and run a contribution app.

References

Elektron Message API