Authors
In this article, we'll create an application that will display statistics of an instrument (e.g.: the foreign exchange (fx) pair) immediately (precise up to a second) after a press release of interest (e.g.: United States' Consumer Price Index (CPI) or US Non Farm Payroll) that can run in CodeBook. This way, you can have such a view on one side of your Workspace, and any other app of choice on the other. We'll display a live, interactive graph of the tick data, and a static table of the historical report data. We will use LSEG Refinitiv's Datastream DSWS API (Application Programming Interface) to collect historical report data; this API has such data going back donkey's years (sometimes back to the 1950s) and it has a navigator in which you can find the relevant report of choice, as outlined brilliantly in Jirapongse's article here. For the tick data, we will use LSEG's Refinitiv Data API; it - however - does not natively allow access to tick data going that far back (only for the past 3 to 5 months). I will endeavour to update this article in the future with use of the LSEG Refinitiv TRTH (Refinitiv Tick History) REST (REpresentational State Transfer) API that may allow us access to tick data further back in time.
Some Imports to start with
Python works with libraries that one can import to use functionalities that are not natively supported but the coding language.
This code runs on Python version 3.8.2 in 32bit
Polls / Estimates Data
We need to gather our economic estimates data to calculate the surprise seen in the metric of interest (e.g.: US Inflation) straight after the release of a report (e.g.: US Inflation Report). Since Refinitiv's DataStream Web Services (DSWS) allows for access to the most accurate and wholesome economic database (DB), naturally it is more than appropriate. We can access DSWS via the Python library "DatastreamDSWS" that can be installed simply by using pip installpip install.
Make sure to entre correct DataStream credentials
We need to find out exactly when (date and time) the last report was released. In our example, we looked at CPI in the US. This is reported retroactively (i.e.: when a press release with CPI figures are published, they inform readers of what the CPI was in past dates). What we were interested in up to now were the datapoints themselves; but now we'll look at FX changes at time of press release. For the sake of this example, let's say it was last released on 11-May-2022 at 13:34. That's what the TREL1 is there for.
DSWS returns dataframes with MultiIndex columns.
MultiIndex([('USCONPRCE', 'X'),
('USCONPRCE', 'TREL1'),
('USCONPRCE', 'DREL1')],
names=['Instrument', 'Field'])
While this is extremely useful for data analytics, it'll better for us to flatten it to a single dimention
Now let's tidy our data up in teh reportActual data-frame:
| USCONPRCE_X | USCONPRCE_TREL1 | USCONPRCE_DREL1 | |
| Dates | |||
| 15/06/2020 | 257.217 | 12:31:00 | 14/07/2020 |
| 15/07/2020 | 258.543 | 12:39:38 | 12/08/2020 |
| 15/08/2020 | 259.58 | 12:32:00 | 11/09/2020 |
| ... | |||
| 15/03/2022 | 287.708 | 12:36:30 | 12/04/2022 |
| 15/04/2022 | 288.663 | 12:36:30 | 11/05/2022 |
| 15/05/2022 | 291.474 | 12:36:30 | 10/06/2022 |
| 15/06/2022 | NaN | None | None |
Let's create a function that does that for us
| Instrument | Datatype | Value | Dates | |
| 0 | USCONPRCE | NAME | US CPI - ALL URBAN: ALL ITEMS SADJ | 24/06/2022 |
| 1 | US&CPNM.F | NAME | US CPI INDEX, NSA-MEDIAN NADJ | 24/06/2022 |
| 2 | US&CPNS.F | NAME | US CPI INDEX, NSA-SURPRISE NADJ | 24/06/2022 |
| USCONPRCE_X | USCONPRCE_TREL1 | USCONPRCE_DREL1 | |
| Dates | |||
| 15/06/2020 | 257.217 | 12:31:00 | 14/07/2020 |
| 15/07/2020 | 258.543 | 12:39:38 | 12/08/2020 |
| 15/08/2020 | 259.58 | 12:32:00 | 11/09/2020 |
| ... | |||
| 15/03/2022 | 287.708 | 12:36:30 | 12/04/2022 |
| 15/04/2022 | 288.663 | 12:36:30 | 11/05/2022 |
| 15/05/2022 | 291.474 | 12:36:30 | 10/06/2022 |
| 15/06/2022 | NaN | None | None |
Let's plot our data to visualise it; we can use plotly with the pd.options.plotting.backend function:
| USCONPRCE_X | USCONPRCE_TREL1 | USCONPRCE_DREL1 | US&CPNM.F_X | US&CPNS.F_X | |
| Dates | |||||
| 15/06/2020 | 257.217 | 12:31:00 | 14/07/2020 | 257.733 | 0.064 |
| 15/07/2020 | 258.543 | 12:39:38 | 12/08/2020 | 258.51 | 0.591 |
| 15/08/2020 | 259.58 | 12:32:00 | 11/09/2020 | 259.518 | 0.4 |
| ... | |||||
| 15/03/2022 | 287.708 | 12:36:30 | 12/04/2022 | 287.41 | 0.094 |
| 15/04/2022 | 288.663 | 12:36:30 | 11/05/2022 | 288.654 | 0.455 |
| 15/05/2022 | 291.474 | 12:36:30 | 10/06/2022 | 291.661 | 0.635 |
Tick Data
In the cell bellow, we import the Python library os, then we use it to point to the path where our Refinitiv Credentials are; we need this file in order to authenticate ourselves to the Refinitiv data services and collect data. You can find out more on this here, and a copy of the Configuration file here.
The last report was on 2022-06-10T12:36:30 and we'll get FX data till 2022-06-10T12:51:30
| GBP= | BID | ASK | MID_PRICE | RatioChangeSince2022-06-10T12:36:30 | %ChangeSince2022-06-10T12:36:30 | Average%ChangeSince2022-06-10T12:36:30 | StandardDeviationOf%ChangeSince2022-06-10T12:36:30 | UpperBoundOfStandardDeviationOf%ChangeSince2022-06-10T12:36:30 | LowerBoundOfStandardDeviationOf%ChangeSince2022-06-10T12:36:30 |
| Timestamp | |||||||||
| 2022-06-10 12:36:30.258000+00:00 | 1.2418 | 1.2422 | 1.242 | 0 | 0 | NaN | NaN | NaN | NaN |
| 2022-06-10 12:36:30.260000+00:00 | 1.2419 | 1.242 | 1.24195 | -0.00004 | -0.004026 | 0 | NaN | NaN | NaN |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2022-06-10 12:51:29.168000+00:00 | 1.2399 | 1.24 | 1.23995 | -0.001651 | -0.165056 | -0.016765 | 0.070156 | 0.053391 | -0.086921 |
| 2022-06-10 12:51:29.960000+00:00 | 1.2398 | 1.2402 | 1.24 | -0.00161 | -0.161031 | -0.016834 | 0.070212 | 0.053378 | -0.087046 |
2149 rows × 9 columns
| GBP= | %ChangeSince2022-06-10T12:36:30 | Average%ChangeSince2022-06-10T12:36:30 | UpperBoundOfStandardDeviationOf%ChangeSince2022-06-10T12:36:30 | LowerBoundOfStandardDeviationOf%ChangeSince2022-06-10T12:36:30 |
| Timestamp | ||||
| 2022-06-10 12:36:30.258000+00:00 | 0 | NaN | NaN | NaN |
| 2022-06-10 12:36:30.260000+00:00 | -0.004026 | 0 | NaN | NaN |
| 2022-06-10 12:36:30.635000+00:00 | -0.012077 | -0.002013 | 0.000834 | -0.00486 |
| 2022-06-10 12:36:30.740000+00:00 | 0 | -0.005368 | 0.000782 | -0.011517 |
| 2022-06-10 12:36:31.099000+00:00 | 0 | -0.004026 | 0.001668 | -0.009719 |
| ... | ... | ... | ... | ... |
| 2022-06-10 12:51:29.168000+00:00 | -0.165056 | -0.016765 | 0.053391 | -0.086921 |
| 2022-06-10 12:51:29.960000+00:00 | -0.161031 | -0.016834 | 0.053378 | -0.087046 |
2149 rows × 4 columns
|
Reported Value | Poll | Surprise |
| 2020-07-14T12:31:00 | 257.217 | 257.733 | 0.064 |
| 2020-08-12T12:39:38 | 258.543 | 258.51 | 0.591 |
| 2020-09-11T12:32:00 | 259.58 | 259.518 | 0.4 |
| ... | |||
| 2022-04-12T12:36:30 | 287.708 | 287.41 | 0.094 |
| 2022-05-11T12:36:30 | 288.663 | 288.654 | 0.455 |
| 2022-06-10T12:36:30 | 291.474 | 291.661 | 0.635 |
For historical FX data, we will have to use the ek library and authenticate ourselves to it. This library will only work with Workspace/Eikon running in the background or in CodeBook.
We'll get data from 2022-04-12T12:36:30 till 2022-04-12T12:51:30
We'll get data from 2022-05-11T12:36:30 till 2022-05-11T12:51:30
We'll get data from 2022-06-10T12:36:30 till 2022-06-10T12:51:30
| TimeStamp | Reported Value | Poll | Surprise | PrctChg | |
| 2020-07-14T12:31:00 | 2020-07-14T12:31:00 | 257.217 | 257.733 | 0.064 | NaN |
| 2020-08-12T12:39:38 | 2020-08-12T12:39:38 | 258.543 | 258.51 | 0.591 | NaN |
| 2020-09-11T12:32:00 | 2020-09-11T12:32:00 | 259.58 | 259.518 | 0.4 | NaN |
| ... | |||||
| 2022-04-12T12:36:30 | 2022-04-12T12:36:30 | 287.708 | 287.41 | 0.094 | 0.084472 |
| 2022-05-11T12:36:30 | 2022-05-11T12:36:30 | 288.663 | 288.654 | 0.455 | -0.150327 |
| 2022-06-10T12:36:30 | 2022-06-10T12:36:30 | 291.474 | 291.661 | 0.635 | -0.161031 |
Interface
Now we will try and display our plot above the table of relevant data:
'5.8.2'
Widget
(Credit to ac24)
We can now look into incorporating our above graph in a widget that allows us to toggle between graph and data (in a table). This is a rudimentary example taken from CodeBook examples (in '__ Examples __/04. Advanced UseCases/04.01. Python Apps/EX_04_01_02__WFCH_Company_Income_Statement_Waterfall.ipynb'), but more complex ones can easily be constructed to fit your workflow.
| GBP= | %ChangeSince2022-04-12T12:36:30 | Average%ChangeSince2022-04-12T12:36:30 | UpperBoundOfStandardDeviationOf%ChangeSince2022-04-12T12:36:30 | LowerBoundOfStandardDeviationOf%ChangeSince2022-04-12T12:36:30 |
|---|---|---|---|---|
| Timestamp | ||||
| 2022-04-12 12:36:31.761000+00:00 | 0.000000 | NaN | NaN | NaN |
| 2022-04-12 12:36:32.194000+00:00 | -0.003840 | 0.000000 | NaN | NaN |
| 2022-04-12 12:36:32.778000+00:00 | -0.007679 | -0.001920 | 7.952188e-04 | -0.004635 |
| 2022-04-12 12:36:33.774000+00:00 | -0.007679 | -0.003840 | -2.841911e-15 | -0.007679 |
| 2022-04-12 12:36:34.805000+00:00 | -0.007679 | -0.004800 | -1.123379e-03 | -0.008476 |
| ... | ... | ... | ... | ... |
| 2022-04-12 12:51:28.545000+00:00 | 0.076793 | 0.074129 | 1.081448e-01 | 0.040112 |
| 2022-04-12 12:51:29.553000+00:00 | 0.084472 | 0.074131 | 1.081342e-01 | 0.040127 |
1345 rows × 4 columns
All Together Now
pandas version 1.3.5
numpy version 1.21.2
ipywidgets version 7.6.3
plotly version 5.8.2
Kudos to Kimberly Fessel
References
You can find more detail regarding the Datastream API and related technologies for this notebook from the following resources:
- Refinitiv Data API page on the LSEG Refinitiv Developer Community web site.
- Datastream DSWS Python Tutorial Series/Article 'Estimating Monthly GDP via the Expenditure Approach and the Holt Winters Model'.
For any question related to this example or Datastream's API (DSWS), please use the Developers Community Q&A Forum.