Hi there, I am trying to pull the bondholders for several RICs, before finding the ultimate parents of each of these bondholders as well as their identifiers. At the moment, I am doing this RIC by RIC/name by name in a loop. This is resulting in too many API calls to the Refinitiv server, but at least for bondholding data you can only request one RIC at a time. Second, the API is timing out when I then search for ultimate parents for each unique bondholder, and also struggling to handle errors (see below - the universe does exist for this bond so I'm assuming it is a timeout):
## Example errors
RDError: Error code -1 | Backend error. 400 Bad Request Requested universes: ['US252610979=']. Requested fields: ['TR.H.HOLDINGCOMPANYNAME.HOLDINGCOMPANYNAME', 'TR.H.PARHELD', 'TR.H.REPORTDATE']
## another example
RDError Traceback (most recent call last)
Cell In[65], line 3
1 bond_holders = pd.DataFrame()
2 for ric in bond_rics: # bond_rics defined above
----> 3 df_hold = rd.get_data(ric,['TR.H.HoldingCompanyName.HoldingCompanyName','TR.H.PARHELD','TR.H.REPORTDATE'])
4 if len(data):
5 bond_holders = pd.concat([bond_holders,df_hold],axis=0,ignore_index=True)
File ~/anaconda3/envs/eikon/lib/python3.11/site-packages/refinitiv/data/_access_layer/get_data_func.py:126, in get_data(universe, fields, parameters, use_field_names_in_headers)
124 if exceptions and all(exceptions):
125 except_msg = "\n\n".join(exceptions)
--> 126 raise RDError(-1, except_msg)
128 hp_and_cust_inst_data = HPAndCustInstDataContainer(stream_columns, stream_data, stream_df)
129 adc_data = ADCDataContainer(adc_raw, adc_df, fields)
RDError: Error code -1 | Backend error. 400 Bad Request Requested universes: ['46590XAR7=']. Requested fields: ['TR.H.HOLDINGCOMPANYNAME.HOLDINGCOMPANYNAME', 'TR.H.PARHELD', 'TR.H.REPORTDATE']
I'm quite new to the Python API, so would appreciate help with the following requests:
- Timing/more efficiently managing API calls to pull all the bondholders for the 49 RICs (this is just for one company, so I'd also like to know how to manage these API calls for say 50 companies, cc 2000 RICs?).
- Batch requesting for the second stage, using rdp search for the organisation and its parents, which I think can be done for more general search.
- Error handling when a search returns no result, so that a record of the query is maintained.
Less of an API question, but does anyone have any experience with why records of investors in Bond Search do not always match any organisations within the main part of Refinitiv. And why it is not possible to directly retrieve an investors' PermID or other identifier, only their name?
Thanks in advance and let me know if more information is needed in the code below!
import eikon as ek
import refinitiv.data as rd
from refinitiv.dataplatform import RDPError
import pandas as
from refinitiv.data.content import search
## Pull all active bonds for one issuer
org = 4295860302 # issuer OAPermID
fi_fields = ['BondRatingLatest', 'IssuerOAPermid','IssuerOrgid','IssuerID','IssuerCommonName','ParentIssuerName', 'ParentOAPermID','IssueRating','IssueRatingSourceCode','BondRatingLatestSourceCode','AssetTypeDescription','DebtTypeDescription','ISIN','MainSuperRIC','DBSTicker','IsGreenBond','IssueDate', 'Currency', 'RCSCurrencyLeaf','FaceIssuedTotal', 'EOMAmountOutstanding', 'NextCallDate','CouponRate','IsPerpetualSecurity','MaturityDate','CdsSeniorityEquivalentDescription','Price', 'RIC']
query = "ParentOAPermID eq '" + str(org) + "' and IsActive eq true"
bonds_outstanding = rd.discovery.search(view = rd.discovery.Views.GOV_CORP_INSTRUMENTS,
filter = query,
top = 10000,
select = ','.join(fi_fields))
bonds_outstanding # 49 instruments total
## Pull bondholders for all bonds
bond_holders = pd.DataFrame()
for ric in bond_rics: # bond_rics defined above
df_hold = rd.get_data(ric,['TR.H.HoldingCompanyName.HoldingCompanyName','TR.H.PARHELD','TR.H.REPORTDATE'])
if len(data):
bond_holders = pd.concat([bond_holders,df_hold],axis=0,ignore_index=True)
else:
bond_holders = df_hold
bond_holders # get a 400 error (timeout?)
## Pull permIDs, ultimate parents, and their permIDs for bondholders
df = pd.DataFrame()
for managing_firm in bond_holders['Managing Firm'].unique():
match = rd.discovery.search(
view=rd.discovery.Views.ORGANISATIONS,
query=managing_firm,
top=1, # choose best match
select="LongName, OAPermID, UltimateParentOrganisationName, UltimateParentCompanyOAPermID"
)
if len(df):
df = pd.concat([df,match],axis=0,ignore_index=True)
else:
df = match
## Join tables to have full list of bondholders and their holdings mapped to ultimate parents??