Cara menggunakan mean-variance optimal portfolio python

python finance portfolio-optimization portfolio-construction mean-variance-optimization backtesting markowitz-portfolio portfolio-management risk-measurement

  • UpdatedMay 18, 2021
  • Python

fortitudo-tech / fortitudo.tech

Star 17

  • Code
  • Issues
  • Pull requests

Investment and risk technologies maintained by Fortitudo Technologies.

investments portfolio-optimization mathematical-finance asset-allocation portfolio-construction black-litterman mean-variance-optimization portfolio-selection asset-management portfolio-allocation investment-analysis markowitz-portfolio efficient-frontier investment-management cvar cvar-optimization investment-risks entropy-pooling risk-adjusted-return market-views

  • UpdatedJan 15, 2023
  • Python

Vinci-Investments / Portfolio_optimization

Star 4

  • Code
  • Issues
  • Pull requests

Using Monte-Carlo simulation in order to find the optimal portfolio weights according to several criteras (Sharpe ratio, max drawdown, mean-variance).

optimization monte-carlo-simulation sharpe-ratio mean-variance-optimization potfolio

  • UpdatedNov 21, 2017
  • Python

hobinkwak / Portfolio-Optimization-Deep-Learning

Star 3

  • Code
  • Issues
  • Pull requests

Mean-Variance Optimization using DL (pytorch)

deep-learning pytorch portfolio-optimization mean-variance-optimization modern-portfolio-theory

  • UpdatedMar 26, 2022
  • Python

l-vicen / -WIB06772-PortfolioOptimizer

Star 3

  • Code
  • Issues
  • Pull requests

Streamlit app to simulate/optimize different portfolio allocations based on mathematical methods.

black-litterman mean-variance-optimization risk-parity

  • UpdatedJun 26, 2022
  • Python

quantumsnowball / AppleDaily20190722

Star 2

  • Code
  • Issues
  • Pull requests

portfolio mean stock stock-market variance mean-variance-optimization standard-deviation stock-market-analysis mean-variance-model mean-variance-analysis

Portfolio optimization is the process of creating a portfolio of assets, for which your investment has the maximum return and minimum risk.

Don’t worry if these terms made no sense to you, we will go over each one in detail.

2. What does a portfolio mean?

An investor’s portfolio basically is his/her investment in different kinds of assets from different companies.

For example, if you have investments in 3 companies, say, Google, Amazon and Tesla, then these 3 companies make up your investment portfolio.

But how do you invest in a company? You do so by purchasing assets of that company.

3. What are assets, returns and risk?

Assets are of various kinds. An asset is what you would purchase if you want to invest in a company.

These include, but are not limited to:

  1. Bonds
  2. Stocks
  3. Cash
  4. Real Estate

Usually when you build a portfolio, it is advisable to diversify your assets, or purchase different kinds of assets from different companies. For all assets, you will get a profit after a specified period of time. However, the profit may not be the same for each investment you make.

This profit is what we call returns.

For example, you will get returns from stocks when it’s market value goes up and similarly you will get returns from cash in form of interest.

But what if the company whose stocks you have purchased goes bankrupt?

MLPlus Industry Data Scientist Program

Do you want to learn Data Science from experienced Data Scientists?

Build your data science career with a globally recognised, industry-approved qualification. Solve projects with real company data and become a certified Data Scientist in less than 12 months. .

Cara menggunakan mean-variance optimal portfolio python

Get Free Complete Python Course

Build your data science career with a globally recognised, industry-approved qualification. Get the mindset, the confidence and the skills that make Data Scientist so valuable.

This will lead to its stocks crashing in the share market and instead of gaining profits, you will also lose your capital investment.

This is what is called risk of investment.

Another aspect of risk is the fluctuations in the asset value. For certain assets, its value is highly volatile, that is, the value increases when the market goes up, and drops accordingly. Whereas certain other assets, like bonds and certain steady stocks, are relatively more resistant to market conditions, but may give lesser returns compared to high risk ones.

A good portfolio is one which gives us maximum return on our investment for minimum risk, as discussed earlier.

The next question is, how do we decide out of an infinite possible combinations for portfolios, the one which is optimum?

4. Modern Portfolio Theory (MPT)

Modern Portfolio Theory, or also known as mean-variance analysis is a mathematical process which allows the user to maximize returns for a given risk level.

It was formulated by H. Markowitz and while it is not the only optimization technique known, it is the most widely used.

MPT assumes that all investors are risk-averse, i.e, if there is a choice between low risk and high risk portfolios with the same returns, an investor will choose one with the low risk.

So, what is the MPT all about?

MPT encourages diversification of assets. It says that a high variance asset A if combined with diverse assets B and C, where A, B and C have little to no correlation, can give us a portfolio with low variance on returns.

This is the crux of the Modern Portfolio Theory.

 

5. What is Efficient Frontier?

We know every asset in a portfolio has its own rate expected returns and risks. It is possible to create multiple combinations of assets that can provide high returns for a pre-defined risk level.

Likewise, there can be multiple portfolios that give lowest risk for a pre-defined expected return.

Efficient frontier is a graph with ‘returns’ on the Y-axis and ‘volatility’ on the X-axis. It shows the set of optimal portfolios that offer the highest expected return for a given risk level or the lowest risk for a given level of expected return.

Portfolios that lie outside the efficient frontier are sub-optimal because they do not provide either enough return for the level of risk or have a higher risk for the defined rate of return.

We will revisit this with an example again.

Now that you understand the term of portfolio optimization, let’s see how its actually implemented.

6. Fundamental terms in portfolio optimization

There are some statistical terms required in optimization process without which an optimal portfolio can’t be defined. Don’t worry, I will simplify it and make it easy and clear.

We will go through each one through an example.

In this example, we are considering a portfolio made up of stocks from just 2 companies, Tesla and Facebook.

Step 1: Pull the stock price data

The first step is to is to pull the required data from a verified site such as Yahoo or Quandl. The example below uses Yahoo and the dates for which we will be pulling the data is from 1st January, 2018 to 31st December, 2019.

# Load Packages
import numpy as np
import pandas as pd
from pandas_datareader import data
import matplotlib.pyplot as plt
%matplotlib inline

Let’s import the data.

# Read Data
test = data.DataReader(['TSLA', 'FB'], 'yahoo', start='2018/01/01', end='2019/12/31')
test.head()

Cara menggunakan mean-variance optimal portfolio python

As you can see, there are a lot of different columns for different prices throughout the day, but we will only focus on the ‘Adj Close’ column. This colum gives us the closing price of company’s stock on the given day.

# Closing price
test = test['Adj Close']
test.head()

SymbolsTSLAFBDate2018-01-0264.106003181.4199982018-01-0363.450001184.6699982018-01-0462.924000184.3300022018-01-0563.316002186.8500062018-01-0867.281998188.279999

Step 2: Calculate percentage change in stock prices

Next, we calculate the percentage change in stock prices of tesla everyday. You will notice that that we take the log of percentage change.

But take log?

The reason for this is that log of the returns is time additive.

That is,
If

Date
2018-01-02         NaN
2018-01-03   -0.010286
2018-01-04   -0.008325
2018-01-05    0.006210
2018-01-08    0.060755
Name: TSLA, dtype: float64
7 is the returns for time between t3 and t1.
Date
2018-01-02         NaN
2018-01-03   -0.010286
2018-01-04   -0.008325
2018-01-05    0.006210
2018-01-08    0.060755
Name: TSLA, dtype: float64
8 is the returns between t1 and t2 and
Date
2018-01-02         NaN
2018-01-03   -0.010286
2018-01-04   -0.008325
2018-01-05    0.006210
2018-01-08    0.060755
Name: TSLA, dtype: float64
9 is the returns between t2 and t3.

Then, log(r13) = log(r12) + log(r23)

For example:,
If

# Variance
var_tesla = tesla.var()
var_tesla
0,
# Variance
var_tesla = tesla.var()
var_tesla
1 and
# Variance
var_tesla = tesla.var()
var_tesla
2,
where
# Variance
var_tesla = tesla.var()
var_tesla
3 is price of stock in time 1

Then:

# Variance
var_tesla = tesla.var()
var_tesla
4,

# Variance
var_tesla = tesla.var()
var_tesla
5 and

# Variance
var_tesla = tesla.var()
var_tesla
6, which is same as
# Variance
var_tesla = tesla.var()
var_tesla
7.

This means a log change of +0.1 today and then -0.1 tomorrow will give you the same value of stock as yesterday. This is not true if you simply compute percentage change.

It is common practice in portfolio optimization to take log of returns for calculations of covariance and correlation.

# Log of percentage change
tesla = test['TSLA'].pct_change().apply(lambda x: np.log(1+x))
tesla.head()
Date
2018-01-02         NaN
2018-01-03   -0.010286
2018-01-04   -0.008325
2018-01-05    0.006210
2018-01-08    0.060755
Name: TSLA, dtype: float64

Variance

The variance in prices of stocks of Tesla are an important indicator of how volatile this investment will be (how returns can fluctuate).

It can be calculated for each company by using built in

# Variance
var_tesla = tesla.var()
var_tesla
8 function. Under the hood, the formula implemented by this function is given by:

$$ s^2 = \sum_{i=1}^N (x_i – \bar{x})^2 / N-1 $$

# Variance
var_tesla = tesla.var()
var_tesla
0.0011483734269334596

Similarly for Facebook,

# Log of Percentage change for Facebook
fb = test['FB'].pct_change().apply(lambda x: np.log(1+x))
fb.head()
Date
2018-01-02         NaN
2018-01-03    0.017756
2018-01-04   -0.001843
2018-01-05    0.013579
2018-01-08    0.007624
Name: FB, dtype: float64

The variance is:

# Variance
var_fb = fb.var()
var_fb
#> .00045697258417022536

Volatility

Volatility is measured as the standard deviation of a company’s stock.

If you carefully look at the formula for standard deviation, you will understand that it is just the square root of variance.

$$ s = \sqrt{ \sum_{i=1}^N (x_i – \bar{x})^2 / N-1} $$

But volatility for the annual standard deviation. What we get from square root of variance is the daily standard deviation. To convert it to annual standard deviation we multiply the variance by 250.

250 is used because there are 250 trading days in a year.

# Read Data
test = data.DataReader(['TSLA', 'FB'], 'yahoo', start='2018/01/01', end='2019/12/31')
test.head()
0

We can plot the volatility of both Tesla and Facebook for better visualization.

# Read Data
test = data.DataReader(['TSLA', 'FB'], 'yahoo', start='2018/01/01', end='2019/12/31')
test.head()
1
# Read Data
test = data.DataReader(['TSLA', 'FB'], 'yahoo', start='2018/01/01', end='2019/12/31')
test.head()
2

Covariance

Covariance measures the directional relationship between the returns on two assets.

A positive covariance means that returns of the two assets move together while a negative covariance means they move inversely. Risk and volatility can be reduced in a portfolio by pairing assets that have a negative covariance.

We can calculate the covariance of Tesla and Facebook by using the

# Variance
var_tesla = tesla.var()
var_tesla
9 function.

# Read Data
test = data.DataReader(['TSLA', 'FB'], 'yahoo', start='2018/01/01', end='2019/12/31')
test.head()
3

SymbolsTSLAFBDate2018-01-02NaNNaN2018-01-03-0.0102860.0177562018-01-04-0.008325-0.0018432018-01-050.0062100.0135792018-01-080.0607550.007624

# Read Data
test = data.DataReader(['TSLA', 'FB'], 'yahoo', start='2018/01/01', end='2019/12/31')
test.head()
4

You can notice that there is small positive covariance between Tesla and Facebook.

Correlation

Correlation, in the finance and investment industries, is a statistic that measures the degree to which two securities move in relation to each other. Correlations are used in advanced portfolio management, computed as the correlation coefficient, which has a value that must fall between -1.0 and +1.0.

You can think of correlation as a scaled version of covariance, where the values are restricted to lie between -1 and +1.

A correlation of -1 means negative relation, i.e, if correlation between Asset A and Asset B is -1, if Asset A increases, Asset B decreases.

A correlation of +1 means positive relation, i.e, if correlation between Asset A and Asset B is 1, if Asset A increases, Asset B increases.

A correlation of 0 means no relation, i.e, if correlation between Asset A and Asset B is 0, they dont have any effect on each other.

This is calculated using the

0.0011483734269334596
0 function.

# Read Data
test = data.DataReader(['TSLA', 'FB'], 'yahoo', start='2018/01/01', end='2019/12/31')
test.head()
5

In line with the covariance, the correlation between Tesla and Facebook is also positive.

Expected Returns

Expected returns of an asset are simply the mean of percentage change in its stock prices. So, the value of expected return we obtain here are daily expected returns.

For an yearly expected return value, you will need to resample the data year-wise, as you will see further.

For expected returns, you need to define weights for the assets choosen.

In simpler terms, this means you need to decide what percentage of your total money to you want to hold in each company’s stock.

Usually this decision is done by using the optimization techniques we will discuss later but for now we will consider random weights for Tesla and Facebook.

First, let’s compute the log of percentage change.

# Read Data
test = data.DataReader(['TSLA', 'FB'], 'yahoo', start='2018/01/01', end='2019/12/31')
test.head()
6

SymbolsTSLAFBDate2018-01-02NaNNaN2018-01-03-0.0102860.0177562018-01-04-0.008325-0.0018432018-01-050.0062100.0135792018-01-080.0607550.007624

Weights

Let’s define an array of random weights for the purpose of calculation. These weights will represent the percentage allocation of investments between these two stocks. They must add up to 1.

So, the problem of portfolio optimization is nothing but to find the optimal values of weights that maximizes expected returns while minimizing the risk (standard deviation).

# Read Data
test = data.DataReader(['TSLA', 'FB'], 'yahoo', start='2018/01/01', end='2019/12/31')
test.head()
7
# Read Data
test = data.DataReader(['TSLA', 'FB'], 'yahoo', start='2018/01/01', end='2019/12/31')
test.head()
8

The total expected return for a portfolio is given by:

$$ E(R_p) = w_1E(R_1) + w_2E(R_2) + ….. w_nE(R_n)$$

Thus,

0.0011483734269334596
1, or total expected return can be calculated as:

# Read Data
test = data.DataReader(['TSLA', 'FB'], 'yahoo', start='2018/01/01', end='2019/12/31')
test.head()
9

7. Building an optimal risky portfolio

Now that you have gone through the building blocks of portfolio optimization, it is time to create an optimal portfolio using the same concepts.

We will be using stocks from 4 companies, namely, Apple, Nike, Google and Amazon for a period of 5 years.

You will learn to calculate the weights of assets for each one. Then, we will calculate the expected returns, minimum variance portfolio, optimal risky portfolio and efficient frontier. You will also learn a new term called Sharpe Ratio.

Let’s get started by pulling the required asset data from Yahoo.

# Closing price
test = test['Adj Close']
test.head()
0

Just like earlier, we will only keep the ‘Adj Close’ column to perform our calculations.

# Closing price
test = test['Adj Close']
test.head()
1

SymbolsAAPLNKEGOOGLAMZNDate2014-12-3125.18104444.454605530.659973310.3500062015-01-0224.94150243.936787529.549988308.5199892015-01-0524.23885743.229393519.460022302.1900022015-01-0624.24114642.975098506.640015295.2900092015-01-0724.58106043.862804505.149994298.420013

8. Covariance and Correlation matrix

The first step is to obtain a covariance and correlation matrix to understand how different assets behave with respect to each other. When we had a 2 asset portfolio, we directly plugged in the names of the assets into

# Variance
var_tesla = tesla.var()
var_tesla
9 and
0.0011483734269334596
0 functions.

In this case, we will need a matrix for better visualisation. This is also achieved by using the same 2 functions on our dataframe

0.0011483734269334596
4.

Note that we perform necessary operations to display log change in prices of stocks each day.

# Closing price
test = test['Adj Close']
test.head()
2

SymbolsAAPLNKEGOOGLAMZNSymbolsAAPL0.0002450.0000840.0001220.000142NKE0.0000840.0002190.0000850.000092GOOGL0.0001220.0000850.0002210.000176AMZN0.0001420.0000920.0001760.000333

The covariance between Apple and Apple, or Nike and Nike is the variance of that asset.

The next step is to create the correlation matrix. Correlation ranges from -1 to 1.

  • A correlation of -1 means negative relation, i.e, if correlation between Asset A and Asset B is -1, if Asset A increases, Asset B decreases.
  • A correlation of +1 means positive relation, i.e, if correlation between Asset A and Asset B is 1, if Asset A increases, Asset B increases.
  • A correlation of 0 means no relation, i.e, if correlation between Asset A and Asset B is 0, they dont have any effect on each other.
# Closing price
test = test['Adj Close']
test.head()
3

SymbolsAAPLNKEGOOGLAMZNSymbolsAAPL1.0000000.3611450.5248180.496704NKE0.3611451.0000000.3875320.341431GOOGL0.5248180.3875321.0000000.647952AMZN0.4967040.3414310.6479521.000000

As you can see, an asset always has a perfectly positive correlation of 1 with itself.

9. Portfolio Variance

The formula for calculating portfolio variance differs from the usual formula of variance. It looks like this:

$$\sigma^2(Rp) = \sum{i=1}^{n} \sum_{j=1}^{n} w_i w_j COV(R_i, R_j) $$

Here, wi and wj denote weights of all assets from 1 to n (in our case from 1 to 4) and COV(Ri, Rj) is the covariance of the two assets denoted by i and j.

The simplest way to do this complex calculation is defining a list of weights and multiplying this list horizontally and vertically with our covariance matrix.

For this purpose, let’s define a random list of weights for all 4 assets. Remember that sum of weights should always be 1.

# Closing price
test = test['Adj Close']
test.head()
4
# Closing price
test = test['Adj Close']
test.head()
5

Thus we have found the portfolio variance. But for truly optimizing the portfolio, we cant plug in random weights. We will need to calculate it according to what gives us maximum expected returns.

How will you find the portfolio expected return?

9. Portfolio expected returns

The mean of returns (given by change in prices of asset stock prices) give us the expected returns of that asset.
The sum of all individual expected returns further multiplied by the weight of assets give us expected return for the portfolio.

Note that we use the

0.0011483734269334596
5 function to get yearly returns. The argument to function, ‘Y’, denotes yearly.
If we dont perform resampling, we will get daily returns, like you saw earlier in the ‘Fundamental Terms’ section.

# Closing price
test = test['Adj Close']
test.head()
6

Output:

# Closing price
test = test['Adj Close']
test.head()
7

Portfolio returns

# Closing price
test = test['Adj Close']
test.head()
8
# Closing price
test = test['Adj Close']
test.head()
9

Plotting the efficient frontier

This is the aim of going through all the topics above, to plot the efficient frontier. Efficient frontier is a graph with ‘returns’ on the Y-axis and ‘volatility’ on the X-axis. It shows us the maximum return we can get for a set level of volatility, or conversely, the volatility that we need to accept for certain level of returns.

The plot of efficient frontier looks something like this:

Cara menggunakan mean-variance optimal portfolio python

Below, you can see the calculations and code for finding the optimal weights of assets and plotting the efficient frontier for given portfolio.
But first, lets take a look at the volatiltilty and returns of individual assets for a better understanding.

# Log of percentage change
tesla = test['TSLA'].pct_change().apply(lambda x: np.log(1+x))
tesla.head()
0
# Log of percentage change
tesla = test['TSLA'].pct_change().apply(lambda x: np.log(1+x))
tesla.head()
1
# Log of percentage change
tesla = test['TSLA'].pct_change().apply(lambda x: np.log(1+x))
tesla.head()
2

ReturnsVolatilitySymbolsAAPL0.2829970.247734NKE0.1959500.233798GOOGL0.2175450.235191AMZN0.4722890.288559

Amazon has the maximum risk attached but it also offers the maximum returns. Apple lies somewhere in the middle, with average risk and return rates.

Next, to plot the graph of efficient frontier, we need run a loop. In each iteration, the loop considers different weights for assets and calculates the return and volatility of that particular portfolio combination.

We run this loop a 1000 times.

To get random numbers for weights, we use the

0.0011483734269334596
6 function. But remember that the sum of weights must be 1, so we divide those weights by their cumulative sum.
Keep reading further to see how it’s done.

# Log of percentage change
tesla = test['TSLA'].pct_change().apply(lambda x: np.log(1+x))
tesla.head()
3
# Log of percentage change
tesla = test['TSLA'].pct_change().apply(lambda x: np.log(1+x))
tesla.head()
4
# Log of percentage change
tesla = test['TSLA'].pct_change().apply(lambda x: np.log(1+x))
tesla.head()
5
# Log of percentage change
tesla = test['TSLA'].pct_change().apply(lambda x: np.log(1+x))
tesla.head()
6

ReturnsVolatilityAAPL weightNKE weightGOOGL weightAMZN weight00.2886560.1951910.1309620.3091400.2881930.27170510.2594400.1911030.1998910.2697290.3944120.13596820.3424420.2091050.2042570.2311460.1072000.45739730.2904960.1947980.2644600.2298820.2677490.23790940.2941590.1960930.1265960.4536890.1130330.306682

You can see that there are a number of portfolios with different weights, returns and volatility. Plotting the returns and volatility from this dataframe will give us the efficient frontier for our portfolio.

# Log of percentage change
tesla = test['TSLA'].pct_change().apply(lambda x: np.log(1+x))
tesla.head()
7
# Log of percentage change
tesla = test['TSLA'].pct_change().apply(lambda x: np.log(1+x))
tesla.head()
8

How to read the Efficient Frontier?

Each point on the line (left edge) represents an optimal portfolio of stocks that maximises the returns for any given level of risk.

The point (portfolios) in the interior are sub-optimal for a given risk level. For every interior point, there is another that offers higher returns for the same risk.

On this graph, you can also see the combination of weights that will give you all possible combinations:

  1. Minimum volatility (left most point)
  2. Maximum returns (top most point)

And everything in between.

# Log of percentage change
tesla = test['TSLA'].pct_change().apply(lambda x: np.log(1+x))
tesla.head()
9
Date
2018-01-02         NaN
2018-01-03   -0.010286
2018-01-04   -0.008325
2018-01-05    0.006210
2018-01-08    0.060755
Name: TSLA, dtype: float64
0

The minimum volatility is in a portfolio where the weights of Apple, Nike, Google and Amazon are 26%, 39%, 30% and 4% respectively. This point can be plotted on the efficient frontier graph as shown:

Date
2018-01-02         NaN
2018-01-03   -0.010286
2018-01-04   -0.008325
2018-01-05    0.006210
2018-01-08    0.060755
Name: TSLA, dtype: float64
1
Date
2018-01-02         NaN
2018-01-03   -0.010286
2018-01-04   -0.008325
2018-01-05    0.006210
2018-01-08    0.060755
Name: TSLA, dtype: float64
2

The red star denotes the most efficient portfolio with minimum volatility.

It is worthwhile to note that any point to the right of efficient frontier boundary is a sup-optimal portfolio.

We found the portfolio with minimum volatility, but you will notice that the return on this portfolio is pretty low. Any sensible investor wants to maximize his return, even if it is a tradeoff with some level of risk.

The question arises that how do we find this optimal risky portfolio and finally optimize our portfolio to the maximum?

This is done by using a parameter called the Sharpe Ratio.

Sharpe Ratio

The ratio is the average return earned in excess of the risk-free rate per unit of volatility or total risk. Volatility is a measure of the price fluctuations of an asset or portfolio.

The risk-free rate of return is the return on an investment with zero risk, meaning it’s the return investors could expect for taking no risk.

The optimal risky portfolio is the one with the highest Sharpe ratio. The formula for this ratio is:

Cara menggunakan mean-variance optimal portfolio python

Below is the code for finding out portfolio with maximum Sharpe Ratio. This portfolio is the optimized portfolio that we wanted to find. We define the risk-free rate to be 1% or 0.01.