Skip to content

Why Small Return Forecast Errors Move Optimal Weights So Much

Original question

Why are portfolio optimisation results so sensitive to expected return estimates, and how can I make them more robust?
Mean-variance optimisation converts differences in forecast returns into trades. When two assets have similar exposures, trading one against the other can add very little estimated variance, so even a small forecast gap can drive a large reallocation. Shrinking return forecasts, imposing economically meaningful allocation and turnover limits, and accounting for forecast uncertainty can all reduce that sensitivity.

The optimiser trades the spread between similar assets

For two assets AA and BB, let ww be the weight in AA, 1−w1-w the weight in BB, cc their covariance, and δ>0\delta>0 the variance penalty. Maximising expected return minus δ/2\delta/2 times variance gives the unrestricted interior solution
w=σB2−c+(μA−μB)/δσA2+σB2−2c.w=\frac{\sigma_B^2-c+(\mu_A-\mu_B)/\delta} {\sigma_A^2+\sigma_B^2-2c}.

The denominator is the variance of the return spread RA−RBR_A-R_B. The smaller that variance, the larger the weight response to a forecast change. If the weights must be long-only, clip this one-dimensional solution to [0,1][0,1]. With more assets, enforce the bounds inside the optimiser.

One way to incorporate uncertainty is to allow μ=μ^+V1/2z\mu=\hat\mu+V^{1/2}z for ∥z∥2≤k\lVert z\rVert_2\le k, where VV describes forecast error. The worst expected portfolio return in this set is w⊤μ^−kw⊤Vww^\top\hat\mu-k\sqrt{w^\top Vw} by Cauchy–Schwarz. Maximising this worst-case return minus a variance penalty makes allocations pay for their exposure to forecast uncertainty.

Differentiate the optimal weight with respect to the expected-return gap. The slope is the reciprocal of risk aversion times the variance of RA−RBR_A-R_B. When the assets move together, that denominator can be small. The optimiser sees a way to express the forecast gap with little incremental variance and scales up the trade. It has no way to tell whether the small gap is genuine signal or estimation noise. Bounds, a turnover penalty or shrinkage of the return forecast each address a different part of that problem.

Take two funds with annual volatility 20%, correlation 0.95 and risk aversion δ=4\delta=4. Then c=0.038c=0.038 and the spread variance is 0.0040.004. With equal expected returns the first fund receives 50%. Raise its forecast by just 0.50 percentage points and its weight rises to 81.25%. Shrink the forecast gap by 75% towards equal expected returns and its weight becomes 57.81%. A turnover penalty would further temper the response if the starting portfolio held both funds equally. The appropriate shrinkage or penalty depends on forecast validation, trading costs and how much deviation from the current allocation is acceptable.

A constraint changes how that sensitivity reaches the actual portfolio. In the example the unconstrained solution with the half-point forecast advantage moves the first weight from 50% to 81.25%. If its maximum permitted weight is 60%, the same forecast moves it only to the cap. The return signal still enters the objective, but once the cap binds additional forecast changes no longer increase that position. Compare the objective and realised risk around the cap rather than assuming that the constrained optimum inherits the same sensitivity everywhere.

Measure how the allocation reacts to forecast error

import numpy as np variance, covariance, risk_aversion = 0.04, 0.038, 4.0 forecast_gap = 0.005 def weight_in_first_fund(gap): spread_variance = 2 * (variance - covariance) optimum = (variance - covariance + gap / risk_aversion) / spread_variance return np.clip(optimum, 0.0, 1.0) for gap in [0.0, forecast_gap, 0.25 * forecast_gap]: print(f"{100 * weight_in_first_fund(gap):.2f}%")

Interactive example

See how correlation changes two-asset portfolio risk

Asset A has 15% annual volatility and asset B has 25%. Move the correlation or the long-only weight in A.

Selected portfolio volatility 15.03% · minimum-risk weight in A 80.19%
Portfolio volatility as the weight in asset A changes1520250255075100Weight in asset A (%)Annual volatility (%)
  • Portfolio volatility
  • Selected weight