Modern Portfolio Theory and Efficient Frontier
Suppose we are given two stocks, stock \(A\) and stock \(B\). We have $\(10,000\) we wish to invest. How much should we invest in each of these stocks?
In Markowitz' Portfolio Theory two important terms are used:
 Return is the change in value of a stock between two time periods, expressed in percentages. This is assumed to be random and can be negative.
 Risk is the uncertainty factor that comes with the randomness. It is mathematically defined as the deviation from the expected return: the variance. Variance and risk are often used interchangeably.
We assume that investors prefer positive returns and are risk averse.
The Theory
We are given \(n\) assets each with corresponding returns \(X_1, X_2, \ldots, X_n\), which are random variables of some unknown (joint) distribution. We denote the expected return of asset \(i\) with \(\mu_i = {\mathrm{E}}[X_i]\) and the variance \(\sigma_i^2 = {\mathrm{Var}}(X_i)\). Because we don't know what these quantities are, we estimate them using statistical estimators. The most common and simple estimator for the expectation is the sample mean based on historical data. Say we have the prices \((x_0, x_1, \ldots, x_t)\) for \(X_i\) for the days \(0,1,\ldots,t\). As a first step we compute the percentage change in prices using:
for \(j = 1,2,\ldots,t\). Then the expectation is estimated by computing the arithmetic mean on \((r_1, r_2, \ldots, r_t)\):
Similarly, we estimate the the variance of the returns by
Based on these two metrics, we may plot stocks on a meanvariance coordinate system. On the horizontal axis we have the standard deviation \(\sigma\) and on the vertical axis we have the mean \(\mu\).
As an example, consider the following graph which plots the meanvariance of several stocks using Yahoo Finance’s data from 01012014 to 12312016.
In general, stocks with high returns tend to have high risk. Ideally, we want a stock that lies high on the graph and leans far to the left, which means high return and low risk. Accordingly, if stock $A$ and stock $B$ have the same return and stock $B$ has a lower variance, then under this framework stock $B$ is more desirable.
Constructing a portfolio
Fortunately, we aren’t limited by the selection of available stocks – we may build our own portfolio from stocks. We create a portfolio of assets by giving each a weight: We take \(\mathbf{w} = (w_1, \ldots, w_n) \in {\mathbb{R}}^n\) where \(w_i\) corresponds to the weight of asset \(i\). Note that we require \(\sum_{i=1}^n w_i = 1\) for a 100% investment. Then the return of our portfolio is the transformed random variable
Its expectation is simply
and its variance
We know from statistics that for random variables \(A,B\) and scalars \(\mu, {\lambda}\)
where \({\mathrm{Cov}}(A,B)\) is the covariance between two random variables. If we write this out for our equation, we obtain
where \(\Sigma\) is the covariance matrix for \(X_1, \ldots, X_n\). The covariance matrix contains the covariances between each pair of stocks:
in which each \(\sigma_{ij}\) denotes the covariance between stock \(X_i\) and \(X_j\). Like the mean and variance, we don’t know the exact covariances and can only estimate them based on estimators.
Optimization
The question then becomes, what should each individual weight be so that our expected return is maximized and the variance minimized? This figure from Markowitz’ original paper from 1952 illustrates this well (note that the axes are swapped here):
The efficient combination of portfolios we call the efficient frontier. If your portfolio is on this frontier, then it is optimal in the sense that there is no portfolio with the same risk and higher return or with the same return and lower risk. To compute, we first find a set of expected returns \(S \subset {\mathbb{R}}\) that are attainable. Then we pick \(\mu_0 \in S\) as our desired return baseline and find weights that minimize the variance for this return level. Let \(\mathbf{r} = (\mu_1, \ldots, \mu_n)\) be the vector of expected returns, we solve:
In Python, we have scipy.optimize.minimize which handles this problem nicely.
def opt_ret(retvct, covmat, tgt): """ Find the optimal weights for tgt expected return. """ cons = ({'type': 'eq', 'fun': lambda x: np.sum(x)  1}, {'type': 'ineq', 'fun': lambda x: x}, # no short selling {'type': 'eq', 'fun': lambda x: get_stats(x, retvct, covmat)[0]  tgt}) func = lambda x: get_stats(x, retvct, covmat)[1] x0 = [1./len(retvct) for x in retvct] return minimize(func, x0, constraints=cons, method='SLSQP').x
Finally, with some additional code, we can generate the efficient frontier for our stocks:
The color marks the return/risk ratio, or the return per unit of risk. This is known as the Sharpe Ratio; however, in our case we didn't account for an interest free rate.
As a final remark, there are several practical details that are worth noting:

The standard deviation is used to express the risk, as this is in line with the unit dimension.

It is conventional to use annualized returns. If the returns are computed using daily percentage changes, then the expectation \({\mathrm{E}}[P]\) is annualized by multiplying with \(N = 252\) (amount of trading days in a year).

Similarly, the standard deviation is annualized by multiplying with \(\sqrt{N}\).

In our code, the set of attainable returns \(S\) ranges from the portfolio with the least variance to the individual asset that has the highest overall return.

The portfolio with least variance lies the most to the left; it is found by solving the above optimization problem without the first constraint (\(\mathbf{r} \cdot \mathbf{w} = \mu_0\)).

Often an additional constraint is added: each \(w_i \geq 0\), i.e., short selling is prohibited. This can make the output weights more sensible, as there won’t be extreme cases where the optimal portfolio is supposedly to have weights \(\mathbf{w} = (34.31, 17.84, 15.47)\) for stocks \(A,B\) and \(C\).

Log returns can also be used instead of simple returns:
\begin{equation*} r_t = \log(x_t)  \log(x_{t1}). \end{equation*}Its rationale is well explained in this Quantivity article.

As mentioned earlier, the true expectation and covariances are unknown; we use historical data and simple statistical estimators to estimate this. However, this approach has its shortcomings, which is further discussed in this paper.
Code for the graphs and computation can be found on Github!
Comments
Comments powered by Disqus