In this article we will explore the use of websocket API to contribute some data to Refinitiv. The article is focused around the Refinitiv Contribution Channel (RCC). 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.
There are a few articles on Refinitiv developers portal which describe how to contribute. These are geared towards different setup environments, which can be used to contribute locally or to RCC. I hope to clear the use case in the following matrix:
Contributing Data to Refinitiv Real-Time using the Websocket API | This article describes posting user data to the in-house (local) Refinitiv Real-Time Distribution System (formerly TREP). The posted data is not sent to RCC and hence not sent to the whole world and stays within the organization. This mechanism is used in a large organization where multiple discreet applications/departments advertise their prices/analytics to other applications in house. |
Contributing your data to Refinitiv | This article describes contributing the data to Refinitiv using RCC, but is aimed at users of Refinitiv Real-Time SDK like EMA. |
Contributing your data to Refinitiv with WebSocket API and Refinitiv Real-Time Distribution System | This article describes contributing to Refinitiv using websocket API, but uses the Refinitiv Real-Time Distribution System to actually forward the contributed data to RCC. |
Current article | This article focuses on using the websocket API for direct contribution to Refinitiv Contribution Channel without the use of Real-Time Distribution System. |
Refinitiv Contribution Channel Overview
The Refinitiv Contribution Channel (RCC) is a new service for on-boarding content to 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 Refinitiv Real-Time Advanced Distribution Server/Advanced Data Hub Server
- Contributions Channel for Real-Time API
- Contributions Channel for Spreadsheet
RCC aims for replacing the legacy Market Link IP (MLIP) system. Recently the RCC capability was enhanced to allow the websocket API to post and hence contribute the data. This functionality greatly simplifies the application development, and allows the use of any programming language (vs only C++ or Java supported by the SDK).
Here is the flow of the contribution setup:
Websockets semantics
The general setup for contribution with websocket/RCC is similar to that with subscribing to a streaming market data. If you are already familiar with the concept of using REST API to get an authorization token, use service discovery and then initiate a streaming websocket connection; then all the same concepts will apply to contribution as well. Here is a block diagram showing how this all works:
The details on the above sequence flow along with the sample code are provided in the Websocket contribution tutorial
The user begins with getting an Access token using their RCC credentials. This is a REST API call, see details in this tutorial.
Establish a websocket connection and send in the login request using the token.
Once login is accepted, start sending your data contributions to the world.
Since, the steps 1 and 2 are described in detail in the articles and tutorials, I will focus on the important points pertaining to contribution only.
Login Message
The endpoint for getting an Access token and connecting to websocket is different depending on the UAT or production environment as shown below:
Login, get Access token from:
Env | URL |
UAT | api.ppe.refinitiv.com |
Production | api.refinitiv.com |
Establish a secure websocket connection at:
Env | URL | Port |
UAT | SERVER-PROTOCOL-REGION.platform.refinitiv.com | 443 |
PROD | SERVER-PROTOCOL-REGION..platform.refinitiv.com | 443 |
User should choose the geographic REGION closest to them, which can be amers, emea or apac. You can get the VIP information about complete URL from the product configuration guides for your region.
Upon successful websocket connection the application begins by logging in and sending the Access token received from previous REST API call. A Login request message looks like:
{
"ID": 1,
"Domain": "Login",
"Key": {
"NameType": "AuthnToken",
"Elements": {
"ApplicationId": "256",
"Position": "****",
"AuthenticationToken": "eyJ0eXAiO****frkdw"
}
}
}
Login response shows if the login was successful and contains an element TRCE:MaxMessagesPerSecond, which is this users contribution rate limit:
[{
"ID": 1,
"Type": "Refresh",
"Domain": "Login",
"Key": {
"Name": "RCC_MACHINE_ID",
"Elements": {
"TRCE:MaxMessagesPerSecond": 1000
}
},
"State": {
"Stream": "Open",
"Data": "Ok",
"Text": "Login accepted by host 75ebb8d3d250 via ip-10-28-167-224"
},
"ClearCache": false,
"DoNotCache": true,
"Private": true,
"Solicited": false
}
]
Contribute the data
Now that the websocket has been established and the application has logged in successfully, it can begin contributing. Contributions are sent in as a Post messages. Sample Post message:
{
"Ack": true,
"ID": 1,
"Key": {
"Name": "RIC_ON_WHICH_ALLOWED_TO_CONTRIBUTE",
"Service": "DDS_TRCE"
},
"Message": {
"Fields": {
"ASK": 45.57,
"BID": 45.55
},
"ID": 0,
"Type": "Update"
},
"PostID": 1,
"Type": "Post"
}
The element Name and the Fields should match the RIC provided by Refinitiv, on which this user is allowed to contribute. Each post message should also contain a unique post ID. It is best practice to increment the ID between each posting. The Ack element tells the server that we need a confirmation message.
Upon successful acceptance of the contribution, server responds with accepted response:
[{
"ID": 1,
"Type": "Ack",
"AckID": 1
}
]
If the contribution was rejected (negative acknowledgment), it contains the NakCode element in the response message. The ID element matches the particular contribution which was rejected. In this sample user tried contributing to non-permissioned symbol.
[{
"ID": 1,
"Type": "Ack",
"AckID": 1,
"NakCode": "SymbolUnknown",
"Text": "Symbol unknown"
}
]
Now the application can continue to post, while throttling itself to stay below the MaxMessagesPerSecond number of messages.
Logout and shutdown
Once the application is finished, it should send a close message before disconnecting the websocket. Sample of stream Close request:
{
"ID": 1,
"Type": "Close",
"Domain": "Login"
}
Close response:
[{
"ID": 1,
"Type": "Status",
"Domain": "Login",
"State": {
"Stream": "Closed",
"Data": "Suspect",
"Code": "NotEntitled",
"Text": "Logout accepted by host 75ebb8d3d250 via ip-10-28-167-224"
},
"Private": true
}
]
To get salient details of the messages used, please see the contributions tutorial which also includes a working python sample.