Planning tools

Modern Portfolio Theory (MPT)

The modern portfolio theory (MPT) is one of the oldest applications in modern finance still used today. The technical implication can be found in the theory subsection. We will now demonstrate how MPT is implemented in the Peccon package and lastly cover some import limitations and recommendations of the tool.

Example

First extract the daily price data of all the assets you are considering in your portfolio.

using Peccon
Tickers = ["IUSA.AS", "IBCI.AS", "IEMA.AS", "WTCH.AS", "VWRL.AS"];
# data = data_alpha(Tickers, "your_api_key", 252);
data[1][1:5,:]

5 rows × 7 columns

timestampopenhighlowclosevolumeticker
SubStrin…Float64Float64Float64Float64Int64String
12024-05-0246.86947.11946.74746.84935049IUSA.AS
22024-04-3047.56847.60447.34747.34741956IUSA.AS
32024-04-2947.53247.6947.44547.46721337IUSA.AS
42024-04-2647.24747.6247.1347.52628257IUSA.AS
52024-04-2546.86346.8846.4546.57747653IUSA.AS

Then calculated the daily log returns for each asset in the portfolio.

returns = daily_returns(data, Tickers);
returns[1:5,:]

5 rows × 5 columns

IUSA.ASIBCI.ASIEMA.ASWTCH.ASVWRL.AS
Float64Float64Float64Float64Float64
10.00.00.00.00.0
2-0.01057380.005649980.01367150.0249604-0.0046364
3-0.00253127-0.00079646-0.00429247-0.0167093-0.00273738
4-0.0012422-0.0009725910.00745203-0.003102150.00119668
50.02017010.004517280.015657-0.001915570.0169057

Subsequently, simulate 5000 possible portfolio combinations with the assets in the portfolio.

port_sim = sim_mpt(returns);
port_sim[1:5,:]

5 rows × 8 columns

exp_returnport_varweight_IUSA.ASweight_IBCI.ASweight_IEMA.ASweight_WTCH.ASweight_VWRL.ASport_std
Float64Float64Float64Float64Float64Float64Float64Float64
10.1066070.004651250.03810790.3515670.2927640.003022770.3145390.0682001
20.1586410.004284880.2300760.2602240.1721550.1425810.1949640.065459
30.1873730.008621790.6388350.04243850.2209470.00310140.09467810.0928536
40.1795680.005417040.1092360.2167830.2222780.2806880.1710160.0736005
50.2065520.008204710.02664810.03375830.3424990.3333460.2637480.0905799

Plot the expected return and variance of each simulated portfolio to visualize the efficient frontier.

using StatsPlots
@df port_sim scatter(:port_var, :exp_return)
savefig("sim_fig.svg"); nothing # hide
   Resolving package versions...
    Updating `~/work/Peccon.jl/Peccon.jl/docs/Project.toml`
  [f3b207a7] + StatsPlots v0.15.7
  No Changes to `~/work/Peccon.jl/Peccon.jl/docs/Manifest.toml`
GKS: cannot open display - headless operation mode active

calculate the efficient frontier of the combinations of stocks.

port_opt = opt_mpt(returns, 0.0:0.02:2.0, 0.00) ;
port_opt[1:5,:]

5 rows × 9 columns

exp_returnport_varrisk_aversionweight_IUSA.ASweight_IBCI.ASweight_IEMA.ASweight_WTCH.ASweight_VWRL.ASport_std
Float64Float64Float64Float64Float64Float64Float64Float64Float64
10.08363960.00254330.09.36321e-180.6411950.006212470.06471110.2878820.0504312
20.1523350.003345930.020.3828350.4327330.01111080.1733212.0288e-160.0578441
30.2128490.00545870.040.5258980.197862.62573e-180.2762433.32805e-180.073883
40.2633850.008322510.060.6330338.42739e-192.47491e-190.3669673.84431e-190.0912278
50.2673270.008687220.080.5983943.07203e-183.34667e-180.4016065.81672e-180.0932053

In the dataframe the optimal portfolios with their respective risk-aversions are shown.

subsequently, add the efficient frontier to the simulated plot.

@df port_opt scatter!(:port_var, :exp_return)

savefig("opt_fig.svg"); nothing # hide

Lastly, calculate the sharp ratio to find the portfolio with the optimal return variation ratio

port_sim_sharp = sharp_ratio(port_sim) ;
@show port_sim_sharp[end,:]
port_opt_sharp = sharp_ratio(port_sim) ;
port_opt_sharp[end,:]

DataFrameRow (9 columns)

exp_returnport_varweight_IUSA.ASweight_IBCI.ASweight_IEMA.ASweight_WTCH.ASweight_VWRL.ASport_stdsharp_ratio
Float64Float64Float64Float64Float64Float64Float64Float64Float64
50000.2439320.007225580.6021290.03838340.02509490.3006380.03375470.08500342.63439

limitations

There are three main limitation to this tool. The first limitation is that the MPT is a historical measurement of the portfolio performance. It does not say anything about future performance of the portfolio. Different Macro-economic situations might lead to total different end results. The second issue is that the tool is based on the expected return and variance of the portfolio. This captures the risk return relationship quite well but it does not take into account skewness and tail risk. It therefore gives rise to a reduced volatility and an inflated growth rate for a portfolio. Lastly, the risk measurement is probabilistic in nature. It does not reflect the structural roots of the risk. For example, the risk of a stock are off a total different nature then that of a commodity, but to tool will still account for them the same way.

Never use this tool for individual stock picking and never but then also never rely only on the MPT. Always do your own due diligence before creating your portfolio and again this is no way or form financial advice.

So why should you use this tool and for what purpose? It is highly recommended to use this tool with exchange traded funds (ETF) as these products are already substantially diversified and issue two of the MPT is therefore greatly diminished. Also, the structural risk that certain ETF are exposed is difficult the estimate and the MPT can help you gain insights into which ETF have less or more risk compared to the returns they offer. Lastly, MPT also works better if you invest in all assets classes as each class has risks of a different nature and you are then therefore not fully exposed to one particular kind of risk.

To know which portfolio weights you should apply, you have to understand your risk preference. If you do not want to take a lot of risk, it is beneficial to look at optimal portfolio's with low values in $P$. The reverse is true for people who are risk seeking.