A constraint restricts the choices an optimizer may consider. Rather than selecting any variable value that improves an objective, optimization must select a feasible value or portfolio that satisfies stated bounds and relationships. Constraints can move an optimum to a boundary, so setting a derivative or gradient to zero is not enough to solve a constrained problem. section 10.1.1
A bounded scalar problem
For f(x) = x² − 6x + 10, the unconstrained minimum occurs at x = 3. If x must lie in [4, 7], x = 3 is infeasible and the minimum is x = 4. If x lies in [0, 5] and the goal is maximization, the stationary point x = 3 is not the answer; the maximum occurs at endpoint x = 0. section 10.1.1
Figure 10.1 Plot of the function \(x^2 - 6x + 10\)
The curve makes clear why a stationary point and a feasible optimum can differ once an interval limits x. section 10.1.1
In portfolio construction, constraints encode practical requirements alongside an objective such as maximizing expected return. Common forms include nonnegative weights, upper bounds on individual positions, relative-weight bounds, benchmark-relative allocations, tracking-error limits, and total-deviation limits. A maximum position size can diversify a portfolio, but combinations of constraints can make the feasible set empty. section 10.2.2 section 10.3.2
A constraint can express several portfolio controls:
- Cap an individual position with wᵢ ≤ uᵢ, or cap every weight through the infinity norm of the weight vector. section 10.2.2
- Keep two asset weights within ratio or difference bounds to prevent them from drifting too far apart. section 10.2.2
- Keep allocations near benchmark weights within an allowed tolerance for an asset subset. section 10.3.2
- Limit tracking error or total deviation from a reference portfolio. section 10.2.2
cvxpy models an objective and a list of constraints, then passes the resulting problem to a solver. It requires convex objectives and constraints; nonconvex formulations produce an error. By contrast, scipy.optimize methods vary in their support for constraints and generally require an initial feasible point, which may be difficult to find when a portfolio has many restrictions. section 10.1.3 section 10.1.3
Listing 10.10 Maximum position size constraint
class GlobalMaxWeightConstraint(Constraint):
def __init__(self, upper_bound: float):
""" Constraint to enforce an upper bound on the magnitude of every
asset in the portfolio
:param upper_bound: Magnitude of every position will be constrained
to be at most this value
"""
self.upper_bound = upper_bound
def generate_constraint(self, variables: Dict):
return cp.norm_inf(variables['w']) <= self.upper_bound
This implementation packages a universal maximum-weight rule as a reusable constraint class using cvxpy’s infinity norm. section 10.3.2
Constraints reduce the freedom of an optimizer and can substantially change selected weights. They help counter concentrated or unintuitive portfolios produced by unconstrained optimization, but restrictive combinations require feasibility checks rather than blind trust in solver output. section 10.3 section 10.4


















