Introduction

This article is the other part of how to contribute data your data to Refinitiv article. The first article shows how to setup TREP for TRCC and how to contribute data with Elektron SDK Java/C++. This second article focuses on how to contribute your data to TRCC using Elektron WebSocket API through through Thomson Reuters Enterprise Platform (TREP).

Note: TRCC username, password and host list credentials are required for contributing data to Refinitiv. Please reach out to your Refinitiv sales associate to acquire TRCC access credentials.

TRCC Overview

The Thomson Reuters Contribution Channel (TRCC) is a new service for on-boarding content to the Refinitiv. Depending on the client's needs, access to the service will be fulfilled by one or more of the following products: Contributions Channel for TREP, Contributions Channel for Elektron API, Contributions Channel for Spreadsheet. TRCC aims for replacing the legacy Market Link IP (MLIP) system.

Contribution Setups

The main different between contributing with Elektron SDK C++/Java and the WebSocket API is the WebSocket API cannot connect to TRCC server directly. It requires TREP version 3.2.1 (and above) to take care of the JSON-OMM conversion, TRCC connection and login process for the WebSocket application.

The TREP infrastructure connects to TRCC through the delivery direct network via Tunnel Stream Aggregator (TSA) adapter, which is a private network (TLS encrypted) between a client site and Refinitiv. The TSA adapter is already packaged with the ADH version 3.2, and needs to be configured. You can find more detail regarding the TREP-TRCC configurations in Contributing your data to Thomson Reuters article page (Contribution through TREP section).

You can find ADH-TRCC configuration parameters example in the project's /trep_config/rdms_trcc.cnf file (please note that it is not a completed ADH configuration file).

Once this configuration is complete and the Contribution service TRCC is available to the user, as shown in the Service-Up state in ADH and ADS consoles. The Elektron WebSocket application can be used to POST data to this service in TREP.

If you are interested to contribute data using the RSSL connection (with or without TREP), please visit the following series of Elektron SDK and TRCC based on your prefer API:

Note: The reader must have an understanding of Elektron SDK, WebSocket programming, 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 in Python programming language.

Contribution Process

The application requires the following steps to contribute data to TRCC via TREP:

  1. The application initiates a WebSocket connection with ADS server.
  2. Application sends a OMM Login request message to ADS in JSON format.
  3. Once the application receives a Login Refresh message from ADS, the application can contribute data to TRCC via Off-Stream Post message.
  4. The TRCC Off-Stream Post message must have the following conditions:
    • The Ack attribute must be true
    • The message must contain the PostID attribute and value
    • The Key information which includes Name and Service attributes that refer to contribution RIC name and TRCC contribution service name
    • The Message payload must be an Update message type
    • The Message payload must contain the same Key information as the Post message

The example TRCC Off-Stream Post message is shown in Posting result example section below.

Note: Please note that TRCC supports Off-Stream Post only.

If you are not familiar with Elektron WebSocket API Posting concept, please visit Contributing Data to TREP using the Websocket API article which will give you a full explanation of the WebSocket API Posting mechanisms and process.

Application Code Walkthrough

Following snippet of code is taken/modified from Elektron WebSocket API Python market_price_posting.py example, available in the Example Applications package. Complete TRCC contribution posting sample is in TR-API-Samples GitHub page.

The example project contains both Python console application and Jupyter Notebook application. please check the README.md in the source code project for more detail regarding how to run the example.

A successful login to TREP, results in the Login-Refresh message. The process_login_response() function then calls c function to send the Post message.

def process_message(ws, message_json):  # Process all incoming messages.
    """ Parse at high level and output JSON of message """
    message_type = message_json['Type']

    if message_type == "Refresh":
        if 'Domain' in message_json:
            message_domain = message_json['Domain']
            if message_domain == "Login":
                process_login_response(ws, message_json)

# Process incoming Login Refresh Response message.
def process_login_response(ws, message_json):
    """ Send Off-Stream Post """
    print("Sending Off-Stream Post to TREP Server")
    send_market_price_post(ws)

The send_market_price_post() function creates the Off-Stream post message in JSON format, then sends it to TREP as follows:

# Create JSON Off-Stream Post message and sends it to ADS server.
def send_market_price_post(ws):
    global post_id
    global bid_value
    global ask_value
    global primact_1_value
    """ Send a post message contains a market-price content to TRCC """

    """ Contribution fields """
    contribution_fields = {
        "BID": bid_value,
        "ASK": ask_value,
        "PRIMACT_1": primact_1_value
    }

    """ OMM Post msg Key """
    mp_post_key = {
        "Name": post_item_name,
        "Service": service_name
    }

    """ OMM Post Payload """
    contribution_payload_json = {
        "ID": 0,
        "Type": "Update",
        "Domain": "MarketPrice",
        "Fields": contribution_fields,
        "Key": {}
    }

    """ OMM Off-Stream Post message """
    mp_post_json_offstream = {
        "Domain": "MarketPrice",
        "Ack": True,
        "PostID": post_id,
        "PostUserInfo": {
            "Address": position,
            "UserID": int(app_id)
        },
        "Key": {},
        "Message": {},
        "Type": "Post",
        "ID": login_id
    }

    contribution_payload_json["Key"] = mp_post_key
    mp_post_json_offstream["Key"] = mp_post_key
    mp_post_json_offstream["Message"] = contribution_payload_json

    ws.send(json.dumps(mp_post_json_offstream))
    print("SENT:")
    print(json.dumps(mp_post_json_offstream,
                     sort_keys=True, indent=2, separators=(',', ':')))	

 

Posting result example

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

Initiate and Login to TREP

Connecting to WebSocket ws://localhost:15000/WebSocket ...
WebSocket successfully connected!
SENT:
{
  "Domain":"Login",
  "ID":1,
  "Key":{
    "Elements":{
      "ApplicationId":"256",
      "Position":"10.42.68.162"
    },
    "Name":"root"
  }
}
RECEIVED:
[
  {
    "Domain":"Login",
    "Elements":{
      "MaxMsgSize":61430,
      "PingTimeout":30
    },
    "ID":1,
    "Key":{
      "Elements":{
        "AllowSuspectData":1,
        "ApplicationId":"256",
        "ApplicationName":"ADS",
        "Position":"10.42.68.162",
        "ProvidePermissionExpressions":1,
        "ProvidePermissionProfile":0,
        "SingleOpen":1,
        "SupportBatchRequests":7,
        "SupportEnhancedSymbolList":1,
        "SupportOMMPost":1,
        "SupportOptimizedPauseResume":1,
        "SupportPauseResume":1,
        "SupportStandby":1,
        "SupportViewRequests":1
      },
      "Name":"root"
    },
    "State":{
      "Data":"Ok",
      "Stream":"Open",
      "Text":"Login accepted by host apis30."
    },
    "Type":"Refresh"
  }
]

Contribution data via an Off-Stream Post message

Sending Off-Stream Post to TREP Server
SENT:
{
  "Ack":true,
  "Domain":"MarketPrice",
  "ID":1,
  "Key":{
    "Name":"<CONTRIBUTION_RIC>",
    "Service":"<CONTRIBUTION_Service>"
  },
  "Message":{
    "Domain":"MarketPrice",
    "Fields":{
      "ASK":35.48,
      "BID":34.25,
      "PRIMACT_1":116.5
    },
    "ID":0,
    "Key":{
      "Name":"<CONTRIBUTION_RIC>",
      "Service":"<CONTRIBUTION_Service>"
    },
    "Type":"Update"
  },
  "PostID":1,
  "PostUserInfo":{
    "Address":"10.42.68.162",
    "UserID":256
  },
  "Type":"Post"
}
Here
RECEIVED: 
[
  {
    "AckID":1,
    "ID":1,
    "Key":{
      "Name":"<CONTRIBUTION_RIC>",
      "Service":"<CONTRIBUTION_Service>"
    },
    "Type":"Ack"
  }
]

References

For any question related to this example or Elektron WebSocket API, please use the Developer Community Q&A Forum.