An optimiser is a function plus rules
scipy.optimize.minimize(fun, x0, method='SLSQP', bounds=..., constraints=...) finds the vector that makes fun smallest. You give it three kinds of information. The objective fun(w) returns a number to minimise: for a minimum-variance portfolio it is w @ cov @ w, and to maximise something you minimise its negative. The bounds are a list of (low, high) pairs, one per weight: (0, cap) means no shorting and no position above the cap. The constraints are dictionaries: {'type': 'eq', 'fun': lambda w: w.sum() - 1} forces the weights to add up to one, because an eq function must equal zero, while an ineq function must stay at or above zero. The starting point x0 matters too: equal weights is a sensible, feasible start.
Two details decide whether the answer is right. First, scale: daily variances are numbers like 0.0001, and SLSQP stops when the objective changes by less than its tolerance ftol (default 1e-6), so with raw daily numbers it can stop at the starting point without moving. Annualise the inputs (times 252) and pass options={'ftol': 1e-12, 'maxiter': 500}, and always check result.success and that the weights obey the rules. Second, the formulation: maximising the Sharpe ratio is a ratio, so minimise -(w @ mu) / sqrt(w @ cov @ w); risk parity asks for equal risk shares wᵢ(Σw)ᵢ/ wᵀΣw, so minimise the squared gaps to 1/n; and an efficient frontier is one minimum-variance problem per target return, with a second eq constraint w @ mu - target.
- Scale and tolerance: annualise the inputs and tighten
ftol, or SLSQP may stop where it started. - Check the answer: the weights must add up to one and obey the bounds; look at
result.success. - Same tool, four problems: minimum variance, a negative Sharpe ratio, equal risk shares and one problem per target return are all
minimizecalls with different objectives and constraints.
Lab · what's graded
- Annual inputs8 pts
- Return and risk of a portfolio8 pts
- Minimum variance with a cap18 pts
- Maximum Sharpe ratio18 pts
- Risk contributions10 pts
- Risk parity16 pts
- A frontier point by point10 pts
- Three portfolios12 pts