Portfolio Constraints

A constraint is a hard limit on what the finished portfolio may hold. You write per-stock lb and ub, exclude stocks outright, and cap or floor a sector or a mktcap band. Every limit binds: a limit that cannot be met makes the request infeasible rather than quietly bending.

The four kinds of limit, and what each one means

Write for the weight of stock . Every optimization already carries the budget row, which says the weights spend the whole portfolio and nothing more:

Your limits add rows to that same statement.

  • A per-stock lb and ub bounds one stock, or every stock at once: .
  • An excluded stock is the ub of zero: . It is a limit rather than a deletion, so the run records that you excluded the stock rather than that you never asked for it.
  • A sector limit bounds the total held in one sector : .
  • A mktcap limit is the same row over a large, mid or small cap band : .

All four are linear in the weights. That single fact is what the whole capability rests on: a linear limit can be added to a convex optimization without changing the kind of problem it is, so the solved portfolio is the best one that obeys your limits rather than an approximation of it.

Two further shapes are available on a sector or mktcap limit. You can bound each stock inside that band, which is a per-stock lb and ub applied to the members rather than to their total. And you can measure the percentages against another band rather than against the whole portfolio, so "IT is at most 35% of the equity sleeve" is expressible. If that sleeve holds 80% of the portfolio, a 35% limit permits 28% of the portfolio.

Limits are solved, never applied afterwards

There are two ways to build a constrained portfolio, and they do not give the same answer.

The tempting way is to optimize first and fix afterwards: find the unconstrained portfolio, then clip whatever breaches a limit and spread the removed weight over the rest. It is simple and it is wrong.

Take four stocks, each limited to between 10% and 40%. Holding 25% of each satisfies every limit outright, so a correct answer plainly exists. The clip-and-spread approach returns 40%, 10%, 10% and 10%, which sums to 70% rather than 100%. Rescaling that back to 100% then pushes the largest holding above its own 40% ub. Nothing in the result announces this. You receive a portfolio that breaches the limit you set, labelled as though it met it.

So we never do that. There is no repair step, no second pass, and no search from an unconstrained answer towards a legal one. Your limits become part of the problem that is solved. A limit that cannot be met therefore makes the problem unsolvable and you are told so, which is the honest outcome and the one you can act on.

Two ways a method receives your limits

Most methods take your limits as a direct input. They state the portfolio problem as a single optimization, and your rows are handed to it alongside the budget row before anything is solved. Because every limit is linear, adding them does not change the kind of problem it is, and the answer that comes back is the best portfolio that obeys them. Twenty-four of the thirty-one methods work this way, including Mean-Variance, Minimum Volatility, Minimum CVaR, Maximum Diversification and Risk Budgeting.

Two of those twenty-four take your limits one step further out. NCO and Stacking Optimization first build a small number of sub-portfolios, then decide how much money each one gets. Your limits are handed to that second decision, expressed on the final stock weights the blend produces. This is still a direct input, with one consequence worth knowing: the sub-portfolios are fixed before that decision, so a limit the individual stocks could meet can still be out of reach for a blend of them. The run says so and names which limits the blend misses and by how much.

Critical Line Algorithm is a third shape. It takes per-stock lb and ub as a direct input and solves them exactly, because its algorithm advances by tracking which bounds are currently active. That same mechanism is what a sector or mktcap total breaks, which is why it accepts one and not the other.

Where a direct input is not possible

Hierarchical Risk Parity, HERC and HERC2 do not solve a single optimization at all, so there is nothing to hand a limit to. They build a tree that groups similar stocks together, then walk down it, splitting the money between two branches at each step. This third step is called recursive bisection.

What recursive bisection means here

Bisection means splitting something in two. Recursive means doing it again to each half. Starting with the whole portfolio, the tree is cut into two branches and the money is divided between them, usually in inverse proportion to each branch's risk. Each branch is then cut in two and divided again, and so on, until every branch is a single stock and every stock has a weight.

It is a top-down splitting procedure. It is not the bisection method from numerical analysis, which repeatedly halves an interval to hunt for the root of an equation, and nothing here searches from an unconstrained portfolio towards a legal one.

Because the money is committed one split at a time, a limit has to shape each split as the tree is walked, before any stock has a weight.

Suppose a branch holds a fraction of the portfolio and divides into two branches, A and B. Write and for the sums of the lb and the ub of every stock under A, and the same for B. The amount given to A must satisfy:

Each of the four terms is doing work:

  • is what A can absorb on its own.
  • stops you giving A so little that the rest cannot fit under B's ub.
  • stops you giving A so much that B can no longer reach its lb.

This is exact for per-stock lb and ub. An amount given to a branch can be completed into a legal set of weights precisely when it lies between that branch's summed lb and summed ub. The interval above preserves that property for both branches at once, so applying it at every split, down to the individual stocks, guarantees every per-stock lb and ub holds and the weights still sum to one.

Two honest limits of the result. It proves the portfolio obeys your limits; it does not claim to be the lowest-risk portfolio that obeys them. And a sector or mktcap total is not a quantity any branch of the tree forms, which is why those three methods do not accept one. That is a decision about this release rather than a theorem: published research sets out a constrained hierarchical risk parity algorithm that handles box and group constraints together, so we describe it as unavailable here and never as impossible.

When no limit binds, the constrained walk reproduces the unconstrained one to floating-point noise, so any difference you see is attributable to your limits and not to a change of method.

Which constraints each method accepts

Of the 31 methods, 27 accept constraints and 22 accept all three kinds. The optimize form shows you this per method before you spend a run, and the PDF and Excel reports record what each method actually did.

A run may deliberately mix methods that take your limits with methods that cannot, because comparing a constrained portfolio against an unconstrained one is sometimes the point. A method that cannot apply your limits produces no portfolio in that run: it is not run without them, and it is not run with them.

MethodPer-stock lb and ubExcluded stocksSector and mktcap limits
Mean-Variance (Markowitz)YesYesYes
Black-LittermanYesYesYes
Minimum VolatilityYesYesYes
Max Quadratic UtilityYesYesYes
Minimum CVaRYesYesYes
Minimum CDaRYesYesYes
Minimum SemivarianceYesYesYes
EWMA Mean-VarianceYesYesYes
HMM Regime MVOYesYesYes
Maximum DiversificationYesYesYes
Distributionally Robust CVaRYesYesYes
Benchmark TrackerYesYesYes
Minimum EVaRYesYesYes
Minimum EDaRYesYesYes
Resampled Mean-VarianceYesYesYes
Maximum DecorrelationYesYesYes
Robust Mean-VarianceYesYesYes
Kelly OptimizationYesYesYes
Sparse Markowitz (L1)YesYesYes
Sparse Index TrackingYesYesYes
NCOYesYesYes
Stacking OptimizationYesYesYes
Risk BudgetingYesNoYes
Hierarchical Risk ParityYesYesNo
HERCYesYesNo
HERC2YesYesNo
Critical Line AlgorithmYesYesNo
Equal WeightedNoNoNo
Inverse VolatilityNoNoNo
Quintile MomentumNoNoNo
Kalman Pairs TradingNoNoNo

Notes on individual methods

Benchmark Tracker
Under constraints it also stops widening its own tracking-error limit. A desk that writes a tracking-error budget beside a sector limit has stated both as limits, so only the number you asked for is attempted.
Resampled Mean-Variance
Every bootstrap draw carries the constraints, and an average of portfolios that each satisfy them satisfies them too.
Kelly Optimization
This method has a per-stock ub of its own. Yours sits beside it and the tighter of the two applies.
Sparse Markowitz (L1)
Under long-only, fully invested weights the L1 term is a constant and does not by itself reduce the number of holdings, with or without constraints.
Sparse Index Tracking
The constraints reach the stock selection as well as the weighting. A stock dropped by the selection is held at zero, so an lb on a dropped stock is reported as a conflict rather than quietly ignored.
NCO
Whether your constraints are reachable depends on the date range, because the number of clusters is a property of the window. The same stocks and the same limits were refused over one span and solved over a shorter one.
Stacking Optimization
The blend can miss a limit that the stocks themselves could meet. The run reports that as a limit of the blend and says which limits it misses and by how much.
Risk Budgeting
An excluded stock is the one case this method cannot take: its formulation uses the logarithm of each weight, so a weight of exactly zero is outside its domain. Remove the stock from the run instead. A binding lb or ub also prevents the exact risk contributions this method exists to deliver, so the run reports what it achieved against what you asked for.
Hierarchical Risk Parity
A sector or mktcap total is not a quantity this method ever forms, because a sector cuts across the branches of its tree. This is a limit of the current release and not a mathematical impossibility.
HERC
As Hierarchical Risk Parity. HERC also keeps fixed proportions inside each final cluster, so a per-stock lb or ub those proportions cannot carry is refused rather than met by changing the method.
HERC2
As HERC, with equal weights inside each final cluster. Flatter proportions leave more room, so it refuses less often.
Critical Line Algorithm
This method solves per-stock lb and ub exactly: its algorithm advances by tracking which bounds are active. A sector or mktcap total is a different shape of rule and breaks that algorithm, so it is permanently unavailable here rather than pending work.
Equal Weighted
The weights are fixed by the definition of the method. Changing them to meet a limit produces a different strategy rather than a constrained version of this one.
Inverse Volatility
The weights are fixed by each stock's own volatility, for the same reason as Equal Weighted.
Quintile Momentum
This ranks and selects stocks rather than optimizing weights. A limit could mean change the weights, change the stocks selected, or both, and we will not guess which you meant.
Kalman Pairs Trading
Long and short by construction. These constraints are long-only, and an lb over a position that may be negative does not mean what it says. This method is available through the API and is not offered on the website.

Checks that run before a run is spent

Can any portfolio satisfy every limit at once?

Checking each limit on its own is not enough, and the reason is worth understanding. Suppose you set a large cap lb of 60% and an IT ub of 40%, and every large cap stock in your list is an IT stock. Each limit passes its own arithmetic. Together they are impossible, and no per-limit test can see it, because the conflict lives in the overlap between two lists rather than in either limit.

So the check is one linear program carrying every limit at once: the budget row, the effective per-stock lb and ub, and every sector and mktcap row simultaneously. This is exact for limits on the allocation, and it is cheap enough to run as you type.

When it fails, a second program finds the smallest total adjustment that would make your limits hold. The adjustments that come back non-zero name the limits in conflict and the size of each conflict, so you read "your large cap lb and your IT ub miss each other by 12 percentage points" rather than the word infeasible.

What can this list of stocks actually hold?

Before a limit is even infeasible, the more useful question is what your stocks can support. For one sector or mktcap band, holding every other limit fixed, two more linear programs give the answer:

That pair is the reachable range, and the form shows it beside the limit you are writing. The band's own limit is taken out of its own range on purpose: a sector already capped at 20% would otherwise report a maximum of 20%, which is your own limit read back rather than a fact about your stocks.

One boundary to keep in mind. These checks cover limits on the allocation and nothing else. A method's own requirement, such as a tracking-error limit, can still refuse a request that sits comfortably inside every reachable range.

Constraints in a backtest

A rolling walk-forward backtest re-optimizes at every rebalance date, and your limits are applied at every one of them, not only at the start. Feasibility is re-checked at each rebalance date and the outcome is recorded for each.

Sector and mktcap limits are the exception, and the reason is look-ahead. A sector list carries a date. Applying a list dated 2026 inside a training window that ends in 2016 would let the optimizer pick its 2016 portfolio with knowledge of which companies survived, merged and re-listed. That inflates a backtest and makes it worthless as evidence.

So a sector or mktcap limit whose list is dated after the first rebalance date is excluded from the backtest and the exclusion is recorded, rather than applied quietly with today's data. The decision is taken once, against the first rebalance date, so one set of limits holds across the whole track. Per-stock lb and ub name a stock directly, read no list, carry no date, and are always applied.

The backtest result states which limits it applied and which it excluded, with the date of the list and the reason, on the results page, in the PDF and in the Excel workbook.

What your limits cost

A constrained portfolio differs from the one the same method would build with no limits at all. You can ask the run to measure that difference. The measurement costs a second solve for each method, so it is off unless you ask for it.

Five measures are reported together, and deliberately so. They answer different questions and they rank limits differently, so publishing one of them would present one ranking as the ranking.

  • Active share, half the sum of the absolute weight changes. How much of the book moved.
  • Tracking error between the two portfolios, annualized. How differently the constrained book should behave.
  • Volatility with and without the limits, and the difference. What the limits cost in risk, measured in advance from the same covariance estimate rather than from a realized track.
  • The largest single stock move, because one stock moving twenty points is worth seeing next to an active share that averages it away.
  • Each sector and mktcap total, with and without the limits.

None of these is a forecast, and a larger distance is not a worse set of limits. They describe two portfolios built on the same frozen inputs, and nothing about how either will perform.

Where the sector list comes from

A sector limit needs to know which sector each stock is in, and you supply that list yourself from Sector Lists. The run reads the list, records the revision it read, and stores it with the result. Editing a list changes what your next run means and never what a past run meant.

An mktcap limit needs no list. The bands are built from a market capitalisation snapshot of the stocks in your own run, using absolute thresholds. This is not the AMFI or SEBI rank-based large, mid and small cap list, which ranks the whole listed universe twice a year and cannot be computed from one portfolio's stocks. The snapshot is point-in-time, so it carries no history and is never applied inside a backtest window.

References

Why constraints are worth setting

  • Jagannathan, R. and Ma, T. (2003). Risk Reduction in Large Portfolios: Why Imposing the Wrong Constraints Helps. The Journal of Finance, 58(4), 1651-1683. Shows that an upper bound on each weight acts like shrinking the covariance estimate, so constraints can reduce realized risk even when the constraint itself is not what the investor truly believes.
  • Best, M. J. and Grauer, R. R. (1991). On the Sensitivity of Mean-Variance-Efficient Portfolios to Changes in Asset Means: Some Analytical and Computational Results. The Review of Financial Studies, 4(2), 315-342. Quantifies how violently unconstrained mean-variance weights move in response to small changes in estimated returns, which is the instability lb and ub are usually set to control.
  • DeMiguel, V., Garlappi, L., Nogales, F. J. and Uppal, R. (2009). A Generalized Approach to Portfolio Optimization: Improving Performance by Constraining Portfolio Norms. Management Science, 55(5), 798-812. Treats constraints on the size of the weight vector as a single framework and measures the out-of-sample effect.

Why a linear limit fits inside the optimization

  • Boyd, S. and Vandenberghe, L. (2004). Convex Optimization. Cambridge University Press. The standard treatment of why adding linear equalities and inequalities to a convex objective leaves the problem convex, and therefore leaves a global optimum reachable.
  • Rockafellar, R. T. and Uryasev, S. (2000). Optimization of Conditional Value-at-Risk. Journal of Risk, 2(3), 21-41. Shows that minimizing CVaR can be written as a linear program, which is what lets the CVaR and drawdown methods carry your limits as ordinary rows rather than needing special handling.
  • Huangfu, Q. and Hall, J. A. J. (2018). Parallelizing the dual revised simplex method. Mathematical Programming Computation, 10(1), 119-142. The class of algorithm behind the feasibility and reachable range programs described above.

Hierarchical methods and recursive bisection

  • Lopez de Prado, M. (2016). Building Diversified Portfolios that Outperform Out of Sample. The Journal of Portfolio Management, 42(4), 59-69. Introduces hierarchical risk parity and the recursive bisection step described above.
  • Raffinot, T. (2017). Hierarchical Clustering-Based Asset Allocation. The Journal of Portfolio Management, 44(2), 89-99. The clustering-based allocation family that HERC and HERC2 belong to.
  • Pfitzinger, J. and Katzke, N. (2019). A constrained hierarchical risk parity algorithm with cluster-based capital allocation. Stellenbosch University, Department of Economics, Working Paper 14/2019. Sets out hierarchical risk parity weights under box and group constraints together. This is a working paper rather than a peer-reviewed article, and it is cited here as the evidence that sector and mktcap limits on the tree-based methods are unavailable in this release rather than mathematically impossible.

Availability

Constraints are an Enterprise capability. They can be set on the optimize form, through the REST API, and through a connected AI assistant. All three read the same per-method table shown above, so none of them can offer you a limit a method cannot apply.

Not investment advice. Past performance is not indicative of future results.