Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 2

Computing Unconstrained Mean–Variance Portfolio Weights

Recommended resources

Welcome back. Previously, we derived the global minimum-variance portfolio,

which uses the covariance matrix alone and is constrained to be fully invested in risky assets. We now introduce expected excess returns and a risk-aversion parameter. This produces a different object: an unconstrained mean-variance allocation, whose total risky exposure is chosen rather than fixed.

By the end of this lesson, you will be able to derive and compute

for a specified risk-aversion coefficient , and interpret what the resulting weights mean operationally.


The mean-variance utility problem

Let:

  • be the vector of risky-asset returns over one period;
  • be the risk-free return over that period;
  • be the vector of excess returns;
  • be the vector of expected excess returns;
  • be the covariance matrix;
  • be the vector of allocations to risky assets.

The portfolio’s expected excess return and variance are

The standard mean-variance utility objective is

where is the risk-aversion coefficient.

The two terms have a direct interpretation:

  • rewards expected excess return.
  • penalizes variance.
  • Larger means variance is penalized more strongly, so the optimizer takes less risky exposure.

Here, “unconstrained” has a precise meaning: we impose no full-investment constraint such as

and no long-only or position-limit constraints. The risky weights can sum to less than, equal to, or greater than one.

When a risk-free asset is available, the residual cash allocation is

Thus, if the risky weights sum to , the investor puts in the risk-free asset. If they sum to , the investor borrows at the risk-free rate to lever the risky portfolio.

This is fundamentally different from the GMVP problem. The GMVP fixed total risky investment at ; this utility problem lets risk aversion determine the amount of capital exposed to the risky assets.

Portfolio Optimization: Mean-Variance Optimization and the Critical Line Algorithm.

Watch “Portfolio Optimization: Mean-Variance Optimization and the Critical Line Algorithm” by Hudson & Thames for a concise intuition about the return-minus-variance-penalty objective. The speaker uses \lambda rather than \gamma for the risk-aversion coefficient.

Watch utility optimization. Focus on how a higher risk-aversion coefficient increases the penalty assigned to portfolio variance; the formal derivation below makes that intuition exact.



Deriving the unconstrained optimal weights

Assume is symmetric positive definite. Then the variance term is strictly convex, so the utility function is strictly concave and has a unique maximizer.

Start from

Differentiate with respect to the weight vector:

At the optimum, the gradient is zero:

Therefore,

Multiplying by gives

This is the unconstrained mean-variance portfolio.

The first-order condition can also be read economically:

At the optimum, each asset’s expected excess return is balanced against its covariance contribution to portfolio risk, scaled by risk aversion. A high expected return alone does not guarantee a high allocation: the asset’s covariance with the whole portfolio matters.

Why this stationary point is the maximum

Define

Completing the square yields

Because is positive definite,

with equality only when . The first term is therefore never positive, establishing that uniquely maximizes utility.



Risk aversion changes scale, not the risky direction

Define the unscaled risky direction

Then

For fixed and , changing multiplies every risky position by the same scalar. It does not alter the relative composition of the risky sleeve.

If doubles, then

Consequently:

while

Expected excess return therefore declines in proportion to , but variance declines in proportion to .

A useful implication is that the Sharpe ratio of this risky direction does not depend on :

Risk aversion selects how much of this efficient risky portfolio to hold, with the remainder allocated to the risk-free asset.

The upper panel plots mean-variance utility against annualized risk for several values of \(\gamma\), with marked points indicating the highest-utility risk levels. The lower panel shows how the corresponding allocations to cash and risky assets vary with risk; lower risk aversion permits greater risky exposure and may require borrowing or leverage.

One boundary case deserves care. With , the problem becomes

If any positive-expected-excess-return direction exists and there are no constraints, the objective is unbounded: the optimizer would take arbitrarily large exposure. Thus , or practical portfolio constraints, are necessary for a finite solution.

Also, do not take the unconstrained weights and normalize them to sum to one as a general fix. Normalization changes the optimization problem: it removes the risk-free allocation decision and no longer corresponds to the specified value of .



Worked two-asset calculation

Use the covariance matrix from the previous lesson, now together with annual expected excess returns:

Suppose the investor has

The optimal risky allocation is

So the investor allocates approximately:

Position Weight
Asset 1
Asset 2
Risk-free asset

The risky weights sum to

The negative risk-free weight means borrowing at the risk-free rate to finance a allocation to the risky sleeve.

The portfolio’s expected excess return is

or about annually. Its variance is

so its volatility is approximately

If instead , all risky allocations halve:

The investor now allocates roughly to the risk-free asset. The risky sleeve has the same relative composition, but the total amount of risk taken is lower.



Reliable Python implementation

As with the GMVP, use a linear solve rather than explicitly constructing .

import numpy as np

def mean_variance_weights(excess_mu, cov, gamma):
    """
    Unconstrained mean-variance risky-asset weights.

    Parameters
    ----------
    excess_mu : array-like, shape (n_assets,)
        Expected excess returns over the same horizon as `cov`.
    cov : array-like, shape (n_assets, n_assets)
        Positive-definite covariance matrix.
    gamma : float
        Positive mean-variance risk-aversion coefficient.

    Returns
    -------
    w_risky : ndarray, shape (n_assets,)
        Risky-asset weights. Their sum need not equal one.
    """
    excess_mu = np.asarray(excess_mu, dtype=float)
    cov = np.asarray(cov, dtype=float)

    if gamma <= 0:
        raise ValueError("gamma must be strictly positive.")

    if cov.shape != (len(excess_mu), len(excess_mu)):
        raise ValueError("cov must be square and match excess_mu.")

    # Solves (gamma * Sigma) w = mu without explicitly inverting Sigma
    return np.linalg.solve(gamma * cov, excess_mu)


cov = np.array([
    [0.0225, 0.0075],
    [0.0075, 0.0625]
])

mu_excess = np.array([0.06, 0.10])
gamma = 3.0

w_risky = mean_variance_weights(mu_excess, cov, gamma)
w_cash = 1.0 - w_risky.sum()

expected_excess_return = w_risky @ mu_excess
variance = w_risky @ cov @ w_risky
volatility = np.sqrt(variance)

print("Risky weights:", w_risky)
print("Risky-weight sum:", w_risky.sum())
print("Implied cash weight:", w_cash)
print("Expected excess return:", expected_excess_return)
print("Volatility:", volatility)

# First-order-condition check: gamma * Sigma * w = mu
print("FOC holds:", np.allclose(gamma * cov @ w_risky, mu_excess))

Expected output, up to rounding:

Risky weights: [0.74074074 0.44444444]
Risky-weight sum: 1.1851851851851851
Implied cash weight: -0.18518518518518512
Expected excess return: 0.08888888888888889
Volatility: 0.17213259316477408
FOC holds: True

In a real implementation, keep several distinctions explicit:

  • Estimate as expected excess returns, not raw returns, when interpreting the residual as a risk-free allocation.
  • Use a covariance matrix estimated over the same horizon as .
  • Do not interpret independently of the return horizon and units used in estimation.
  • Treat extreme long-short positions as an output to diagnose, not necessarily a trade list to implement.


Why this matters for random-matrix portfolio methods

The mean-variance solution depends on two estimated quantities:

Thus it inherits instability from both estimated expected returns and the inverse sample covariance matrix.

The covariance component has the spectral representation

where and are sample eigenvalues and eigenvectors. Small sample eigenvalues enter through , potentially producing large and unstable portfolio tilts.

Random matrix theory will help us address the covariance part of that issue. It cannot, by itself, make expected-return estimates reliable; mean estimation is often an even more severe practical problem.



Key takeaways

  • The unconstrained mean-variance problem is
  • With and positive-definite , its unique solution is
  • The weights refer to the risky sleeve. Their sum need not equal one; the remaining allocation is cash or borrowing at the risk-free rate.
  • Raising proportionally reduces every risky position while preserving the risky sleeve’s direction.
  • In code, compute weights with np.linalg.solve(gamma * cov, excess_mu), not an explicit matrix inverse.
  • The same inverse-covariance sensitivity seen in the GMVP is present here, now combined with uncertainty in expected-return estimates.

Next, we will examine why covariance inversion specifically amplifies estimation error in low-variance sample-eigenvector directions.