Python Financial Modelling PDF
Python Financial Modelling PDF
Modelling Sandbox
Powered by Eikon Data API
Leonid Sopotnitskiy
Director, Eikon Platform,
Emerging & Frontier Markets
1
About
The Python Credit Sandbox library is designed to solve 2 sets of problems:
• assist users in a simpler way to access complex Refinitiv data structures
• provide off-the-shelf blocks for analytics related to financial markets.
2
BASIC •
•
•
Universal chain resolver
PermID lookup
Organization metadata & attributes resolver (fixed income focus)
FUNCTIONS •
•
Eikon bond search
Bond metadata loader
3
Universal chain resolver1/3
RIC chains are dynamic lists that are maintained by Refinitiv and would usually contain sets of related instruments like futures contracts, deposits, swaps and more with a
similar (if not the same) underlying instrument type.
One of the main problems of working with multiple asset types is the difference in data fields for different RIC types. Some instruments would have prices on fields like
PRIMACT_1, others on BID, which means that the consumer has to be aware of these differences. chain_expander is a module that was designed to assist users in
handling these differences and expanding RIC chains automatically just by feeding the chain code into the main function.
df = chain_expander.get_data(ric_chain, at_date = '', chain_type = '')
Returns values in a pandas.DataFrame.
4
Universal chain resolver2/3
Most RIC chains can be expanded with the native eikon.get_data() method, however the the chain_expander module will not only retreive the RICs, but also pull relevant
market & metadata. For example, the function will return strikes, option type and implied volatilities for option chains whereas bond chains will be expanded with ISINs,
coupon rates, maturities, adfin structures and more.
5
Universal chain resolver3/3
Another example displayed below – commodity futures.
6
PermID lookup
The permid_lookup module contains a method to call the Open Perm ID API and retrieve an organization's Perm ID based on it's name. The method can be called using the
following syntax.
df = permid_lookup.get_data(name)
Returns a pandas.DataFrame containing the name and Perm ID of the organization.
7
Organization metadata & attributes resolver1/2
organization_object_v2 is a module that has been designed to retreive metadata and generate classification attributes for a specified organization.
df = organization_object_v2.get_data(perm_id)
Returns values in a pandas.DataFrame.
The only expected input parameter is an organization's PermID as a string value.
Results:
• the fixed income ticker (which can be used for bond search);
• peer organizations' tickers (in case the user wishes to search for peer bond issues);
• aggregated credit rating bucket, which is formed from available global agencies' assessments and Starmine models.
• credit grade: investment grade / IG or high yield / HY
• sector key: this a string value that can be used to build a Refinitiv sector credit curve chain code, eg. 0#AAA + key + USDBMK=
• country of risk: at the time of creating this library, country of risk as a standard field is not available in Eikon, and this module determines this value by attempting to
construct benificiary connections between issuing entities and their parent organizations
• currency of risk: depending on the previous field, the module will pick the respective currency
• issuer type: this field represents a flag of whether the target organzation is a sovereign or corporate
• SPV status: contains a boolean flag stating whether the target organization is a special purpose vehicle
• private company flag: contains a boolean value highlighting the private / public company status.
8
Organization metadata & attributes resolver2/2
9
Eikon bond search
At the time of creating the libary, this module is available only via Refinitiv VPN. eikon_bond_search posts calls to Search API and looks for fixed income instruments that
have the specified ticker and currency.
df = eikon_bond_search.get_data(ticker, currency_iso = None)
Returns a list of bond RICs.
It is possible to input any number of tickers into the first parameter as long as they are concatenated and presented in a UTF-8 format. NOTE:
The organization_object_v2 returns the peers tickers in UTF-8 by default. And the user can specify any number of currencies in a string separated by a comma (e.g. 'USD,
EUR, CNY').
10
Bond metadata loader
This method is very similar to chain_expander, however the only differences are that this method was the designed only to work with bond data, and it works with an
arbitrary list of bonds, rather than a RIC chain.
df = bond_metadata.get_data(ric_list, at_date = '')
Returns values in a pandas.DataFrame.
11
CREDIT
• Advanced Dynamic Yield Curve Engine (ADYCE)
• Bond peer spread builder (including cross-currency)
• Private Company Analytics (PVTCO)
ANALYTICS •
•
•
Loan advisor
Yield map charting
Bond portfolio analytics
• 3D yield surface
12
Advanced Dynamic Yield Curve Engine (ADYCE)1/3
ADYCE is the next generation yield curve engine to the current version of DYCE - the main analytics plugin behind Eikon's DCM Pricer app. The new version represents a
smarter algorithm that builds yield curves in multiple currencies on the fly. And the module can generate a series of scatter plots showing the pricing yield curve, its
constituents (when applicable) and indicative pricing results.
The call to the main method has the following structure:
df_list = adyce.get_data(org_data, currency, tenors, enable_threading = False, plot_chart = False)
Returns a list of 2 pandas.DataFrame objects: one with re-offer yields, and the other - with benchmark spreads.
Curve fitting is done using the Nelson-Siegel-Svensson approximation, however in case there is no mathematical solution, the module will attempt to produce a
logarithmic regression. The NSS approximation might fail in case there is insufficient secondary market data (e.g. the identified constituents are illiquid).
13
Advanced Dynamic Yield Curve Engine (ADYCE)2/3
Just like the predecessor, ADYCE relies uses the issuer's attributes and required pricing currencies as the main prerequisites to derive yield curves. The diagram below
provides a view of curve combinations that ADYCE attempts to construct based on data availability and the priority ranks of the entity bucket and curve class.
14
Advanced Dynamic Yield Curve Engine (ADYCE)3/3
15
Bond peer spread builder1/2
The peer spread builder module allows the user to search for peer bond instruments by specifying the target single-name bond RIC and retreiving a pandas.Dataframe with a
timeseries of nominal basis-point spreads between the specified bond and its peers. Since spread analysis often requires calculating benchmark spreads over treasuries, the
offered methods have the option to match the nearest benchmark.
df = peer_spreads.get_peer_spreads(ric, chart, incl_sov, days = 30)
Returns values in a pandas.DataFrame and builds an a series of plots containing spread timeseries.
16
Bond peer spread builder2/2
17
Cross-currency bond peer spread builder1/2
Another function within the peer_spreads module is the cross-currency spread builder. It provides the same output format to the get_peer_spreads() method, however the
key difference is that the currency filter is lifted in the bond search request, which means that as long as the bonds are issued by the same / peer entity and share the same
tenor bucket as well as seniority rank, coupon type as well as other criteria, they will be short-listed for spread analysis.
The module builds zero-coupon and forward FX surfaces that are then used for xCCY IR swaps to convert any bond yields to the denomination currency of the target bond.
df = peer_spreads.get_peer_xfx_spreads(ric, chart, incl_sov, days = 30)
Returns values in a pandas.DataFrame and builds an a series of plots containing spread timeseries.
On the output side, please note that in case the Search API returns a suitable bond with enough historical data, and the xCCY spread is successfully built, the spread
series name will contain a notation *xCCY, which means that the yields of the second bond were swapped into the base currency.
18
Cross-currency bond peer spread builder2/2
19
Private company analytics – credit ratings1/4
PVTCO is an Eikon app that handles private company financials and derives a default probability and credit rating based on the provided data. The methodology behind the
scenes is the Starmine SmartRatios credit risk model for private companies. The python version of the methodology was designed to applied for several scenarios:
• bulk / enterprise level credit rating calculations on a portfolio of private companies (given complete availability of financials);
• single-company credit rating assessment based on limited financial inputs.
Each of these scenarios has a separate method that can be called using the following syntax.
In case of limited financial data:
list(default_prob, credit_rating) = pvtco.get_data_simple(revenueFY1, net_incomeFY1, cashFY1, total_assetsFY1, short_term_debtFY1, total_debtFY1, total_equityFY1,
industry_name, country_iso)
Returns a list with the default probability and corresponding credit rating.
20
Private company analytics – credit ratings2/4
For complete financial data:
list(name, default_prob, credit_rating) = pvtco.get_data(name, country_iso, sector, revenue, ebitda, ebit, interest_expense, net_income,
diluted_net_income_incl_extra_items, cash, st_investment, accounts_receivable, goodwill_intangibles, total_inventory, total_current_assets, total_assets, current_liabilities,
st_debt, lt_debt, total_debt, total_equity, cf_from_ops, capex)
Returns a list with the company name, default probability and corresponding credit rating.
Parameter Description Possible arguments
name String value containing the name of the company. eg. 'ABC Company'
country_iso String value containing the country ISO code. eg. 'GB'
Only these values are applicable
'ENERGY'
'BASIC MATERIALS'
'INDUSTRIALS'
'CONSUMER CYCLICALS'
sector Should be a string value containing the TRBC classification 'CONSUMER NON-CYCLICALS'
'FINANCIALS'
'HEALTHCARE'
'TECHNOLOGY'
'TELECOMMUNICATION SERVICES'
'UTILITIES'
revenue, ebitda, ebit, interest_expense, net_income,
diluted_net_income_incl_extra_items, cash,
st_investment, accounts_receivable,
eg. [100000000, 11000000, 10500000, 12000000.
goodwill_intangibles, total_inventory, Should be 0 x 6 list of int or float values.
13000000. 10000000]
total_current_assets, total_assets, current_liabilities,
st_debt, lt_debt, total_debt, total_equity, cf_from_ops,
capex
21
Private company analytics – credit ratings3/4
Below are examples of PVTCO calls in case of limited / unavailability of most of the financials.
For demonstration purposes let’s compare the above result with a scenario, where complete financial data is known (see next slide).
22
Private company analytics – credit ratings3/4
23
Loan advisor
An extension to ADYCE is the loan_advisor module. This plugin has contains a single method, which converts ADYCE output fixed rates into floating note quoted margins
(basis point spreads). This logic can be applied to pricing loans and floating rate notes, since both are usually quoted as a margin over index.
df = loan_advisor.get_data(adyce_output_rates, adyce_zero_curve_dictionary)
Returns values in a pandas.DataFrame.
24
Yield map charting1/4
This module can be used as a charting utility for a portfolio of bonds. The user is expected to feed a list of RICs into the main function and the module will get data and build
yield curves on the supplied portfolio automatically.
ymap_charting.get_data(ric_list, width = 15, height = 15)
Returns a matplotlib scatter plot.
25
Yield map charting2/4 // Russia quasi-sovereign
26
Yield map charting3/4 // EUR Daimler, VW
27
Yield map charting4/4
For the user's convenience, an automatic label placement algorithm ensures that the Matplotlib scatter point annotations do not overlap.
28
Matplotlib anti-overlap label placement
A common problem with scatter plots is efficient annotation, which in most cases is solved manually by the user. There are numerous algorithms that address this problem,
like label placement using simulated annealing, however it might be time consuming to get a satisfactory placement on larger label numbers. The implemented method is
based on a greedy algorithm, which may not be as efficient as simulated annealing in terms of the quality, but will highly likely outperform the execution time.
The core principle of the method is to loop through predefined label alignments around a The alignment is carried out in the following order:
data point and increase the distance from the label to the data point in case it overlaps with
its neighbour. In total every label can have up to 8 alignments x 3 radius increments = 24
7 1 5
positions as shown on the diagram below.
3 4
The horizontal & vertical steps here are calculated as width & height of the label’s text
respectively. In case all 24 positions still lead to overlapping, the label will be hidden.
29
Bond portfolio analytics
The module supports cloud-based analytics on a bond portfolio, and allows the user to calculate the Z-spread, modified duration and convexity.
bond_portfolio_analytics.get_data(ric_list, amount_list)
Returns a dictionary containing the portfolio’s Z-spread, modified duration and convexity.
30
3D yield surface
This function builds a yield surface from a RIC chain.
yield_surf.get_data(ric_chain)
Returns a plotly surface chart.
31
COMMODITY •
•
Forward term structure analysis
Seasonality chart
32
Forward term structure analysis1/4
The commodities forward curve analysis module allows the user to specify custom underlyings for the forward term structure and perform a retrospective comparison of the
curve's evolution against a spot contract's dynamic.
cmdty_fwd_curve.get_data(spot_ric, forward_curve, dates = calculation_dates)
Returns a matplotlib chart.
33
Forward term structure analysis2/4
In this example we build curves from futures:
34
Forward term structure analysis3/4
This example shows how a dictionary with a custom set of contracts can be used. The key difference is that the user will need to specify the tenors of the contracts.
35
Forward term structure analysis4/4
In case the user doesn’t know the tenors, it is sufficient to simply provide a list of RICs, and the module will get contract tenors automatically.
36
Commodities intra-month seasonality chart1/2
This module allows the user to plot a seasonality chart by specifying the futures contract RIC, number of years to look back and the required month.
cmdty_seasonality.get_data(ric, number_of_years, month = int)
Returns a plotly chart.
37
Commodities intra-month seasonality chart2/2
38
Vessel monitor
The module supports tracking changes in vessel movements on a user-defined list vessels by RIC or IMO code.
vessel_monitor.get_data(ric, start_date, optional geographical_scope)
The user is required to provide IMOs on a list of vessels, specify a start date (e.g. 2019-01-01) for tracking the change and optionally choose the geographical scope (e.g.
‘asia’, ‘world’, etc.). The method returns a plotly chart and a dictionary of dataframes containing the vessel data.
39
FX/MM • FX hedging impact on Value-at-Risk analysis
ANALYCITCS • Currency relative strength
40
FX hedging impact on VaR analysis1/2
This model calculates a parametric VaR on an FX portfolio, and measures the changes in risk depending on % of FX positions being hedged.
fx_hedge_var_impact.get_data(portfolio)
Returns a plotly chart.
The portfolio is to be declared as a dictionary of the following structure: { currency_RIC : [ position_amt, %_of_position_hedged ] }
Amount, USD
7,375,175
In this example we will be building a risk profile for a
portfolio of 5 currencies: SGD, EUR, GBP, JPY and CHF 10,157,440
with a total value of 8.4 mln USD.
41
FX hedging impact on VaR analysis2/2
42
Currency relative strength
This module builds applies statistical methods to help the user determine the relative value and potential performance of given cross-FX pairs based on their deviation from
the mean, and visualize the correlation with a defined base currency.
fx_cross_relative_value.get_data(fx_list, base_currency)
The function returns a pandas dataframe containing the z-scores and correlations of the cross-currency pairs, as well as a plotly scatter plot.
43
QUANT •
•
Timeseries forecasting with standard normal distribution limits
Timeseries forecasting with the ARIMA model
44
Timeseries forecasting with distribution limits
This model builds a forecast based on the drift of a historical time series and plots the distribution limits at a user-defined confidence interval.
series_forecast.get_data(instrument, confidence_interval)
Returns a plotly chart.
45
Timeseries forecasting with ARIMA model
This module builds an autoregressive moving average based on time series for short term series forecast.
arima_forecast.get_data(ric, start_date)
Returns a matplotlib chart and a Pandas dataframe containing the predicted values.
46
Yield curve principal component analysis1/3
The pca_yield_curve module performs the PCA decomposition of a defined list of rates instruments (e.g. treasuries or IR swaps) and models the expected mean reversion
on a curve trade. Additionally this model runs a Monte Carlo simulation using an Ornstein-Uhlenbeck process to determine the strategy's optimal horizon period.
pca_yield_curve.get_data(instruments, strategy, trade)
The function returns a pandas dataframe containing the strategy residual in bps, mean reversion and 2x standard deviation limits; the optimal holding period print as well as 2
plotly charts displaying the dataframe series with a vertical line showing the strategy horizon date, and the last residuals by tenors.
47
Yield curve principal component analysis2/3
48
Yield curve principal component analysis3/3
Latest residuals by tenors.
49
CHAT BOT •
•
DCM syndication advisory bot
Bond portfolio charting bot
50
DCM syndication advisory bot
In this example ADYCE is integrated with a chat and parses the incoming messages for keywords like ‘price’, tenors, currencies.
51
Bond portfolio charting bot
The example below allows the user to drop a list of RICs or ISINs into the chat and ask the bot to plot these bonds on a chart and automatically construct yield curves.
52
Commodity forward term structure bot
The commodities forward curve analysis bot supports 2 methods of specifying the curve that needs to be plotted: by listing the complete constituents list, or by providing a
RIC chain containing the forwards / futures contracts.
53
The Financial and
Risk business of
Thomson Reuters
is now Refinitiv.
© 2019
54