Article

Web Page Development Using Widgets for RKD

Gurpreet Bal
Platform Application Developer Platform Application Developer

Web Page Development Using Widgets for RKD

This article demonstrates HTML widgets developed in Javascript and the RKD REST API, which retrieves and renders market data from Refinitiv Knowledge Direct (RKD).

Refinitiv Knowledge Direct offers access to Refinitiv hosted content and capabilities and is a source of realtime and fundamental data on wide variety of asset classes. It integrates into custom solutions, customer facing investment portals, online trading platforms and provides data through a powerful and uniform suite of web based API's.

Introduction

This article demonstrates the use of RKD API to develop a set of widgets for Quote, Chart and Company Financial Reports. The RKD API offers content as both traditional (SOAP/XML) and a RESTful WebService. This example uses Javascript and REST interface to fetch and render JSON data. The code sample runs as a server side NodeJS application. All the widgets except the one to get Authentication Token, can be implemented and run as client side - browser based widgets.

The widgets provide an interface to get raw JSON data or a HTML snippet, which can be readily plugged into the page. The styling information is not embedded in the widget itself, so the user is free to render it in their own flavor. A sample webpage with sample style is also provided. When requesting the raw data, the widget does not create a HTML widget, but sends the JSON object instead, where a user script within the browser is free to slice and use it in any manner.
 


Here is a sample webpage displaying the Quote, Chart and Financial Report widget:
 

 

Development Environment

Following dependencies are needed for running the accompanying sample:

  • Node JS - version 6.10 or higher.

To install the sample code, unzip the code repository into a directory of your choice and invoke command npm install. This command will install all the dependencies required to run the sample in a subdirectory called node_modules/.

If the machine is behind a proxy server, then NodeJS has to be instructed to use proxy instead of a direct HTTP connection. Set the following script at the command prompt which is used to run node application:

set https_proxy=http://<proxy.server>:<port>

To run the sample, first configure the RKD user-id and password in the config.json file. To request a user ID, please contact Refinitiv Account manager or visit Refinitiv Knowledge Direct.

Sample config file:

    	
            
{
    "username":     "Joe.Doe@example.com",
    "applicationID":"myFirstApp",
    "password":     "theRKDPassword",
    "httpPort":        3000
}

Start the application by typing node app.js in the command prompt.

Upon startup:

  1. The Application will request an authentication token - which is used in subsequent API calls
  2. Start a web server on configured port - if a valid token is received
  3. If unable to get a valid authentication token, the app will display the status message and terminate

Sample output:
 


Next, use the web browser to navigate to the URL of this node web server. If using the local machine with default settings, the URL will be http://localhost:3000

The sample webpage uses jQuery library to request and display widgets using AJAX.

Code

In this NodeJS based server side application, the RKD widgets are defined in the lib/ directory. These widgets use the node-request module to talk to the RKD REST service. The request module itself is wrapped in a Javascript promise in the module pRequest.js.

A helper class - app.js serves as a glue code, which initializes the widgets, starts up a web server and provides an interface to invoke widgets from a web request.

Semantics of a REST request

At the underlying level, TRKD web service follows and fulfills requests using REST protocol. A typical call for data, starts with an HTTP POST to TRKD service endpoint. Additional HTTP header may be required based on the API call. The parameters for request are carried in HTTP content as a JSON message. It is important to indicate this by using appropriate Content-Type HTTP header. Its important to include two additional headers X-Trkd-Auth-ApplicationID - which contains your RKD application ID, and X-Trkd-Auth-Token containing the authorization token. The calls will return HTTP status code 5xx, if there is problem retrieving data, due to invalid token or invalid RIC etc.

Sample Quote Request (only relevant headers shown):

    	
            
POST https://api.rkd.refinitiv.com/api/Quotes/Quotes.svc/REST/Quotes_1/RetrieveItem_3 HTTP/1.1
X-Trkd-Auth-ApplicationID: myAwsomeApp
X-Trkd-Auth-Token: EA3C4E99EF5...E18C9FD6A1
Content-Type: application/json;charset=utf-8
Content-Length: 167

{
    "RetrieveItem_Request_3" : {
        "TrimResponse" : false,
        "ItemRequest" : [{
                "RequestKey" : [{
                        "Name" : "IBM.N",
                        "NameType" : "RIC"
                    }
                ],
                "Scope" : "All",
                "ProvideChainLinks" : true
            }
        ]
    }
}

RKD Quote Service response (only relevant headers shown):

    	
            
HTTP/1.1 200 OK
Content-Type: application/json;charset=utf-8
Date: Thu, 19 Oct 2017 19:28:30 GMT

{
    "RetrieveItem_Response_3" : {
        "ItemResponse" : [{
                "Item" : [{
                        "RequestKey" : {
                            "Name" : "IBM.N",
                            "Service" : "IDN",
                            "NameType" : "RIC"
                        },
                        "QoS" : {
                            "TimelinessInfo" : {
                                "Timeliness" : "REALTIME",
                                "TimeInfo" : 0
                            },
                            "RateInfo" : {
                                "Rate" : "TICK_BY_TICK",
                                "TimeInfo" : 3000
                            }
                        },
                        "Status" : {
                            "StatusMsg" : "OK",
                            "StatusCode" : 0
                        },
                        "Fields" : {
                            "Field" : [{
                                    "DataType" : "Utf8String",
                                    "Name" : "DSPLY_NAME",
                                    "Utf8String" : "INTL BUS MACHINE"
                                }, {
                                    "DataType" : "Double",
                                    "Name" : "TRDPRC_1",
                                    "Double" : 160.63
                                }, {
                                .
                                .
                                .
                                }, {
                                    "DataType" : "Utf8String",
                                    "Name" : "CF_CURRENCY",
                                    "Utf8String" : "USD"
                                }

Here we see that both request parameters and the returned data is a JSON object - which has been pretty formatted for display purposes.

trkd-authenticate Widget

This widget exports a single function, which takes in userid, password and application ID, and returns a promise which resolves to an authentication token. The token is received when the token endpoint, namely CreateServiceToken_1 is invoked and following JSON message is sent in the HTTP POST payload:

    	
            
"CreateServiceToken_Request_1": {
    "ApplicationID": appid,
    "Username": userName,
    "Password": password
}

The HTTP response from this endpoint is an object containing the token, which is then extracted and returned as a promise.

    	
            
return pRequest.sendRequest(_REQUEST_HEADERS_AND_BODY_)
    .then(resp => resp.CreateServiceToken_Response_1.Token);

The token should be stored as a global parameter in the application, since it is used by all subsequent TRKD API calls. Widgets expect the token to be available in global.token parameter.

trkd-quote Widget

This widget exports two functions from module.

  • getQuoteJSON() - allows the caller to get the raw JSON data that is received from TRKD server. Sample JSON response:
     
    	
            
{"RequestKey": {"Name": "TRI.N","Service": "IDN","NameType": "RIC"},
"QoS": {"TimelinessInfo": {"Timeliness": "REALTIME","TimeInfo": 0},
"RateInfo": {"Rate": "TICK_BY_TICK","TimeInfo": 3000}},
"Status": {"StatusMsg": "OK","StatusCode": 0},
"Fields": {
"Field": [{"DataType": "Double","Name": "CF_ASK","Double": 44.35
}, {"DataType": "Double","Name": "CF_BID","Double": 44.34
}, {"DataType": "Double","Name": "CF_CLOSE","Double": 44.03
}, {"DataType": "Utf8String","Name": "CF_DATE","Utf8String": "07 DEC 2017"
}, {"DataType": "Utf8String","Name": "CF_EXCHNG","Utf8String": "NYS"
}, {"DataType": "Double","Name": "CF_HIGH","Double": 44.4
}, {"DataType": "Double","Name": "CF_LAST","Double": 44.33
}, {"DataType": "Double","Name": "CF_LOTSIZE","Double": 100
}, {"DataType": "Double","Name": "CF_LOW","Double": 43.95
}, {"DataType": "Double","Name": "CF_NETCHNG","Double": 0.3
}, {"DataType": "Double","Name": "CF_OPEN","Double": 43.96
}, {"DataType": "Utf8String","Name": "CF_SOURCE","Utf8String": "NYS"
}, {"DataType": "Utf8String","Name": "CF_TICK","Utf8String": "⇩"
}, {"DataType": "Utf8String","Name": "CF_TIME","Utf8String": "16:35:00"
}, {"DataType": "Int64","Name": "CF_VOLUME","Int64": 99809
}, {"DataType": "Double","Name": "CF_YIELD","Double": 3.1342
}, {"DataType": "Utf8String","Name": "CF_NAME","Utf8String": "THOMSON REUTERS"
}, {"DataType": "Utf8String","Name": "CF_CURRENCY","Utf8String": "USD"}]}}

getQuoteDiv() - formats the JSON Quote data into a HTML-div element, which can be readily placed in a HTML page. No styling information is applied to the div element, except specifying a class name for namespace separation. When the div containing quote information is added to a web page, style information from that page will apply. This allows a user to control the look and feel of Quotes, without modifying the underlying code. This widget expects the authentication token and application ID parameter will be available in global.token and global.applicationID variables.
 

    	
            
<div class="quote1">
  <div class="hdr"><span class="lb">TRI.N</span><span class="vl">THOMSON REUTERS (USD)</span></div>
  <div class="pt"><span class="lb">ASK</span><span class="vl">44.33</span></div>
  <div class="pt"><span class="lb">BID</span><span class="vl">44.32</span></div>
  <div class="pt"><span class="lb">CLOSE</span><span class="vl">44.03</span></div>
  <div class="pt"><span class="lb">DATE</span><span class="vl">07 DEC 2017</span></div>
  <div class="pt"><span class="lb">EXCHNG</span><span class="vl">NYS</span></div>
  <div class="pt"><span class="lb">HIGH</span><span class="vl">44.4</span></div>
  <div class="pt"><span class="lb">LAST</span><span class="vl">44.33</span></div>
  <div class="pt"><span class="lb">LOTSIZE</span><span class="vl">100</span></div>
  <div class="pt"><span class="lb">LOW</span><span class="vl">43.95</span></div>
  <div class="pt"><span class="lb">NETCHNG</span><span class="vl">0.3</span></div>
  <div class="pt"><span class="lb">OPEN</span><span class="vl">43.96</span></div>
  <div class="pt"><span class="lb">SOURCE</span><span class="vl">NYS</span></div>
  <div class="pt"><span class="lb">TICK</span><span class="vl">⇩</span></div>
  <div class="pt"><span class="lb">TIME</span><span class="vl">16:33:00</span></div>
  <div class="pt"><span class="lb">VOLUME</span><span class="vl">98893</span></div>
  <div class="pt"><span class="lb">YIELD</span><span class="vl">3.1342</span></div>
  <div class="pt"><span class="lb">NAME</span><span class="vl">THOMSON REUTERS</span></div>
  <div class="pt"><span class="lb">CURRENCY</span><span class="vl">USD</span></div>
</div>

As described earlier, additional HTTP headers are specified in the request message by this widget as shown:

    	
            
"X-Trkd-Auth-ApplicationID": global.applicationID,
"X-Trkd-Auth-Token": global.token

To use this widget, set the appropriate token and application ID in the global variables, and invoke getQuoteDiv(). The return object from this function, is a promise which contains the HTML-div element.

app.js and index.html

app.js is the entry point/glue class which demonstrates how to import and use these sample widgets. The execution starts by requesting the authentication token, from values defined in config.json. If the authentication promise resolves, this token is stored as a global variable, and a node HTTP server is started on pre-configured port. This class also maps different HTTP URI's to widget functions. For every request coming from a browser, the URI is checked and an appropriate TRKD widget is invoked to get data. The data from widget is passed back to the browser.

The sample html file - index.html, demonstrates how to invoke a remote widget and display it on the web page. It also shows how to provide style information for rendering the widgets.

Source Code: RKD HTML Widget

This article walks through a bare-bone framework for implementing the widgets using RKD. A few areas which are skipped and need improvement are:

  • Handle token expiry, and re-requesting a new token
  • Implement more robust error handling
  • Generate user friendly error message in widget display
  • Explore widgets for other TRKD services

Reference

 

Downloads