import matplotlib.pyplot as plt, numpy as np, pandas as pd
plt.style.use('bmh')
from matplotlib import rcParams
rcParams['font.family'] = 'Verdana'
Let's suppose that 3 months ago we built our portfolio with this macro asset allocation:
35% equity - 50% bonds - 15% precious metals
In order to reach this allocation we bought 22 ETFs/ETC listed on Italian Stock Exchange.
Let's suppose that after 2 months stock prices have fallen and precious metals prices have risen, mantaining the value of portfolio close to the initial capital of 100k, but with different weights. Moreover the relative weights of the asset within each macro asset have changed (for example the weight of gold is not anymore the same within the precious metals class, or the weight of equity emerging markets has changed compared to the initial weight).
We want to know which are the current weights of our portfolio.
Let's say that for each day we have an excel file named 'day'.xlsx where are reported the ETF tickers in our portfolio with the corresponding closing market value of the day.
Let's verify the new weights at the end of the chosen day:
# input the day we want to check out
day = input('Weights at the end of (dd-mm-yyyy):')
df = pd.read_excel( day + '.xlsx')
print('Portfolio at %s' % day)
df
We have 19 ETFs in our portfolio that replicate indexes of developed and emerging markets for stocks and bonds (in this notebook we don't group bond ETFs by government and corporate types), 3 ETC for precious metals, and a small amount of residual cash reported in the last row of the DataFrame.
# ETFs equity developed countries
equity_dev = ['NRAM','MEUD','LCJP','EPRA','XDER','CSPXJ']
# ETFs equity emerging countries
equity_eme = ['SAFRI', 'RUS', 'AEEM', 'ALAT', 'CINA']
# ETFs bonds developed countries
bond_dev = ['CSBGU7', 'CBUS5', 'ITPS', 'EM57', 'JNKE', 'CBEU5', 'XJSE', 'XCS2']
# ETFs bonds emerging countries
bond_eme = ['EMLC']
# ETC silver, palladium, gold
precious_metals = ['PHAG','PHPD','SGBS']
# total equity
equity = equity_dev + equity_eme
# total bond
bond = bond_dev + bond_eme
# the function the finds out the current weights of portfolio
def find_weight(compartment):
weight = df[df['Ticker'].isin(compartment)]['Value'].sum(axis = 0) / df['Value'].sum(axis = 0)
return round(weight,4)
# Let's see the total current asset allocation
# The small white area is the residual cash
weights = []
print('Asset allocation:\n')
for comp in (equity, bond, precious_metals):
weights.append(find_weight(comp))
plt.figure(figsize = (8,6))
plt.pie(weights, labels = ['Equity', 'Bonds', 'Precious Metals'], autopct='%1.1f%%', textprops = {'fontsize' : 14});
# Let's draw pie charts to represent absolute weights and relative weights for each macro asset
# (equity, bonds, precious metals)
def chart(macro_asset : str, comp1 : list, comp2: list, labels : list):
''' Args:
macro_asset: equity, bonds or metals.
comp1 : subset of tickers of the macro_asset
comp2 : complementary subset of the same macro_asset
'''
fig, ax = plt.subplots(1,2, figsize = (14,5))
fig.suptitle(macro_asset, fontsize = 26, color = 'tan', y = 1.1)
ax[0].pie([find_weight(comp1), find_weight(comp2)], labels = labels, autopct='%1.1f%%',textprops = {'fontsize' : 13});
ax[1].pie([find_weight(comp1) / (find_weight(comp1) + find_weight(comp2)) \
, 1 - find_weight(comp1) / (find_weight(comp1) + find_weight(comp2))]\
, labels = labels, autopct='%1.1f%%', textprops = {'fontsize' : 13});
ax[0].set_title('Absolute weights')
ax[1].set_title('Relative weights');
macro = 'Equity'
labels = [macro + i for i in [' developed', ' emerging']]
chart(macro, equity_dev, equity_eme, labels)
macro = 'Bonds'
labels = [macro + i for i in [' developed', ' emerging']]
chart(macro, bond_dev, bond_eme, labels)
labels = ['Gold', 'Silver + Palladium']
chart('Precious metals', ['SGBS'], set(precious_metals) - set(['SGBS']), labels);