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
timestamp | open | high | low | close | volume | ticker | |
---|---|---|---|---|---|---|---|
SubStrin… | Float64 | Float64 | Float64 | Float64 | Int64 | String | |
1 | 2024-05-02 | 46.869 | 47.119 | 46.747 | 46.849 | 35049 | IUSA.AS |
2 | 2024-04-30 | 47.568 | 47.604 | 47.347 | 47.347 | 41956 | IUSA.AS |
3 | 2024-04-29 | 47.532 | 47.69 | 47.445 | 47.467 | 21337 | IUSA.AS |
4 | 2024-04-26 | 47.247 | 47.62 | 47.13 | 47.526 | 28257 | IUSA.AS |
5 | 2024-04-25 | 46.863 | 46.88 | 46.45 | 46.577 | 47653 | IUSA.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.AS | IBCI.AS | IEMA.AS | WTCH.AS | VWRL.AS | |
---|---|---|---|---|---|
Float64 | Float64 | Float64 | Float64 | Float64 | |
1 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
2 | -0.0105738 | 0.00564998 | 0.0136715 | 0.0249604 | -0.0046364 |
3 | -0.00253127 | -0.00079646 | -0.00429247 | -0.0167093 | -0.00273738 |
4 | -0.0012422 | -0.000972591 | 0.00745203 | -0.00310215 | 0.00119668 |
5 | 0.0201701 | 0.00451728 | 0.015657 | -0.00191557 | 0.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_return | port_var | weight_IUSA.AS | weight_IBCI.AS | weight_IEMA.AS | weight_WTCH.AS | weight_VWRL.AS | port_std | |
---|---|---|---|---|---|---|---|---|
Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | |
1 | 0.106607 | 0.00465125 | 0.0381079 | 0.351567 | 0.292764 | 0.00302277 | 0.314539 | 0.0682001 |
2 | 0.158641 | 0.00428488 | 0.230076 | 0.260224 | 0.172155 | 0.142581 | 0.194964 | 0.065459 |
3 | 0.187373 | 0.00862179 | 0.638835 | 0.0424385 | 0.220947 | 0.0031014 | 0.0946781 | 0.0928536 |
4 | 0.179568 | 0.00541704 | 0.109236 | 0.216783 | 0.222278 | 0.280688 | 0.171016 | 0.0736005 |
5 | 0.206552 | 0.00820471 | 0.0266481 | 0.0337583 | 0.342499 | 0.333346 | 0.263748 | 0.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_return | port_var | risk_aversion | weight_IUSA.AS | weight_IBCI.AS | weight_IEMA.AS | weight_WTCH.AS | weight_VWRL.AS | port_std | |
---|---|---|---|---|---|---|---|---|---|
Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | |
1 | 0.0836396 | 0.0025433 | 0.0 | 9.36321e-18 | 0.641195 | 0.00621247 | 0.0647111 | 0.287882 | 0.0504312 |
2 | 0.152335 | 0.00334593 | 0.02 | 0.382835 | 0.432733 | 0.0111108 | 0.173321 | 2.0288e-16 | 0.0578441 |
3 | 0.212849 | 0.0054587 | 0.04 | 0.525898 | 0.19786 | 2.62573e-18 | 0.276243 | 3.32805e-18 | 0.073883 |
4 | 0.263385 | 0.00832251 | 0.06 | 0.633033 | 8.42739e-19 | 2.47491e-19 | 0.366967 | 3.84431e-19 | 0.0912278 |
5 | 0.267327 | 0.00868722 | 0.08 | 0.598394 | 3.07203e-18 | 3.34667e-18 | 0.401606 | 5.81672e-18 | 0.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_return | port_var | weight_IUSA.AS | weight_IBCI.AS | weight_IEMA.AS | weight_WTCH.AS | weight_VWRL.AS | port_std | sharp_ratio | |
---|---|---|---|---|---|---|---|---|---|
Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | |
5000 | 0.243932 | 0.00722558 | 0.602129 | 0.0383834 | 0.0250949 | 0.300638 | 0.0337547 | 0.0850034 | 2.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.
Recommended usage
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.