Learning objectives
By the end you can:
- Implement mean-variance optimization end to end in code: build an n-asset covariance matrix from volatilities and a correlation matrix, validate it is positive semi-definite before trusting anything downstream of it, and compute the global minimum-variance (GMV) and unconstrained tangency portfolios from closed-form linear algebra: reproducing AA1.01's own hand-verified numbers to the decimal.
- Add real constraints via
scipy.optimize.minimize: turn a mandate's actual rules (long-only, a single-asset cap, a sector or liquidity ceiling, a hard exclusion) into bounds and constraints on a numerical Sharpe-maximization, and quantify the Sharpe ratio a specific constraint costs relative to the unconstrained optimum. - Prove, numerically and in your own code, that unconstrained MVO is an "estimation-error maximizer" (Best & Grauer 1991; Michaud 1989): perturb one expected-return assumption by an amount smaller than any honest confidence interval around it, and reproduce a ten-plus-point weight swing and a sign flip, while the portfolio's own Sharpe ratio moves almost nothing.
- Implement Black-Litterman in code: reverse-optimize the market-implied equilibrium return vector from benchmark weights and a risk-aversion coefficient, blend in a single stated view via the closed-form posterior, verify the no-view identity that catches a broken build, and contrast the resulting portfolio against one built from noisy trailing-mean history on the identical asset menu.
- Implement risk parity in code: compute marginal and percent contribution to risk for any weight vector, implement the two-asset closed form, and implement the N-asset iterative solver that a naive inverse-volatility shortcut cannot replace once three or more assets carry genuinely different pairwise correlations.
- Implement and diagnose a second, independent way naive optimizers blow up: estimate a covariance matrix from a short real return history two different ways (the raw sample covariance and a Ledoit-Wolf shrinkage estimate) and show, numerically, that GMV weights built from the raw estimate swing far more across two different short windows of the same real menu than weights built from the shrunk estimate.
- State precisely what this module owns versus what AA1.01/AA1.02 own: the theory, the derivations, and the by-hand verification of every formula below belong to AA1.01 and AA1.02 (Finance-Plus Ring); this module never re-derives them, it implements, validates, hardens, and stress-tests them in running code.
- Know honestly what this program's runtime can and cannot run: name
cvxpyas a real production tool this module's runtime cannot execute, and explain whyscipy.optimizeplus closed forms are the substitute here, not a downgrade in understanding. - (Productivity objective: R10 duality.) Use an AI coding assistant to accelerate drafting an optimization scaffold, the matrix algebra, the
scipy.optimizeboilerplate, for a task you can already solve and verify yourself, and catch the specific, silent ways AI-generated numerical code goes wrong: a transposed matrix, a missing constraint, a flipped objective sign, a covariance estimator applied with the wrongrowvaraxis.
The duality, stated once (R10). As in every module in this program, this node carries two objectives at once. The understanding objective (items 1–8) is what the mastery gate rewards: you earn the pass by implementing each function yourself, clearing its hidden tests, and being able to explain in your own words why each demonstration comes out the way it does. The productivity objective (item 9) is the payoff you keep afterward: knowing how to point a copilot at optimization code without being quietly misled by it. A tool can never buy you a pass on the gate; QD1.04-e04 and QD1.04-e08's
choose-implstructured fallbacks are built from exactly the bugs a fluent-but-wrong AI-generated answer tends to contain.