Open in Colab

You can run the code examples in Google Colab.

To install the package:

[ ]:
!pip install okama

import okama and matplotlib packages …

[1]:
import matplotlib.pyplot as plt

plt.rcParams["figure.figsize"] = [12.0, 6.0]

import okama as ok

Get information about a single asset

You can start with getting general information about a single asset / index.

[2]:
one_asset = ok.Asset("VOO.US")
one_asset
[2]:
symbol                         VOO.US
name             Vanguard S&P 500 ETF
country                           USA
exchange                    NYSE ARCA
currency                          USD
type                              ETF
first date                    2010-10
last date                     2021-10
period length                    11.0
dtype: object
[3]:
# live (20 min delay) price
one_asset.price
[3]:
406.76
[4]:
# dividends history
one_asset.dividends.tail(10)
[4]:
Date
2020-12    1.3829
2021-01    0.0000
2021-02    0.0000
2021-03    1.2625
2021-04    0.0000
2021-05    0.0000
2021-06    1.3329
2021-07    0.0000
2021-08    0.0000
2021-09    1.3084
Freq: M, Name: VOO.US, dtype: float64

Financial Database: Tickers & Namespaces

If you doubt about ticker availability or asset name, check it with search:

[5]:
ok.search("exxon")
[5]:
symbol ticker name country exchange currency type isin
0 XOM.US XOM Exxon Mobil Corporation USA NYSE USD Common Stock None
1 XONA.XETR XONA Exxon Mobil Corporation Germany XETR EUR Common Stock
2 XONA.XFRA XONA Exxon Mobil Corporation Germany XFRA EUR Common Stock
3 XONA.XSTU XONA EXXON MOBIL (XONA.SG) Germany XSTU EUR Common Stock

Namespase is a set of characters after the period in the ticker (SPY.US).

Namespaces are based on MIC (Market Identifier Codes) and okama own code systems for macro parameters.

[6]:
# available namespaces
ok.namespaces
[6]:
{'CBR': 'Central Banks official currency exchange rates',
 'CC': 'Cryptocurrency pairs with USD',
 'COMM': 'Commodities prices',
 'FX': 'FOREX currency market',
 'INDX': 'Indexes',
 'INFL': 'Inflation',
 'LSE': 'London Stock Exchange',
 'MOEX': 'Moscow Exchange',
 'PIF': 'Russian mutual funds',
 'RATE': 'Bank deposit rates',
 'RE': 'Real estate prices',
 'US': 'US Stock Exchanges and mutual funds',
 'XAMS': 'Euronext Amsterdam',
 'XETR': 'XETRA Exchange',
 'XFRA': 'Frankfurt Stock Exchange',
 'XSTU': 'Stuttgart Exchange',
 'XTAE': 'Tel Aviv Stock Exchange (TASE)'}
[2]:
# available symbols in namespace
ok.symbols_in_namespace("INDX")
[2]:
symbol ticker name country exchange currency type isin
0 000906.INDX 000906 China Securities 800 Unknown INDX USD INDEX
1 0O7N.INDX 0O7N Scale All Share GR EUR Germany INDX EUR INDEX
2 3LHE.INDX 3LHE ESTX 50 Corporate Bond TR Greece INDX EUR INDEX
3 5SP2550.INDX 5SP2550 S&P 500 Retailing (Industry Group) USA INDX USD INDEX
4 990100.INDX 990100 MSCI International World Index Price Unknown INDX USD INDEX
... ... ... ... ... ... ... ... ...
1509 XU100.INDX XU100 BIST 100 Turkey INDX TRY INDEX
1510 XUSIN.INDX XUSIN BIST Industrials Turkey INDX TRY INDEX
1511 XUSRD.INDX XUSRD BIST Sustainability Turkey INDEX TRY INDEX
1512 XUTEK.INDX XUTEK BIST Technology Turkey INDEX TRY INDEX
1513 YMU0.INDX YMU0 E-mini Dow $5 Future Sept 20 USA INDX USD Futures

1514 rows × 8 columns

Compare assets from different stock markets

AssetList is used to compare different type of stocks, indexes, currencies, or commodities. Asset performance is adjusted to the base currency (USD is default).

[8]:
ls = ["SPY.US", "BND.US", "GC.COMM", "EUR.FX"]
currency = "EUR"  # base currency
[9]:
x = ok.AssetList(
    ls, ccy=currency, last_date="2020-01"
)  # first_date and last_date limits the Rate of Return time series
x
[9]:
assets           [SPY.US, BND.US, GC.COMM, EUR.FX]
currency                                       EUR
first_date                                 2007-05
last_date                                  2020-01
period_length                   12 years, 9 months
inflation                                 EUR.INFL
dtype: object
[10]:
x.names
[10]:
{'SPY.US': 'SPDR S&P 500 ETF Trust',
 'BND.US': 'Vanguard Total Bond Market Index Fund ETF Shares',
 'GC.COMM': 'Gold',
 'EUR.FX': 'EUR'}

lets see the accumulated return and comapare it with the inflation.

[11]:
x.wealth_indexes.plot();
../_images/jupyter_quickstart_24_0.png

Drawdowns history is availably and easy to see

[12]:
x.drawdowns.plot();
../_images/jupyter_quickstart_26_0.png

See the dividend yield history for all the assets in the list.

[13]:
x.dividend_yield
[13]:
SPY.US BND.US GC.COMM EUR.FX
2007-05 0.000000 0.001699 0.0 0.0
2007-06 0.004358 0.005189 0.0 0.0
2007-07 0.004543 0.008332 0.0 0.0
2007-08 0.004471 0.012238 0.0 0.0
2007-09 0.009239 0.016673 0.0 0.0
... ... ... ... ...
2019-09 0.017920 0.026580 0.0 0.0
2019-10 0.017939 0.027181 0.0 0.0
2019-11 0.017102 0.026875 0.0 0.0
2019-12 0.017516 0.027322 0.0 0.0
2020-01 0.017338 0.026509 0.0 0.0

153 rows × 4 columns

… or plot the same results

[14]:
x.dividend_yield.plot();
../_images/jupyter_quickstart_30_0.png

describe method shows all the main parameters (risk metrics, rate of return etc.) for the list of assets.

[15]:
x.describe(years=[1, 10])  # You can specify the period or leave the default: 1, 5 and 10 years
[15]:
property period BND.US EUR.FX GC.COMM SPY.US inflation
0 Compound return YTD 0.030712 0.010700 0.056990 0.010296 -0.010000
1 CAGR 1 years 0.132887 0.031992 0.235531 0.253479 0.011915
2 CAGR 10 years 0.060618 0.022543 0.062663 0.164232 0.012802
3 CAGR 12 years, 9 months 0.060013 0.016364 0.086480 0.102403 0.012940
4 Dividend yield LTM 0.026509 0.000000 0.000000 0.017338 NaN
5 Risk 12 years, 9 months 0.107615 0.105235 0.194223 0.150558 NaN
6 CVAR 12 years, 9 months 0.127888 0.155073 0.303712 0.331293 NaN
7 Max drawdowns 12 years, 9 months -0.150754 -0.173337 -0.365609 -0.468101 NaN
8 Max drawdowns dates 12 years, 9 months 2011-04 2011-04 2013-12 2009-02 NaN
9 Inception date None 2007-05 2000-01 1979-01 1993-02 2007-05
10 Last asset date None 2021-10 2021-10 2021-10 2021-10 2020-01
11 Common last data date None 2020-01 2020-01 2020-01 2020-01 2020-01

Correlation Matrix

If you need to check the correlation (or covariance) between assets returns, it’s easy to use native Pandas functions.

Monthly rate of return time series are available with .assets_ror property:

[16]:
x.assets_ror
[16]:
SPY.US BND.US GC.COMM EUR.FX
2007-05 0.048581 0.006188 -0.012575 0.0142
2007-06 -0.021005 -0.009580 -0.019415 -0.0065
2007-07 -0.040600 -0.000488 0.013278 -0.0096
2007-08 0.015940 0.017946 0.012930 0.0031
2007-09 -0.008042 -0.039175 0.055943 -0.0450
... ... ... ... ...
2019-09 0.028064 0.002652 -0.020037 0.0084
2019-10 -0.001102 -0.019670 -0.005793 -0.0227
2019-11 0.048945 0.011895 -0.021713 0.0123
2019-12 0.011194 -0.018088 0.019349 -0.0174
2020-01 0.010296 0.030712 0.056990 0.0107

153 rows × 4 columns

The correlation matrix is obtained by x.ror.corr()

[17]:
x.assets_ror.corr()
[17]:
SPY.US BND.US GC.COMM EUR.FX
SPY.US 1.000000 0.196963 -0.085213 0.251952
BND.US 0.196963 1.000000 0.336050 0.936992
GC.COMM -0.085213 0.336050 1.000000 0.223800
EUR.FX 0.251952 0.936992 0.223800 1.000000

Covariance matrix:

[18]:
x.assets_ror.cov()
[18]:
SPY.US BND.US GC.COMM EUR.FX
SPY.US 0.001541 0.000226 -0.000170 0.000294
BND.US 0.000226 0.000855 0.000500 0.000814
GC.COMM -0.000170 0.000500 0.002590 0.000338
EUR.FX 0.000294 0.000814 0.000338 0.000883
Rolling correlation with the benchmark is useful to see the correlation patterns for shorter periods.
The benchmark (index) should be on the first place in the AssetList (SPY.US in this example).
[19]:
x.index_rolling_corr(window=12 * 5).plot()
[19]:
<AxesSubplot:>
../_images/jupyter_quickstart_42_1.png

Basic portfolio methods

Lets create a portfolio with 3 assets and base currency USD. We need to specify weigts.

[20]:
tickers = [
    "VNQ.US",
    "DBXD.XFRA",
    "MCFTR.INDX",
]  # we can create lists of assets and portfolio containing general type of assets and **indexes**
w = [0.5, 0.25, 0.25]
currency = "USD"
[21]:
y = ok.Portfolio(tickers, ccy=currency, weights=w)
y
[21]:
symbol                              portfolio_8056.PF
assets                [VNQ.US, DBXD.XETR, MCFTR.INDX]
weights                             [0.5, 0.25, 0.25]
rebalancing_period                              month
currency                                          USD
inflation                                    USD.INFL
first_date                                    2007-02
last_date                                     2021-08
period_length                      14 years, 7 months
dtype: object
[22]:
y.table
[22]:
asset name ticker weights
0 Vanguard Real Estate Index Fund ETF Shares VNQ.US 0.50
1 Xtrackers - DAX UCITS ETF DBXD.XETR 0.25
2 MOEX Total Return MCFTR.INDX 0.25

Portfolio has the same property .wealth_index (accumulated return) as AssetList objects.

[23]:
y.wealth_index.plot();
../_images/jupyter_quickstart_49_0.png

Risk metrics

You can use risk(volatility or standard deviation), semideviation, max drawdown, var and cvar metrics.

[24]:
y.risk_annual
[24]:
0.23294736579193767
[25]:
y.semideviation_annual
[25]:
0.18204535267514022
[26]:
y.get_var_historic(level=1)
[26]:
0.5516180873119316
[27]:
y.get_cvar_historic(level=5)
[27]:
0.5047561855627113
[28]:
y.drawdowns.min()
[28]:
-0.6474308140441074
… another useful rist metric is max drawdown recovery period - .recovery_period.
The longest recovery period for the portfolio assets value is returned.
[29]:
y.recovery_period / 12  # years
[29]:
3.4166666666666665

.describe shows main properties for the portfolio in different trailing periods.

[30]:
y.describe()
[30]:
property period portfolio_8056.PF inflation
0 compound return YTD 0.238152 0.050356
1 CAGR 1 years 0.346644 0.052562
2 CAGR 5 years 0.116337 0.025828
3 CAGR 10 years 0.095214 0.019065
4 CAGR 14 years, 7 months 0.061114 0.020872
5 Dividend yield LTM 0.014660 NaN
6 Risk 14 years, 7 months 0.232947 NaN
7 CVAR 14 years, 7 months 0.579034 NaN
8 Max drawdown 14 years, 7 months -0.647431 NaN
9 Max drawdown date 14 years, 7 months 2009-02 NaN

Forecasting return

Monte Carlo forecast for normal distrubution.
.plot_forecast_monte_carlo plots N random wealth indexes according to given return distribution.
[31]:
y.plot_forecast_monte_carlo(distr="norm", years=5, n=20)
../_images/jupyter_quickstart_63_0.png

For normal distribution it’s easy to see forecasted accumulated return for a given set of percentiles.

[32]:
y.plot_forecast(
    years=5, today_value=1000, percentiles=[10, 50, 90]
);  # lognormal or historical distribution can be used with "distr" argument
../_images/jupyter_quickstart_65_0.png

More examples of forecasting portfolio perfomance are available in07 forecasting.ipynb.

[ ]: