### Exploring Efficient Frontier and optimizing investment portfolios with Python

# Introduction

In the world of finance, maximizing returns while minimizing risk is a key objective for investors. Achieving this delicate balance requires a solid understanding of Modern Portfolio Theory (MPT), a groundbreaking concept introduced by Nobel laureate Harry Markowitz. In this blog, we will demystify MPT for individuals with little to no finance knowledge, delve into the concept of Efficient Frontier, and explore how MPT is applied in today’s dynamic investment landscape. In the end, we will apply our learning, build a portfolio and optimize it using Python.

# Modern Portfolio Theory

Modern Portfolio Theory is a framework that seeks to optimize investment portfolios by considering the relationship between risk and return. At its core, MPT recognizes that by diversifying investments across different assets, investors can achieve higher returns for a given level of risk, or conversely, reduce risk for a desired level of return. The two key factors that play a pivotal role are diversification and asset correlation.

**Diversification**

Diversification is the cornerstone of MPT. It involves spreading investments across a variety of asset classes, such as stocks, bonds, commodities, and real estate, rather than putting all eggs in one basket. The rationale behind diversification is that different asset classes behave differently under various market conditions, and by combining them, the overall portfolio risk can be reduced.

**Role of asset correlation**

Asset correlation plays a vital role in diversification. Correlation measures the degree to which two or more assets move in relation to each other. If assets have a low or negative correlation, their price movements tend to be independent, reducing the overall portfolio risk. Conversely, assets with a high positive correlation move in tandem, increasing the portfolio risk.

# What is an Efficient Frontier?

Later in this blog, we will build a few thousand portfolios to arrive at the most optimal weights for the stocks in the portfolio. Once we build the portfolio, there will be a set of portfolios that would give higher returns either for a defined level of risk or minimum risk. The MPT theory graphically represents the distribution of portfolios that maximize the returns for defined risk.

The curve in the Efficient Frontier graph shows the benefits of diversification and the portfolio’s risk-to-reward trade-off. The optimal portfolio is the one with the highest return for reasonable (acceptable) risk. An investor with a high-risk appetite would incline towards the right side of the curve with high risk and conservative ones would prefer to be on the left side of the frontier with lesser risk. All the portfolios that fall on the frontier line are efficient and any portfolio that is either below or above is not optimal because they offer either a lesser return for the same risk or a higher risk for the same return. Our objective will be to create an Efficient Frontier chart and find a combination of weights for each stock to build an optimal portfolio.

# What is a Sharpe Ratio?

The Sharpe ratio (also known Sharpe index) is a ratio to measure the performance of an investment such as a portfolio. It was proposed by William Sharpe in 1966 as a ratio that is a difference in the returns on the portfolio and risk-free rate to the volatility of the portfolio. The risk-free return is the theoretical return that has zero risk or it can be an industry benchmark eg: government bonds etc where risk is minimal or close to zero. It helps us determine how much the excess return is for a unit of volatility. In short, the higher Sharpe ratio indicates that for a lower risk, the portfolio had higher returns. In this blog, we assume the risk-free rate to be zero.

Sharpe Ratio = (Rₚ — Rₑ) / SDₚ

Rₚ = return of the portolio

Rₑ = risk-free returns

SDₚ = Standard deviation of the portfolio

# Implementing MPT in Python

In the realm of implementing Modern Portfolio Theory (MPT), we have the advantage of utilizing various tools and libraries in Python. One such powerful library is pyportfolioopt, which simplifies the implementation process by providing built-in functionalities that automatically generate the necessary metrics.

By incorporating pyportfolioopt, we gain access to a comprehensive set of features that streamline the MPT implementation. This library allows us to effortlessly calculate key portfolio metrics such as expected returns, volatility, and correlation coefficients. Additionally, it offers convenient functions to generate efficient frontiers, identify optimal portfolios, and compute the Sharpe ratio.

However, if you prefer a more customized approach or want to delve deeper into the implementation details, basic Python libraries such as pandas, numpy, and matplotlib are more than sufficient. These fundamental libraries provide essential functionalities for data manipulation, mathematical calculations, and data visualization. With them, you can create your own MPT implementation, tailor it to your specific needs, and gain a deeper understanding of the underlying concepts.

If you wish to implement entire portfolio optimization logic using sharpe ratio from scratch, please refer How To Use Sharpe Ratio To Optimize And Balance Financial Portfolio

**Step 1: Installing and importing dependencies**

import pandas as pd

import yfinance as yf

import copy

import seaborn as sb

import matplotlib.pyplot as plt

from pypfopt import EfficientFrontier

from pypfopt import plotting

from pypfopt import risk_models, expected_returns

**Step 2: Gathering financial data**

We will use yahoo finance to download the data for the stocks selected.

tickers = ['AAPL', 'GOOGL', 'MSFT', 'AMZN', 'TSLA']

prices = yf.download(tickers, start='2018-01-01', end='2023-01-01')['Adj Close']

**Step 3: Correlation between stocks**

To keep it simple, our portfolio is mostly IT stocks. Ideally, a portfolio will have stocks across sectors/industries.

import seaborn as sb

plt.style.use('ggplot')

fig = plt.figure()

sb.heatmap(S,xticklabels=S.columns, yticklabels=S.columns,

cmap='RdBu_r', annot=True, linewidth=0.5)

print('Covariance between daily simple returns of stocks in your portfolio')

plt.show(fig)

**Step 4: Calculating key metrics and optimized weights**

The below few lines of code calculate the historical mean returns, covariance matrix, and weights based on the Sharpe ratio. The annual return turns out to be 28.3% and the Sharpe ratio is 0.81 (*Sharpe ratio > 1 is considered to be good*)

mu = expected_returns.mean_historical_return(prices)

S = risk_models.sample_cov(prices)

ef = EfficientFrontier(mu, S)

weights = ef.max_sharpe()

cleaned_weights = ef.clean_weights()

print(cleaned_weights)

ef.portfolio_performance(verbose=True)

OUTPUT:

OrderedDict([('AAPL', 0.38147), ('AMZN', 0.0), ('GOOGL', 0.0),

('MSFT', 0.42793), ('TSLA', 0.1906)])

Expected annual return: 28.3%

Annual volatility: 32.6%

Sharpe Ratio: 0.81

(0.28340331802717283, 0.325525373351676, 0.8091637076247491)

**Step 5: Calculating discreet allocation**

After obtaining the weights for each stock in the portfolio, we can proceed to determine the allocation of funds based on those weights. For instance, let’s assume we have $100,000 available for investment. To calculate the discrete allocation, we can utilize the DiscreteAllocation method, which allocates the funds to individual stocks based on their respective weights. This approach ensures that the investment is distributed according to the desired portfolio composition.

from pypfopt.discrete_allocation import DiscreteAllocation, get_latest_prices

latest_prices = get_latest_prices(prices)

da = DiscreteAllocation(weights, latest_prices, total_portfolio_value=100000)

allocation, leftover = da.greedy_portfolio()

print("Discrete allocation:", allocation)

print("Funds remaining: ${:.2f}".format(leftover))

OUTPUT:

Discrete allocation: {'MSFT': 179, 'AAPL': 294, 'TSLA': 155}

Funds remaining: $91.48

# Visualize the Efficient Frontier and max Sharpe Ratio Portfolio

The following code snippet, taken from the documentation, allows you to visually represent various aspects of your stock portfolios. By generating 1000 portfolios with randomly assigned weights, the code plots their corresponding returns and volatility. Additionally, it displays the efficient frontier and identifies the portfolio with the maximum Sharpe ratio. This visualization provides valuable insights into the risk-return tradeoff and helps you make informed investment decisions.

def plot_efficient_frontier_and_max_sharpe(mu, S):

# Optimize portfolio for maximal Sharpe ratio

ef = EfficientFrontier(mu, S)

fig, ax = plt.subplots(figsize=(8,6))

ef_max_sharpe = copy.deepcopy(ef)

plotting.plot_efficient_frontier(ef, ax=ax, show_assets=False)

# Find the max sharpe portfolio

ef_max_sharpe.max_sharpe(risk_free_rate=0.02)

ret_tangent, std_tangent, _ = ef_max_sharpe.portfolio_performance()

ax.scatter(std_tangent, ret_tangent, marker="*", s=100, c="r", label="Max Sharpe")

# Generate random portfolios

n_samples = 1000

w = np.random.dirichlet(np.ones(ef.n_assets), n_samples)

rets = w.dot(ef.expected_returns)

stds = np.sqrt(np.diag(w @ ef.cov_matrix @ w.T))

sharpes = rets / stds

ax.scatter(stds, rets, marker=".", c=sharpes, cmap="viridis_r")

# Output

ax.set_title("Efficient Frontier with Random Portfolios")

ax.legend()

plt.tight_layout()

plt.show()

plot_efficient_frontier_and_max_sharpe(mu, S)

If you wish to implement entire portfolio optimization logic usinf sharpe ratio from scratch, please refer How To Use Sharpe Ratio To Optimize And Balance Financial Portfolio

**Application of Modern Portfolio Theory**

Modern Portfolio Theory has revolutionized the investment landscape and is widely applied in today’s financial world. Here are a few notable applications:

**Asset Allocation**: MPT guides investors in determining the optimal allocation of their investment capital across different asset classes based on their risk tolerance, time horizon, and investment goals.

**Risk Management**: MPT aids in managing risk by identifying the level of diversification required to reduce portfolio volatility. It helps investors navigate through uncertain market conditions and mitigate potential losses.

**Portfolio Optimization**: MPT employs advanced mathematical models and algorithms to optimize portfolios by maximizing returns for a given level of risk or minimizing risk for a desired level of return. It takes into account historical data, asset correlations, and risk measures to construct efficient portfolios.

# Conclusion

Modern Portfolio Theory, with its cornerstone of diversification and the powerful concept of the Efficient Frontier, offers a robust framework for optimizing investment portfolios. By understanding the principles of MPT, investors can strive to strike a balance between risk and return, achieve efficient portfolios, and navigate the dynamic world of finance with confidence. As financial markets continue to evolve, the principles of MPT will remain invaluable in helping investors make informed decisions and pursue their long-term financial goals.

I hope you liked the article and found it helpful.

You can connect with me — on ** Linkedin** and

*Github*# Disclaimer

The blog is only educational and should not be used as professional advice for real-world financial decisions.