liveBook · Manning

Convex optimization

As explained in Build a Robo-Advisor with Python (From Scratch)

Optimization with a convex objective function and a convex feasible set, for which efficient algorithms can provide globally optimal solutions.

Convex optimization minimizes a convex objective over a convex feasible set. This combination matters because efficient algorithms can solve such problems reliably and return an optimal solution; if either the objective or feasible set is nonconvex, that guarantee disappears. section 10.1.2

Convex feasible sets let iterative methods keep moving toward improvement without being blocked by holes in the allowed region. For an unconstrained convex function of several variables, an optimum occurs where its gradient is the zero vector. Maximizing a convex function, however, is not a convex minimization problem and can make the derivative-based approach find a minimum instead. section 10.1.2

A bounded quadratic

Minimize x² − 6x + 10 subject to 4 ≤ x ≤ 10. The objective is convex and the interval is a convex feasible set, so this is a convex problem. In CVXPY, define x as a variable, specify Minimize(x ** 2 - 6 * x + 10), add the two bounds, create a Problem, solve it, and inspect x.value. section 10.1.2 section 10.1.3

CVXPY is a modeling layer: it expresses an optimization problem and passes it to a solver. Its convexity requirement is useful rather than incidental, since it avoids the fragile behavior that can arise in general-purpose methods. SciPy optimization routines can accept nonconvex inputs, but require an initial feasible guess for constrained problems and may return solutions that depend strongly on that starting point. section 10.1.3 section 10.4

Risk-parity portfolio construction

For general risk parity, choose portfolio weights w by minimizing ½wᵀΣw − γΣᵢ ln(wᵢ), where Σ is the covariance matrix and γ is positive. Both terms are convex, and setting the gradient to zero yields wᵢ(Σw)ᵢ = γ for every asset, which gives equal risk contributions. A CVXPY implementation can solve the weights and then calculate each asset’s contribution from the covariance matrix. section 11.2.2

Listing 11.3 Risk contributions of a three-asset risk-parity portfolio
import cvxpy as cp
sigma = np.matrix([[0.0225 , 0.0216 , 0.00075],   
                   [0.0216 , 0.0324 , 0.00045], 
                   [0.00075, 0.00045, 0.0025]])
N = sigma.shape[0]
w = cp.Variable(N)
gamma = 1.0
objective = cp.Minimize(0.5 * cp.quad_form(w, sigma) - gamma * sum(cp.log(w)))
constraints = []    
prob = cp.Problem(objective, constraints)
result = prob.solve()
p = w.value
risk_contribs = np.diag(p) @ sigma @ p / (p @ sigma @ p)
risk_contribs

Use the three-asset CVXPY listing to connect the convex risk-parity objective with computed portfolio risk contributions. section 11.2.2

How Build a Robo-Advisor with Python (From Scratch) covers it

How deep it goes
Defines convex objectives and feasible sets, explains gradient optimality, and derives a risk-parity objective.
Examples
Uses a bounded quadratic and a three-asset covariance-matrix risk-parity portfolio.
What you can do after
Apply it via CVXPY to formulate and solve convex portfolio optimization problems.
How it connects
Connects convexity to feasible sets, gradients, CVXPY, SciPy, portfolio optimization, and risk parity.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Build a Robo-Advisor with Python (From Scratch). The section links point to the parts of the book it draws on.