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
12025-01-3158.34958.73158.34358.56347119IUSA.AS
22025-01-3057.99358.1657.657.79724106IUSA.AS
32025-01-2958.09258.21157.79357.8241871IUSA.AS
42025-01-2857.48857.8557.23657.65444404IUSA.AS
52025-01-2757.17157.20656.17156.77464342IUSA.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
20.01316620.00541250.003246970.02231710.00933904
3-0.0003978650.002059190.0117772-0.008162340.00367188
40.00287511-0.000613820.01565430.002595260.00412858
50.0153812-0.0001314840.006169550.02754340.0120403

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.1813310.01494290.2043090.1709850.2085440.3112480.1049140.122241
20.2129080.01992840.1940080.03342210.07219050.3562030.3441760.141168
30.2012390.01666890.2702430.10190.06968490.2923210.2658520.129108
40.1438120.009299650.1317020.3932060.05245170.2529730.1696670.0964347
50.1653910.009696730.2753640.1590730.343540.01863860.2033840.098472

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`
qt.qpa.xcb: could not connect to display
qt.qpa.plugin: From 6.5.0, xcb-cursor0 or libxcb-cursor0 is needed to load the Qt xcb platform plugin.
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: eglfs, offscreen, vnc, minimal, minimalegl, xcb, linuxfb, vkkhrdisplay.

Aborted (core dumped)
connect: Connection refused
GKS: can't connect to GKS socket application

GKS: Open failed in routine OPEN_WS
GKS: GKS not in proper state. GKS must be either in the state WSOP or WSAC in routine ACTIVATE_WS

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.04151820.002324980.08.34115e-170.8843290.02920851.38247e-180.0864630.048218
20.07463040.002702690.020.2175380.7445740.0378882.50826e-196.45323e-180.0519874
30.1072310.00382130.040.3747060.5973550.02793934.90218e-187.56357e-170.0618167
40.1398320.005685640.060.5318730.4501360.01799071.21673e-171.5762e-160.0754032
50.1724320.008295730.080.6890410.3029170.008042026.47313e-177.66562e-160.0910809

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
qt.qpa.xcb: could not connect to display
qt.qpa.plugin: From 6.5.0, xcb-cursor0 or libxcb-cursor0 is needed to load the Qt xcb platform plugin.
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: eglfs, offscreen, vnc, minimal, minimalegl, xcb, linuxfb, vkkhrdisplay.

Aborted (core dumped)
connect: Connection refused
GKS: can't connect to GKS socket application

GKS: Open failed in routine OPEN_WS
GKS: GKS not in proper state. GKS must be either in the state WSOP or WSAC in routine ACTIVATE_WS

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.2120450.01311120.7406250.04923210.176050.02180040.01229240.1145041.67719

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.