Explore Portfolio Optimization using Modern Portfolio Theory (MPT) in Python. Learn how to construct efficient portfolios by balancing risk and return, inspired by the groundbreaking work of Harry Markowitz. Discover key concepts like the efficient frontier and mean-variance optimization, which are essential for diversification and maximizing portfolio performance. With Python’s libraries like NumPy and Pandas, analyze investment portfolios, apply Monte Carlo simulation for quantitative analysis, and visualize results using Matplotlib.pyplot (plt). Elevate your investment strategy with practical insights from stock market data sourced from Yahoo Finance and ETFs, optimizing allocations for higher returns while managing risk effectively.
This article was published as a part of the Data Science Blogathon.
In finance, a portfolio, inspired by Harry Markowitz, refers to a collection of financial assets such as stocks, bonds, commodities, and ETFs, aimed at diversification to mitigate risk while maximizing returns. Returns represent the gains or losses generated by these assets over a specific time period, typically expressed as a percentage.
Returns can be calculated in Python by analyzing historical data of asset prices sourced from platforms like Yahoo Finance. The percentage change in an asset’s price over a given time frame can be computed using functions like pct_change() from Pandas. This enables investors to calculate returns for individual assets or entire portfolios efficiently.
In investments, risk refers to the uncertainty or volatility of returns. It includes market fluctuations, economic conditions, and company-specific events. Understanding and managing risk is crucial for investors to protect their capital and achieve their financial goals.
In Python, portfolio risk is determined by the combined risk of individual assets and their correlations within the portfolio. Metrics such as the standard deviation of returns, or volatility, are commonly used to measure portfolio risk. Python libraries like Pandas and NumPy can compute covariance matrices and portfolio variances, enabling investors to assess and manage risk effectively.
Before we calculate the returns on an asset and portfolio, let’s briefly examine the definitions of portfolio and returns.
A portfolio is a collection of financial instruments like stocks, bonds, commodities, cash and cash equivalents , as well as their fund counterparts. [Investopedia] In this article, we will have our portfolio containing 4 assets (“Equities-focused portfolio“): the shares of Apple Inc. , Nike (NKC), Google and Amazon . The preview of our data is shown below:
It refers to the gain or loss on our asset/portfolio over a fixed time frame. In this analysis, we make a return as the percentage change in the closing price of the asset over the previous day’s closing price. We will compute the returns using .pct_change() function in python. Below is shown the python code to do the same and the top 5 rows (head) of the returns Note: the first row is Null if there doesn’t exist a row prior to that to facilitate the computation of percentage change.
It is defined as the weighted sum of the assets’ returns. To demonstrate how to compute portfolio return in Python, let us initialize the weights randomly (which we will later optimize). The portfolio return is computed as shown in the code below, and the head of the portfolio returns is shown as well:
We have seen how to calculate the returns. Now, let’s shift our focus to another concept: Risk.
The method to compute the risk of a portfolio is written below and subsequently, we explain and give the mathematical formulation for each of the steps:
The formula to compute the covariance and annualizing it is :covariance = returns.cov()*252
Since there are 252 trading days, we multiply the covariance by 252 in order to annualize it.
The portfolio variance , to be calculated in step3 above, depends on the weights of the assets in the portfolio and is defined as:
where,
Below is shown the approach to compute the asset risk in python.
As explained above we multiple the covariance matrix with 252 as there are 252 trading days in a year.
The diagonal elements of the variance_matrix represent the variance of each asset, while the off-diagonal terms represent the covariance between the two assets, eg: (1,2) element represents the covariance between Nike and Apple.
The code to compute the portfolio Risk in python, the method of which we saw above, is as shown:
Now, the task for us is to optimize the weights. Why? So that we can maximize our return or minimize our risk – and that we do by using the Modern Portfolio Theory!
Modern portfolio theory argues that an investment’s risk and return characteristics should not be viewed alone, but should be evaluated by how the investment affects the overall portfolio’s risk and return. MPT shows that an investor can construct a portfolio of multiple assets that will maximize returns for a given level of risk. Likewise, given a desired level of expected return, an investor can construct a portfolio with the lowest possible risk. Based on statistical measures such as variance and correlation, an individual investor’s performance is less important than how it impacts the entire portfolio [Investopedia]
This theory is summarized in the figure below. We find the frontier as shown below and either maximize the Expected Returns for Risk level or minimize Risk for a given Expected Return level.
Our goal is to choose the weights for each asset in our portfolio such that we maximize the expected return given a level of risk .
Mathematically, the objective function can be define as shown below:
Another way to look at the Efficient Frontier and the objective function is that we can minimize the risk given that the Expected return is at least greater than is given value. Mathematically this objective function can be written as:
The first line represents that the objective is to minimize the portfolio variance , i.e in turn the portfolio volatility and therefore minimizing the risk.
The subject to constraints implies that the returns have to be greater than a particular target return, all the weights should sum to 1 and weights should not be negative.
Now, that we know the concept, let’s go to the hands-on part now!
Firstly, we create the efficient frontier by running a loop. In each loop, we consider a randomly allocated different set of weights for the assets in our portfolio and calculate the return and volatility for that combination of weights.
For this purpose we create 3 empty lists , one for storing the returns , another for storing the volatility and the last one for storing the portfolio weights.
Once we have created the lists, we randomly generate the weights for our assets repeatedly , then normalized the weight to sum to 1. We then compute the returns in the same manner as we calculated earlier., we compute the portfolio variance and then we take the square root and then annualize it to get the volatility, the measure of risk for our portfolio.
We now aggregate the data into a dictionary and then create a dataframe to see the weight combination for the assets and the corresponding returns and volatility that they generate.
Here is the preview of the data of portfolio returns, volatility and weights.
Now we have everything with us to enter into the final lap of this race and find the optimal set of weights!
We plot Volatility against the returns that we compute above, this will give us the Efficient Frontier that we wanted to create at the beginning of this article.
And here we go!
Now that we have with us the Efficient Frontier, let’s find the optimal weights.
We can optimize the using multiple methods as written below:
In this article I will optimize via the first two approaches. In the third segment the ‘Maximum returns at a risk level’ and ‘Minimum Risk at a Expected Return Level’ are pretty straight forward while the one based on Sortino Ratio is similar to Sharpe Ratio.
To find the minimum volatility combination, we select the row in our data frame which corresponds to the minimum variance, and we find that row using the .idxmin() function. The code to do the same is shown below:
The weights that we get from this are:
Now, find out where will the minimum volatility point lies on the above curve ? The answer is shown at the end! Don’t cheat though!
The Sharpe-ratio is the average return earned in excess of the risk-free rate per unit of volatility or total risk. The formula used to calculate Sharpe-ratio is given below:
Sharpe Ratio = (Rp – Rf)/ SDp
where,
The code to compute the most optimal portfolio, i.e the portfolio with the highest Sharpe Ratio is shown below:
The weights of the portfolio giving the highest Sharpe Ratio are shown below:
Find out where will the highest Sharpe Ratio point lies on the above curve ? The answer is shown below! Again, Don’t cheat!
As promised here is the answer to the above two question!
The blue star corresponds to the highest Sharpe ratio point and the yellow star corresponds to the minimum volatility point.
Now, before ending this article I encourage you to find the Maximum returns at a risk level’ and ‘Minimum Risk at an Expected Return Level’ portfolio and mark them on the graph above.
Apart from using the Sharpe Ratio, we can optimize the portfolio using the Sortino Ratio as well.
Giving a brief about it:
The Sortino ratio is a variation of the Sharpe Ratio that differentiates harmful volatility from total overall volatility by using the asset’s standard deviation of negative portfolio returns—downside deviation—instead of the total standard deviation of portfolio returns. The Sortino ratio takes an asset or portfolio’s return and subtracts the risk-free rate, and then divides that amount by the asset’s downside deviation. [Investopedia]
Sortino Ratio = (Rp – rf)/ SDd
where,
Portfolio Optimization with Modern Portfolio Theory (MPT) in Python offers a transformative journey in investment strategy refinement. By harnessing the power of MPT principles, diversification can be achieved, as advocated by Harry Markowitz, thus mitigating risk while striving for higher returns. With Python’s computational prowess and libraries such as Pandas, NumPy, and Matplotlib.pyplot (plt), investors gain invaluable insights into asset allocation and portfolio optimization. Machine learning techniques, including Monte Carlo simulation, can be employed to enhance portfolio performance by exploring optimization problems efficiently. This empowers investors to navigate dynamic financial landscapes with confidence and precision, leveraging data from platforms like Yahoo Finance for quantitative analysis. Whether it’s analyzing stock prices, constructing investment portfolios, or optimizing allocations, Python provides the necessary tools for quantitative analysis and decision-making. With a quantitative approach and true understanding of portfolio performance metrics, investors can optimize their investment portfolios effectively, maximizing returns while managing risk systematically.
A. Optimize a portfolio in Python by leveraging Modern Portfolio Theory (MPT), employing techniques such as mean-variance optimization, efficient frontier analysis, and risk management strategies for balanced asset allocation.
A. Mean-variance optimization, a key component of Modern Portfolio Theory (MPT), is widely regarded as one of the best methods for portfolio optimization, balancing risk and return effectively.
A. Markowitz’s portfolio theory in Python, part of Modern Portfolio Theory (MPT), optimizes asset allocation by maximizing returns while minimizing risk through mean-variance optimization, which is efficiently implemented using Python libraries.
A. Python facilitates portfolio management by offering data analysis, optimization, and visualization libraries. It enables tasks such as analyzing asset returns, constructing diversified portfolios, and implementing optimization algorithms efficiently.
A. In Python, construct an optimal portfolio of risky asset classes by applying Modern Portfolio Theory principles, utilizing mean-variance optimization techniques to balance risk and return effectively.
The media shown in this article is not owned by Analytics Vidhya and is used at the Author’s discretion.
This was the best & simple explanation of portfolio optimization theory and its implementation in python. Thank you for explaining theory along with graphs and formulas. Your article has helped me a lot in understanding this subject. Keep it up ! Hoping to read and learn more from your blogs.
Hi, If I am not wrong, you have used annual average returns and annual Covariance matrix for Portfolio return and volatility calculations, right ??