Searching for KungFu Bonds (Chinese-issued U.S. dollars bonds) with RDP Libraries - Search function

Raksina Samasiri
Developer Advocate Developer Advocate
Mary Cai
Senior Technical Implementation Spe... Senior Technical Implementation Specialist

Overview

Due to Greater Bay Area (GBA) has a lot of population (86M) and huge number of GDP ($1.6T), there’s a huge potential of this market with investment opportunities across multiple asset classes and propositions. However, the ability to identify the exact investment opportunities and the consolidated source of GBA data isn’t directly accessed in Eikon Application/Refinitiv workspace yet
In this article, we’re focusing on Kung Fu Bonds (The bond issued by a Chinese entity in USD currency) as we notice that their market has been growing (there’re about 6,000 Active Kung Fu bonds). Hence, Refinitiv Data Platform (RDP) libraries are being used to create the solution to identify, aggregate and visualize KungFu bonds.

What is KungFu bonds?

Kungfu bonds or Chinese-issued U.S. dollars bonds are dollar-denominated bond issued by Chinese financial institutions and corporations.

In 2017 this part of the bond market doubled to $214 billion as tighter domestic regulations and market conditions saw Chinese companies look offshore to raise capital. This far outpaced the other major foreign currency bonds issued in Asia. Chinese issuance of dollar bonds makes up nearly 70% of corporate dollar bonds in Asia (excluding Japan).

Major issuers include Tencent Holdings Limited, Industrial and Commercial Bank of China Limited and Sinopec Group. In 2017, China's Ministry of Finance revealed plans to sell US$2 billion worth of sovereign dollar bonds in Hong Kong, its first dollar bond offering since October 2004. The technology and communications sector in China made up a significant share of the offshore U.S. dollar bond market. Tencent priced $5 billion of notes in January 2018.

What is Refinitiv Data Platform (RDP) libraries?

The Refinitiv Data Platform (RDP) Libraries are ease-of-use APIs defining a set of uniform interfaces providing the developer access to the Refinitiv Data Platform. The APIs are designed to provide consistent access through multiple access channels, spanning multiple programming languages that target both Professional Developers and Financial Coders.  Developers can choose to access content from the desktop, through their deployed streaming services or directly to the cloud.  The interfaces encompass a set of unified Web APIs providing access to both streaming (over WebSockets) and non-streaming (HTTP REST) data available within the platform. You may check the resources below for more detail

    -  RDP libraries - An Introduction
    -  RDP libraries - Getting started with Python
    -  RDP libraries - Tutorials
    -  RDP APIs
    -  Step-by-step articles for the RDP Library.
         -  Discover our Refinitiv Data Platform Library (part 1)
         -  Discover our Refinitiv Data Platform Library (part 2)

What is Refinitiv Codebook?

The CodeBook is a cloud hosted coding environment that lives inside Eikon/Workspace that can be used to develop Python notebook, script without any installation required because it's Python ready with common Python packages preinstalled and an access to Refinitiv Data Platform Library
Hence, CodeBook is Available in Refinitiv Workspace and Eikon, it also gives you access to our APIs and platform services in a single interface so you can be even more efficient. With our data, you can build analytics, applications and other use cases that are critical for your daily workflow needs.

The list of available libraries installed in Refinitiv Codebook, including Refinitiv Data Platform (RDP) and many other useful libraries, can be found in Libraries&Extensions.md file.

Prerequisite

The code can be run on Refinitiv Codebook or Jupyter Notebook that has Refinitiv Data Platform (RDP) library installed and ready to be used. To run examples in this article, I'll be using the Codebook.
    -  In case you’re running the Jupyter Notebook in your own environment (not using Codebook),
        -  The Access Credential is required to use RDP libraries. For more detail, please check this page RDP libraries - Access Credentials.
        -  Required python libraries:
            -  refinitiv.dataplatform==1.0.0a10
            -  pandas==1.3.5
            -  plotly==5.3.1
            -  datetime
            -  dateutil==2.8.2
    -  Using Codebook, the key ‘DEFAULT_CODE_BOOK_APP_KEY’ can be used
You may contact your Refinitiv's representative to help you to access Refinitiv workspace/Eikon.

RDP Libraries Code Example

    1. Set up the environment, import RDP and other necessary libraries and open the RDP desktop session with app key

    	
            import refinitiv.dataplatform as rdp
import datetime
import pandas as pd
rdp.open_desktop_session('DEFAULT_CODE_BOOK_APP_KEY')

    2. Using RDP Search function to retrieve the data from government corporate bond with several filters regarding Kungfu bonds
The search service identifies a matching set of documents which satisfy the caller's criteria, sorts it, and selects a subset of the matches to return as the result set. Each step can be controlled via parameters. You may check the article Building Search into your Application Workflow for more detail about RDP Search. Plus, you may also check This guidelines showing how to determine the properties to use within your search using the metadata, debug output, and navigators.

Or the app Advanced Search - Government and Corporate Bonds (GOVSRCH) can be used to generate Python code using RDP libraries

The search criteria for Kungfu bonds is as below
        1 )  Parent Domicile include China (Mainland), Hong Kong
        2 ) Principal Currency include USD
        3 ) Country of Issue exclude China
        4 ) Then click the dropdown at the top right and select Export Query

Here’s the screenshot of GOVSRCH app with the filters applied

The Export query window will pop-up, click CODEBOOK tab to get the code to be used, then click Copy

Here's the code we get,
        -  The properties under select parameter were adjusted to be the properties needed for an analysis
        -  Update number in top parameter to 10000 to get all result of the bonds

    	
            rdp.search(
    view = rdp.SearchViews.GovCorpInstruments,
    top = 10000,
    filter = "((DbType eq 'GOVT' or DbType eq 'CORP' or DbType eq 'AGNC' or DbType eq 'OMUN' or DbType eq 'OTHR') and IsActive eq true and (RCSParentDomicileGenealogy in ('G:53' 'G:3H') and RCSCurrencyLeaf eq 'US Dollar' and RCSCountryGenealogy ne 'M:DQ\G:B6'))",
    select = "RIC,RCSTRBC2012Leaf,IssueDate,EOMAmountOutstanding,PricingRedemDate,IssuerLegalName,PricingClosingYield, CurrentYield, FaceIssuedTotal,EOMPriceChange,RCSBondGradeLeaf,EOMPriceReturn"
)

For more detail on how to discover Views and Properties/Meta data to be used as a filter, check this article: Building Search into your Application Workflow

  • View: rdp.SearchViews.GovCorpInstruments
  • Filter: Properties / Meta data: This section is including several different techniques to help finding the proper properties to be used in the filter
  • Select: Select the properties below
    	
            RIC, RCSTRBC2012Leaf, IssueDate, EOMAmountOutstanding, PricingRedemDate, IssuerLegalName, PricingClosingYield, CurrentYield, FaceIssuedTotal, EOMPriceChange, RCSBondGradeLeaf, EOMPriceReturn
        
        
    
  • Top: 10000 rows, define the upper limit of output

Here’s an output of the Search

    3. Visualize the Kungfu bonds (df dataframe)

3.1 ) TRBC Pie

    	
            import plotly.express as px
rt = df.groupby("RCSTRBC2012Leaf",as_index=False).agg('count')
rt = rt.sort_values('RIC', ascending = False).head(10)
fig = px.pie(rt, values='RIC', names='RCSTRBC2012Leaf', title='TRBC Pie',color_discrete_sequence=px.colors.sequential.RdBu)
fig.show()

3.2 ) Bond Grade Pie

    	
            df['RCSBondGradeLeaf'].fillna("No Grade", inplace=True)
grad = df.groupby("RCSBondGradeLeaf",as_index=False).agg('count')
fig = px.pie(grad, values='RIC', names='RCSBondGradeLeaf', title='Bond Grade Pie',color_discrete_sequence=px.colors.sequential.RdBu)
fig.show()

3.3 ) Issued amount last 12 months

    	
            from datetime import date
from dateutil.relativedelta import relativedelta
decb = date.today() + relativedelta(months=-12)
start = datetime.datetime(decb.year, decb.month, 1).strftime("%Y-%m-%d %H:%M:%S")[0:10]
end = date.today().strftime("%Y-%m-%d %H:%M:%S")[0:10]

cols = ['RIC','IssueDate','FaceIssuedTotal']
c = df[cols].copy()
c.loc[:,"IssueDate"] = pd.to_datetime(c["IssueDate"])
c = c.set_index("IssueDate").sort_index(ascending=False)
c_month = c.resample('BM').sum()
c_monthb = c_month[start:end]
c_monthb.index.name = None

import plotly.express as px
fig = px.bar(c_monthb, y='FaceIssuedTotal', title = 'Issued amount last 12 months', color_discrete_sequence=px.colors.sequential.RdBu)
fig.show()

3.4 ) Redem amount in 10 years

    	
            yearsf = date.today() + relativedelta(years=+10)
end = datetime.datetime(yearsf.year, yearsf.month, 1).strftime("%Y-%m-%d %H:%M:%S")[0:4]
start = date.today().strftime("%Y-%m-%d %H:%M:%S")[0:4]
cols = ['RIC','PricingRedemDate','FaceIssuedTotal']
d = df[cols].copy()
d.loc[:,"PricingRedemDate"] = pd.to_datetime(d["PricingRedemDate"], errors = 'coerce')
d = d.set_index("PricingRedemDate").sort_index(ascending=True)
d_month = d.resample('BY').sum()
d_monthf = d_month[start:end]
d_monthf.index.name = None

import plotly.express as px
fig = px.bar(d_monthf, y='FaceIssuedTotal',title = 'Redem amount in 10 years', color_discrete_sequence=px.colors.sequential.RdBu)
fig.show()

3.5 ) Newly issued bonds last 3 months

    	
            monb3 = date.today() + relativedelta(months=-3)
start = datetime.datetime(monb3.year, monb3.month, 1).strftime("%Y-%m-%d %H:%M:%S")[0:10]
end = date.today().strftime("%Y-%m-%d %H:%M:%S")[0:10]
print(start, end)
cols = ['RIC','IssueDate','FaceIssuedTotal','RCSTRBC2012Leaf']
f = df[cols].copy()
f.loc[:,"IssueDate"] = pd.to_datetime(f["IssueDate"])
f = f.set_index("IssueDate").sort_index(ascending=True)
f_3m = f[start:end]
rt = f_3m.groupby("RCSTRBC2012Leaf",as_index=False).agg('count')
rt = rt.sort_values('RIC', ascending = False).head(10)
fig = px.pie(rt, values='RIC', names='RCSTRBC2012Leaf', title='newly issued bonds last 3 months',color_discrete_sequence=px.colors.sequential.RdBu)
fig.show()

3.6 ) Price top 10

    	
            cols = ['RIC','IssuerLegalName','EOMPriceReturn','EOMPriceChange']
price = df[cols].copy()

price_top10 = price.sort_values('EOMPriceReturn', ascending = False).head(10)
price_top10

3.7 ) Yield

    	
            cols = ['RIC','IssuerLegalName','CurrentYield','PricingClosingYield']
y = df[cols]
y = y[y['CurrentYield']>0]

3.7.1 ) Yield top 10

    	
            yield_top10 = y.sort_values('CurrentYield', ascending = False).head(10)
yield_top10

3.7.2 ) Yield last 10

    	
            yield_last10 = y.sort_values('CurrentYield', ascending = True).head(10)
yield_last10

The full code can be found in this GitHub Repository and here's the Jupyter Notebook with the output

  • Register or Log in to applaud this article
  • Let the author know how much this article helped you
If you require assistance, please contact us here