Markowitz’s Mean-Variance Model Derivation in Python
Written by Jiang Rongrong(2019E8010663001)
Interested by “Lecture 3.Quadratic Programing and Portfolio Selection Theory”,I’ve consulted a number of books about Markowitz’s Mean-Variance Model.Therefore,I want to make some discussion about what I’ve learnt and the expeirments when I tried to figure out this model.
Theory Summary
Markowitz made the following assumptions while developing the Mean-Variance Model:
- Risk of a portfolio is based on the variability of returns from the said portfolio.
- An investor is risk averse.
- An investor prefers to increase consumption.
- The investor’s utility function is concave and increasing, due to his risk aversion and consumption preference.
- Analysis is based on single period model of investment.
- An investor either maximizes his portfolio return for a given level of risk or maximizes his return for the minimum risk.
- An investor is rational in nature.
To choose the best portfolio from a number of possible portfolios, each with different return and risk, two separate decisions are to be made, detailed in the below sections:
- Determination of a set of efficient portfolios.
- Selection of the best portfolio out of the efficient set.
Above quotes from wiki
Based on above assumptions and thoughts,Markowitz establish his Mean-Variance Model as follows:
Formula:

Constraints:

notes:xi stands for the weights of asset i,ri stands for the return of asset i
Simulations
In this part ,I will try to use random data to simulate the derivation process of Mean-Variance Model.Thanks for my boyfriend’s leading,I choose python as the main tool.And each line of code is with notes if necessary.
First,initiate and import necessary util packages.
Intro of each util package:
- numpy and pandas: Matrix calculate
- matplotlib : Data plot
- cvxopt : A convex solver
1 | import numpy as np |
Assume that there are 4 assets, each with a return series of length 1000. The func numpy.random.randn is used to sample returns from a normal distribution.1
2
3
4
5
6
7
8
## NUMBER OF ASSETS
n_assets = 4
## NUMBER OF OBSERVATIONS
n_obs = 1000
return_vec = np.random.randn(n_assets, n_obs)
Plot the return series of the assumed 4 assets.1
2
3plt.plot(return_vec.T, alpha=.4);
plt.xlabel('time')
plt.ylabel('returns');

These return series can be used to create a wide range of portfolios. After that random weight vectors and plot those portfolios will be produced. As I want all my capital to be invested, the weights will have to sum to one.1
2
3
4
5
6
7def rand_weights(n):
''' Produces n random weights that sum to 1 '''
k = np.random.rand(n)
return k / sum(k)
print(rand_weights(n_assets))
print(rand_weights(n_assets))
Next, evaluate how these random portfolios would perform by calculating the mean returns and the volatility (here using standard deviation). I set a filter so that only portfolios with a standard deviation of < 2 are ploted for better illustration.
1 | def random_portfolio(returns): |
Calculate the return using
R=pTw
where R is the expected return, pT is the transpose of the vector for the mean returns for each time series and w is the weight vector of the portfolio. p is a N*1 column vector, so pT turns is a 1*N row vector which can be multiplied with the weight (column) vector w to give a scalar result.
Next, Calculate the standard deviation
sigma=sqrt(wTCw)
where C is the N*N covariance matrix of the returns.
Generate the mean returns and volatility for 500 random portfolios and plot them:1
2
3
4
5
6
7
8
9
10n_portfolios = 500
means, stds = np.column_stack([
random_portfolio(return_vec)
for _ in range(n_portfolios)
])
plt.plot(stds, means, 'o', markersize=5)
plt.xlabel('std')
plt.ylabel('mean')
plt.title('Mean and standard deviation of returns of randomly generated portfolios');

By observing the picture it can be figured out that they form a characteristic parabolic shape called the “Markowitz Bullet” whose upper boundary is called the “efficient frontier”, where investors can have the lowest variance for a given expected return.
Now the efficient frontier in Markowitz-style can be calculated. This is done by minimizing
wTCw
for fixed expected portfolio return RTw while keeping the sum of all the weights equal to 1:
sum(wi)=1 (i=1,2,3…n)
Here I parametrically run through RTw=miu and find the minimum variance for different miu‘s.
1 | def optimal_portfolio(returns): |

In yellow is the optimal portfolios for each of the desired returns (i.e. the mus). In addition, the weights for one optimal portfolio are also calculated.