How to expand Chain RICs using the Tick History REST API in Python

Overview

Tick History's REST API is a Representational State Transfer (REST)-compliant API that programmatically exposes Tick History functionality on the DataScope Select platform. Client applications can be written in most programming languages, such as C#, C++, Visual Basic, Java, Python, Objective-C, and Swift.

One of the favorite use cases for applications that use the legacy SOAP-based TRTH API is to use the API to expand a Chain RIC and get RIC list. After getting the list, they can pass the list to retrieve some specific data using other TRTH functions and they can also export the list to other applications. In this article, we will demonstrate how to use the new REST API to expand a Chain RIC and get RIC list like the legacy API.

This example demonstrates how to interact with the TRTH REST API without using.Net SDK. And we use Python programming language to demonstrate the API usages as it works as a script and it can work across OS. This example applies knowledge from TRTH document and tutorial from developer community website especially steps from Chapter 4: Expanding a Chain RIC over a Date Range from USE CASES REFERENCE document.

Introduction

The Legacy SOAP API has the ExpandChain method which will return a list of the RICs for all instruments that were part of the given chain at any time during the given time period. This Function expands the chain for the given RIC independently on each day in the requested range of dates and then collates the results as a single list of RICs. For the new REST API, clients can expand a chain RIC and get underlying RICs using HTTP endpoint /Search/HistoricalChainResolution. The API calls resolve current and past chain constituents given a Chain RIC. Instruments may be currently active, or inactive. It can be very time consuming on both SOAP and REST API. Try not to use this function with large ranges of dates.

HTTP Request

  • Endpoint URL:
https://hosted.datascopeapi.reuters.com/RestApi/v1/Search/HistoricalChainResolution
  • Method: POST
  • Headers:
Prefer: respond-async
Content-Type: application/json; odata.metadata=minimal
Authorization: <Your Authorization Token>
  • Body:
ChainRics: Identifies one or more chain RICs, each of which will be resolved into its constituent RICs.
Start: Start date. For example, 2017-01-01T00:00:00.000Z.
End: End date. For example, 2017-01-01T00:00:00.000Z.
  • Sample Request Body
 {
       "Request":
                {
                     "ChainRics": [ "0#HO:" ],
                     "Range": {
                            "Start": "2008-01-01T00:00:00.000Z",
                            "End": "2016-01-01T00:00:00.000Z"
                          }
               }
}

HTTP Response

  • Sample Response message
HTTP/1.1 200 OK
 {
    "@odata.context": "https://hosted.datascopeapi.reuters.com/RestApi/v1/$metadata#Collection(ThomsonReuters.Dss.Api.Search.HistoricalChainInstrument)",
    "value": [
              {
                "Identifier": "0#HO:",
                "IdentifierType": "ChainRIC",
                "Source": "",
                "Key": "VjF8MHgxMDAwMDAwMDAwMDAwMDAwfDB4MTAwMDAwMDAwMDAwMDAwMHx8Q0hSfENIUnxDSFJ8SHx8MCNITzp8",
                "Description": "Historical Chain",
                "InstrumentType": "Unknown",
                "Status": "Valid",
                "Constituents": [
                               {             
                                  "Identifier": "HOF0",
                                  "IdentifierType": "Ric",
                                  "Source": "", "Key": "VjF8MHgzMDAwMDAwMDAwMDAwMDAwfDB4MzAwMDAwMDAwMDAwMDAwMHx8fHx8fHxIT0YwfA",
                                  "Description": "Historical Instrument",
                                  "InstrumentType": "Unknown",
                                  "Status": "Valid",
                                  "DomainCode": "6"
                               },

              . . .                                                                                           
                               {
                                 "Identifier": "HOZ9",
                                   "IdentifierType": "Ric",
                                   "Source": "",
                                   "Key": "VjF8MHgzMDAwMDAwMDAwMDAwMDAwfDB4MzAwMDAwMDAwMDAwMDAwMHx8fHx8fHxIT1o5fA",
                                   "Description": "Historical Instrument",
                                   "InstrumentType": "Unknown",
                                   "Status": "Valid",
                                   "DomainCode": "6"
                               }]
               ]

          }
    ]
}

From the HTTP response, it presents the chain’s constituent RICs. Hence the application has to parse JSON object and get the RIC list by accessing the value of Constituents.

Python Example

Prerequisite

  • To run the example user should have python 2.7 or 3.6 installed on OS. A user can download python installer from the link below. Basically, users can open the example with any text editor. There are free Python IDEs such as PyCharm Community edition and Visual Studio Code developers can use to open python source file.
https://www.python.org
  • In order to access the Tick History Endpoint, a user must have DSS account with permission to access Tick History’s REST API. Please contact your Thomson Reuters Account representative if you need a new account or additional permissions.
  • To use HTTP request and response, this example uses the Python 'requests' module. 
  • This example uses pandas data frames and some functions from numpy to parse and display data so you have to install pandas and numpy module.

Implementation

The example starts from importing the required Python modules so you need to import requests and JSON module to the example. It also requires pandas and numpy module to convert JSON data to the pandas data frame.

from json import dumps, loads, load
from requests import post,get
...
import pandas as pd
import numpy as np

Authentication

To get an Authentication Token, the example will require a valid username and password and then send a new Authentication request to the DSS server to get a new Token. After it gets a new Token, it will pass the token to the Http request header. Below is the code for requesting a new token from the DSS server. If a user doesn’t want to get a new token as the old one still valid for 24 hours, feel free to modify RequestNewToken function to return valid token instead.

def RequestNewToken(username="",password=""):
    _AuthenURL = "https://hosted.datascopeapi.reuters.com/RestApi/v1/Authentication/RequestToken"
    _header= {}
    _header['Prefer']='respond-async'
    _header['Content-Type']='application/json; odata.metadata=minimal'
    _data={'Credentials':{
        'Password':password,
        'Username':username
        }
    }

    print("Send Login request")
    resp=post(_AuthenURL,json=_data,headers=_header)

    if resp.status_code!=200:
        message="Authentication Error Status Code: "+ str(resp.status_code) +" Message:"+resp.text
        raise Exception(dumps(message,indent=4))

    return loads(resp.text)['value']

Expand Chain

Before sending an Http request with a post message to HistoricalChainResolution endpoint, it required the Authorization Token from the previous steps with JSON payload containing Chain RIC, start date and end date. Please find sample JSON payload from section Sample Request Body.

In order to get underlying RICs from HTTP response message(see section Sample Response message), the application has to access the Constituents list from JSON object and then convert the list to a pandas data frame. And then it can access RIC list under the Constituents list. Below is the python code from the example. It will print a data frame containing RIC name and Status to console.

def ExpandChain(token,json_payload):
    _expandChainURL = "https://hosted.datascopeapi.reuters.com/RestApi/v1/Search/HistoricalChainResolution"
    _header = {}
    _header['Prefer'] = 'respond-async'
    _header['Content-Type'] = 'application/json; odata.metadata=minimal'
    _header['Accept-Charset'] = 'UTF-8'
    _header['Authorization'] = 'Token' + token
    resp = post(_expandChainURL, data=None, json=json_payload, headers=_header)
    item_list = []
    if(resp.status_code==200):
        json_object=loads(resp.text,object_pairs_hook=OrderedDict)
        if len(json_object['value']) > 0:
            dataFrame = pd.DataFrame.from_dict(json_object['value'][0]['Constituents'])
        else:
            return pd.DataFrame()
    else:
        print("Unable to expand chain response return status code:",resp.status_code)

    return dataFrame
#In the Main function
            _jsonquery={
                        "Request": {
                            "ChainRics": [
                                    _chainRIC
                                    ],
                            "Range": {
                                "Start": _startDate,
                                "End": _endDate
                            }
                         }
            }
            print("Start Expanding Chain "+_chainRIC+"\n")
            df=ExpandChain(_token,_jsonquery)
            if df.empty:
                print("Unable to expand chain "+_chainRIC) 
                return

            ricCount=len(df['Identifier'])
            print("Found "+str(ricCount)+" RIC")
            #Filter and print only RIC name and Status columns
            pd.set_option('display.max_rows', ricCount)
            newDF = df.filter(items=['Identifier','Status'])
            newDF.index = np.arange(1,len(newDF)+1)
            print(newDF)

Running example

To test the example, please run the following python command

>python ExpandChainREST.py

The example will ask a user to input DSS username and password then it will request a new Token and pass it to HTTP request as described. Feel free to change the following variables if you want to set chain RIC, start date, end date.

_chainRIC="0#.FTSE"

_startDate="2017-03-14T00:00:00.000Z"

_endDate="2017-03-15T00:00:00.000Z"

After running the example, it will display the following console output

Login to DSS Server
Send Login request
Authorization Token:_tHSMJfR5k2n4a56GCmGhhyCCYjt1AA6F5FC3DswB9ad55M5TQhpkOuK6jw5NWy3ir9Vzq5phjQ71rHkZhYrB7tA0c6eBEAVDlOK26H98YWYe9QqVSYp-5IeaMsI9QYIvB-ZxQr5xEv1Mc6u1KF9Afzbq3LtSC11qALNdIIS4JbGjNLqKJ8HgTD6VYuUa6Vc-OlXvEkIlClkUH7_tLCKNwqNZZYK7LPFxnhXWq9NhsoxAoxMOj2kRM1NnhUoCIIgOYfkyw69GEMTauLoHLyOHprN_4KsDlBQN59BQ8OAQu5c

Start Expanding Chain 0#.FTSE

Found 103 RIC
    Identifier Status
1     .AD.FTSE  Valid
2        .FTSE  Valid
3        AAL.L  Valid
4        ABF.L  Valid
5       ADML.L  Valid
6        AHT.L  Valid
7       ANTO.L  Valid
8         AV.L  Valid
9        AZN.L  Valid
10       BAB.L  Valid
11      BAES.L  Valid
12      BARC.L  Valid
13      BATS.L  Valid
14      BDEV.L  Valid
15      BLND.L  Valid
16       BLT.L  Valid
17      BNZL.L  Valid
18        BP.L  Valid
19      BRBY.L  Valid
20        BT.L  Valid
21       CCH.L  Valid
22       CCL.L  Valid
23       CNA.L  Valid
24       CPG.L  Valid
25      CRDA.L  Valid
26       CRH.L  Valid
27      CTEC.L  Valid
28       DCC.L  Valid
29       DGE.L  Valid
30      DLGD.L  Valid
31      EXPN.L  Valid
32       EZJ.L  Valid
33      FRES.L  Valid
34       GKN.L  Valid
35      GLEN.L  Valid
36       GSK.L  Valid
37       HIK.L  Valid
38      HMSO.L  Valid
39      HRGV.L  Valid
40      HSBA.L  Valid
41      ICAG.L  Valid
42       IHG.L  Valid
43       III.L  Valid
44       IMB.L  Valid
45       INF.L  Valid
46     INTUP.L  Valid
47      ITRK.L  Valid
48       ITV.L  Valid
49      JMAT.L  Valid
50       KGF.L  Valid
51      LAND.L  Valid
52      LGEN.L  Valid
53      LLOY.L  Valid
54       LSE.L  Valid
55      MCRO.L  Valid
56      MDCM.L  Valid
57      MERL.L  Valid
58       MKS.L  Valid
59      MNDI.L  Valid
60       MRW.L  Valid
61        NG.L  Valid
62       NXT.L  Valid
63       OML.L  Valid
64       PFG.L  Valid
65       PPB.L  Valid
66       PRU.L  Valid
67       PSN.L  Valid
68      PSON.L  Valid
69        RB.L  Valid
70       RBS.L  Valid
71      RDSa.L  Valid
72      RDSb.L  Valid
73       REL.L  Valid
74       RIO.L  Valid
75       RMG.L  Valid
76        RR.L  Valid
77       RRS.L  Valid
78       RSA.L  Valid
79       RTO.L  Valid
80      SBRY.L  Valid
81       SDR.L  Valid
82       SGE.L  Valid
83       SHP.L  Valid
84       SJP.L  Valid
85       SKG.L  Valid
86      SKYB.L  Valid
87        SL.L  Valid
88      SMIN.L  Valid
89       SMT.L  Valid
90        SN.L  Valid
91       SSE.L  Valid
92      STAN.L  Valid
93       SVT.L  Valid
94      TSCO.L  Valid
95      TUIT.L  Valid
96        TW.L  Valid
97      ULVR.L  Valid
98        UU.L  Valid
99       VOD.L  Valid
100      WOS.L  Valid
101      WPG.L  Valid
102      WPP.L  Valid
103      WTB.L  Valid

Note

The time to expand chain is proportional to the number of days in the date range. Do not specify longer date ranges than necessary.

Source Code

The sources code can be downloaded from ExpandChain