2 Markowitz portfolio optimization¶
In this section we introduce the Markowitz model in portfolio optimization, and discuss its different formulations and the most important input parameters.
2.1 The mean–variance model¶
Consider an investor who wishes to allocate capital among
The part of investment risk called specific risk (the risk associated with each individual security) can be reduced (for a fixed expected rate of return) through diversification, which means the selection of multiple unrelated securities into a portfolio. [1] Modern Portfolio Theory formalized this process by using variance as a measure of portfolio risk, and constructing a optimization problem.
Thus we make the investment decision at time
The expected portfolio return
The portfolio variance
Here
Using these input parameters, the MVO problem seeks to select a portfolio of securities
2.1.1 Solution of the mean–variance model¶
To be able to solve the portfolio optimization problem, we have to assume that the investor knows the value of the expected return vector
In the simplest form of the MVO problem only risky securities are considered. Also the portfolio is fully invested with no initial holdings, implying the linear equality constraint
We can formulate this portfolio optimization problem in three equivalent ways:
Minimize the portfolio risk, with the constraint expressing a lower bound on the portfolio return:
(2.1)¶Here
is the target expected return, which the investor wishes to reach. In this problem the objective function is convex quadratic, all the constraints are linear, thus it is a quadratic optimization (QO) problem. While QO problems are easy to solve, this formulation is not ideal in practice because investors might prefer specifying an upper bound on the portfolio risk instead of specifying a lower bound on the expected portfolio return.Maximize the expected portfolio return, with the constraint expressing an upper bound on the portfolio risk:
(2.2)¶In this formulation it is possible to explicitly constrain the risk measure (the variance), which makes it more practical. We can also add constraints on multiple types of risk measures more easily. However, the problem in this form is not a QO because of the quadratic constraint. We can reformulate it as a conic problem; see Sec. 2.3 (Conic formulation).
Maximize the utility function of the investor:
(2.3)¶In this case we construct the (concave) quadratic utility function
to represent the risk-averse investor’s preferred tradeoff between portfolio return and portfolio risk. This preference can be adjusted using the risk-aversion coefficient . However this parameter might not have intuitive investment meaning for the investor.We get a variant of this optimization problem by using the standard deviation instead of the variance:
(2.4)¶This form is favorable because then the standard deviation penalty term will be of the same scale as portfolio return.
Moreover, if we assume portfolio return to be normally distributed, then
has a more tangible meaning; it is the z-score [4] of portfolio return. Also, the objective function will be the -quantile of portfolio return, which is the opposite of the confidence level value-at-risk (VaR). The number comes from , where is the cumulative distribution function of the normal distribution.We can see that for
we maximize expected portfolio return. Then by increasing we put more and more weight on tail risk, i. e., we maximize a lower and lower quantile of portfolio return. This makes selection of more intuitive in practice. Note that computing quantiles is more complicated for other distributions, because in general they are not determined by only mean and standard deviation.These two problems will result in the same set of optimal solutions as the other two formulations. They also allow an easy computation of the entire efficient frontier. Maximizing problem (2.3) is again a QO, but problem (2.4) is not because of the square root. This latter problem can be solved using conic reformulation, as we will see in Sec. 2.3 (Conic formulation).
The optimal portfolio
The above introduced simple formulations are trivial to solve. Through the method of Lagrangian multipliers we can get analytical formulas, which involve
2.2 Constraints, modifications¶
In investment practice additional constraints are essential, and it is common to add linear equalities and inequalities, convex inequalities, and/or extra objective function terms to the model, which represent various restrictions on the optimal security weights.
Constraints can reflect investment strategy or market outlook information, they can be useful for imposing quality controls on the portfolio management process, or for controlling portfolio structure and avoiding inadvertent risk exposures. In these more realistic use cases however, only numerical optimization algorithms are suitable for finding the solution.
In the following, we discuss some of the constraints commonly added to portfolio optimization problems.
2.2.1 Budget constraint¶
In general we can assume that we have
has to hold. For the differences
If we do not want to keep any wealth in the risk-free security, then in addition
2.2.2 Diversification constraints¶
These constraints can help limit portfolio risk by limiting the exposure to individual positions or industries, sectors.
For a single position, they can be given in the form
For a group of securities such as an industry or sector, represented by the set
We can also create a constraint that limits the total fraction of the
where
2.2.3 Leverage constraints¶
2.2.3.1 Componentwise short sale limit¶
The simplest form of leverage constraint is when we do not allow any short selling. This is the long-only constraint stated as
We can allow some amount of short selling
2.2.3.2 Total short sale limit¶
We can also bound the total short selling by the constraint
We can rewrite this as a set of linear constraints by modeling the maximum function based on Sec. 13.1.1.1 (Maximum function) using an auxiliary vector
2.2.3.3 Collateralization requirement¶
An interesting variant of this constraint is the collateralization requirement, which limits the total of short positions to a fraction of the total of long positions. We can model it by introducing new variables
2.2.3.4 Leverage strategy¶
A leverage strategy is to do short selling, then use the proceeds to buy other securities. We can express such a strategy in general using two constraints:
, or equivalently ,
where
2.2.4 Turnover constraints¶
The turnover constraint limits the total change in the portfolio positions, which can help limiting e. g. taxes and cost of transactions.
Suppose
This nonlinear expression can be modeled as linear constraint using Sec. 13.1.1.6 (Manhattan norm (1-norm)).
2.2.5 Practical considerations¶
We can of course add many other constraints that might be imposed by regulations or arise from specific investor preferences. As long as all of these are linear or conic, the problem will not become significantly harder to solve. (See Sec. 13.1 (Conic optimization refresher) for a summary on conic constraints.)
However, we must not add too many constraints. Overconstraining a portfolio can lead to infeasibility of the optimization problem, or even if there exists a solution, out-of-sample performance of it could be poor.
Throughout this book the general notation
2.3 Conic formulation¶
We have seen that some of the portfolio optimization problems in Sec. 2.1.1 (Solution of the mean–variance model) are quadratic optimization problems. Solving QO problems in their original form is popular and considered easy, because this model was studied starting from early in history (in the 1950s), allowing it to become a well known and mature approach. However, more recent results show us that conic optimization models can improve on QO models both in the theoretical and in the practical sense. More on this in Sec. 13.1.2 (Traditional quadratic models).
In this section we will show to convert problems (2.1)-(2.4) into conic form. Assuming that the covariance matrix estimate
Even if there are no redundant securities,
Using the decomposition we can write the portfolio variance as
Modeling with rotated quadratic cone:
We can directly model the squared norm constraint
using the rotated quadratic cone as . This will give us the conic equivalent of e. g. problem (2.3):(2.7)¶Modeling with quadratic cone:
We can also consider the equivalent norm constraint
instead of the squared norm, and model it using the quadratic cone as . The conic equivalent of problem (2.3) will then look like(2.8)¶This way we can also model problem (2.4). We introduce the variable
to represent the upper bound of the portfolio standard deviation, and model the constraint using the quadratic cone as(2.9)¶While modeling problem (2.3) using the rotated quadratic cone might seem more natural, it can also be reasonable to model it using the quadratic cone for the benefits of the smaller scale and intuitive interpretation of
. This is the same as modeling of problem (2.4), which shows that conic optimization can also provide efficient solution to problems that are inefficient to solve in their original form.
In general, transforming the optimization problem into the conic form has multiple practical advantages. Solving the problem in this format will result in a more robust and usually faster and more reliable solution process. Check Sec. 13.1.2 (Traditional quadratic models) for details.
2.4 Example¶
We have seen how to transform a portfolio optimization problem into conic form. Now we will present a detailed example in MOSEK Fusion. Assume that the input data estimates
Suppose we would like to create a long only portfolio of eight stocks. Assume that we receive the following variables:
# Expected returns and covariance matrix
m = np.array(
[0.0720, 0.1552, 0.1754, 0.0898, 0.4290, 0.3929, 0.3217, 0.1838]
)
S = np.array([
[0.0946, 0.0374, 0.0349, 0.0348, 0.0542, 0.0368, 0.0321, 0.0327],
[0.0374, 0.0775, 0.0387, 0.0367, 0.0382, 0.0363, 0.0356, 0.0342],
[0.0349, 0.0387, 0.0624, 0.0336, 0.0395, 0.0369, 0.0338, 0.0243],
[0.0348, 0.0367, 0.0336, 0.0682, 0.0402, 0.0335, 0.0436, 0.0371],
[0.0542, 0.0382, 0.0395, 0.0402, 0.1724, 0.0789, 0.0700, 0.0501],
[0.0368, 0.0363, 0.0369, 0.0335, 0.0789, 0.0909, 0.0536, 0.0449],
[0.0321, 0.0356, 0.0338, 0.0436, 0.0700, 0.0536, 0.0965, 0.0442],
[0.0327, 0.0342, 0.0243, 0.0371, 0.0501, 0.0449, 0.0442, 0.0816]
])
The similar magnitude and positivity of all the covariances suggests that the selected securities are closely related. In Sec. 3.4.2 (Data collection) we will see that they are indeed from the same market and that the data was collected from a highly bullish time period, resulting in the large expected returns. Later in Sec. 5.5.1 (Single factor model) we will analyze this covariance matrix more thoroughly.
2.4.1 Maximizing return¶
We will solve problem (2.2) with an additional constraint to prevent short selling. We specify a risk level of
Recall that by the Cholesky decomposition we have
In the code, numpy
for this purpose, abbreviated here as np
.
N = m.shape[0] # Number of securities
gamma2 = 0.05 # Risk limit
# Cholesky factor of S to use in conic risk constraint
G = np.linalg.cholesky(S)
Next we define the Fusion model for problem (2.11):
with Model("MarkowitzReturn") as M:
# Decision variable (fraction of holdings in each security)
# The variable x is the fraction of holdings in each security.
# x must be positive, this imposes the no short-selling constraint.
x = M.variable("x", N, Domain.greaterThan(0.0))
# Budget constraint
M.constraint('budget', Expr.sum(x) == 1)
# Objective
M.objective('obj', ObjectiveSense.Maximize, x.T @ m)
# Imposes a bound on the risk
M.constraint('risk', Expr.vstack(gamma2, 0.5, G.T @ x),
Domain.inRotatedQCone())
# Solve optimization
M.solve()
returns = M.primalObjValue()
portfolio = x.level()
The resulting portfolio return is
2.4.2 Efficient frontier¶
In this section we compute the full efficient frontier using the same input variables. This is the easiest to do based on the formulation (2.3) by varying the delta parameter. We also prevent short selling in this case and assume no transaction costs. The optimization problem becomes
With the help of Cholesky decomposition, we can model the quadratic term
First we compute the input variable
N = m.shape[0] # Number of securities
# Cholesky factor of S to use in conic risk constraint
G = np.linalg.cholesky(S)
Next we define the Fusion model for problem (2.13):
with Model("MarkowitzFrontier") as M:
# Variables
# The variable x is the fraction of holdings in each security.
# x must be positive, this imposes the no short-selling constraint.
x = M.variable("x", N, Domain.greaterThan(0.0))
# The variable s models the portfolio variance term in the objective.
s = M.variable("s", 1, Domain.unbounded())
# Budget constraint
M.constraint('budget', Expr.sum(x) == 1)
# Objective (quadratic utility version)
delta = M.parameter()
M.objective('obj', ObjectiveSense.Maximize,
x.T @ m - delta * s)
# Conic constraint for the portfolio variance
M.constraint('risk', Expr.vstack(s, G.T @ x), Domain.inQCone())
Here we use a feature in Fusion that allows us to define model parameters. The line delta = M.parameter()
in the code does this. Defining a parameter is ideal for the computation of the efficient frontier, because it allows us to reuse an already existing optimization model, by only changing its parameter value.
To do so, we define the range of values for the risk aversion parameter
deltas = np.logspace(start=-1, stop=1.5, num=20)[::-1]
Then we will solve the optimization model repeatedly in a loop, setting a new value for the parameter
columns = ["delta", "obj", "return", "risk"] + df_prices.columns.tolist()
df_result = pd.DataFrame(columns=columns)
for d in deltas:
# Update parameter
delta.setValue(d)
# Solve optimization
M.solve()
# Save results
portfolio_return = m @ x.level()
portfolio_risk = s.level()[0]
row = pd.Series([d, M.primalObjValue(), portfolio_return,
portfolio_risk] + list(x.level()), index=columns)
df_result = df_result.append(row, ignore_index=True)
Then we can plot the results. See the risk-return plane on Fig. 2.1. We generate it by the following code:
# Efficient frontier
df_result.plot(x="risk", y="return", style="-o",
xlabel="portfolio risk (std. dev.)",
ylabel="portfolio return", grid=True)
We can observe the portfolio composition for different risk-aversion levels on Fig. 2.2, generated by
# Portfolio composition
my_cmap = LinearSegmentedColormap.from_list("non-extreme gray",
["#111111", "#eeeeee"], N=256, gamma=1.0)
df_result.set_index('risk').iloc[:, 3:].plot.area(colormap=my_cmap,
xlabel='portfolio risk (std. dev.)', ylabel="x")

Fig. 2.1 The efficient frontier.¶

Fig. 2.2 Portfolio composition
Footnotes