Sparse Index Tracking
Replicate the return profile of a benchmark index using only a small subset of its constituents. The classical formulation is a regression of index returns on asset returns with an L1 penalty, solved iteratively by reweighted L1 minimisation; the result is a portfolio that hugs the benchmark with a small number of names.
Overview
A passively-managed index fund typically holds every constituent of its benchmark in cap-weighted proportions. For institutional investors with mandate-driven turnover or transaction-cost budgets, holding hundreds of names is impractical: the bottom of the cap-weight distribution contributes negligibly to index return but generates real trading cost. Sparse index tracking solves the same replication problem with a fraction of the constituents.
The original formulation by Brodie, Daubechies, De Mol, Giannone and Loris (2009) used an penalty on the weight vector to induce sparsity. Benidis, Feng and Palomar (2018) developed the high-dimensional theory and proposed the reweighted- iteration of Candes, Wakin and Boyd (2008) as the practical solver: the L1 penalty is updated at each iteration so that small weights are penalised more aggressively, as an approximation of the sparsity ideal. On a long-only, fully invested portfolio a single plain L1 solve cannot induce sparsity, because the plain term is the same constant for every such portfolio. Only the reweighted form changes the solution there.
FolioLab implements the reweighted-L1 iteration with every setting fixed. There is no user cardinality field, no user field, no penalty sweep, and no tracking-error budget:
- Cardinality is derived from the universe size , as . A universe of 5 names or fewer keeps all of them.
- The penalty is fixed in one shot, not swept: , where is the benchmark return series. The multiplier 0.2 is a constant in the code.
- The support is chosen by rank: after the iteration, the top names by score are selected. It is not selected by meeting a tracking-error target.
- The iteration is capped at
max_iter = 8, and stops earlier when the weights settle.
No tracking-error budget is stated or enforced anywhere in this method. The tracking error is the objective it minimises, and it is an outcome you read off the result, not a ceiling you set.
Mathematical Formulation
Notation
- - matrix of asset returns over periods
- - benchmark return vector
- - portfolio weights, summing to 1, long-only
- - L1 penalty strength
- - per-coordinate weights at iteration
L1 sparse regression (Brodie et al., 2009)
The squared loss measures the in-sample tracking error of the portfolio against the benchmark. Brodie et al. allow short positions, and there the L1 term limits gross exposure and drives small weights to zero. This method is long-only and fully invested. On that set for every portfolio, so the plain term is the constant . It does not change the solution, and a larger does not make this program sparser. FolioLab does not solve this program. It shows the starting point that the reweighted form below changes. The Sparse Markowitz L1 page states the same fact for the mean-variance case.
Reweighted L1 (Candes, Wakin & Boyd, 2008)
Iterate
Each iteration solves a weighted L1 problem. On the long-only set , so the penalty is linear in the weights. The per-coordinate cost grows for small , so weight moves off the marginal names. Unequal costs are what make the penalty act on the simplex. In the first pass every cost is the same, so the first pass is plain least-squares tracking. Candès, Wakin and Boyd motivate the iteration as an approximation of an penalty. Each pass is a convex program, but the repeated procedure is a heuristic, with no guarantee of the sparsest portfolio. This implementation starts from equal weights, uses , runs at most 8 iterations, and stops early when two successive weight vectors agree to a small tolerance. Every pass keeps the long-only, fully invested simplex.
Constrained refit step
The support set is not every name the iteration left positive. The names are ranked by their score, and the top are taken, where is the derived cardinality above. That support is then fixed and the weights are re-optimised on it without the L1 penalty. The refit holds the unselected names at zero. This step removes the shrinkage bias that L1 introduces while holding the cardinality, and gives the final tracking portfolio.
The score is normally the converged weight vector. Where every reweighted pass collapses to zero, the method falls back to ranking by the raw tracking correlation instead.
Requirements and constraints
The method needs at least two assets and a benchmark return series that overlaps the optimization window. If the benchmark cannot be fetched or does not overlap, the method does not run and the run states why.
Per-name weight bounds, asset exclusions, and group sum limits such as sector caps reach all three stages. Every reweighted pass carries them as extra rows. The selection keeps the names a floor forces into the book and swaps toward names that let the rules hold. The refit holds the unselected names at zero, so a floor on a dropped name is reported as a conflict rather than dropped. The selection is a bounded, deterministic search: it never exceeds the cardinality limit, and it is not a certified best subset. The run records which selection strategy chose the names.
Practical use on Indian benchmarks
For Nifty 50 the ten largest names carry more than half of index weight, so a sparse tracker built on 15 to 20 names can follow the index closely. The tracking error it achieves depends on the window and the names, and the run reports it. On Nifty 200 and Nifty 500 the trade-off is more interesting: a 30 to 50 name sparse portfolio needs far fewer trades than holding all 200 or 500 names, at the cost of a wider tracking error.
That trade-off is background for reading the result, not a dial. FolioLab's implementation takes neither nor a target cardinality from the user. The cardinality follows from the size of the universe you submit, so the way to change it is to change the universe. On a 500 name submission the cardinality is capped at 20, well below the 30 to 50 names this paragraph describes.
Advantages & Limitations
Advantages
- Holdings-cap aware: Targets a small number of positions natively.
- Approximates : Reweighted L1 is much closer to true sparsity than single L1.
- Convex per iteration: Each L1 step is a tractable QP.
- Cost aware: Lower cardinality means lower transaction costs and better fit on illiquid constituents.
Limitations
- Path sensitivity: Small changes in can flip individual names in the support.
- Out-of-sample drift: A support chosen on history may not track the benchmark equally well in regime breaks.
- No view on returns: Pure replication, no enhancement.
- Sample TE optimised: Future tracking error can exceed the in-sample objective.
References
- Benidis, K., Feng, Y., & Palomar, D. P. (2018). "Sparse Portfolios for High-Dimensional Financial Index Tracking." IEEE Transactions on Signal Processing, 66(1), 155-170.
- Candes, E. J., Wakin, M. B., & Boyd, S. P. (2008). "Enhancing Sparsity by Reweighted Minimization." Journal of Fourier Analysis and Applications, 14(5), 877-905.
- Brodie, J., Daubechies, I., De Mol, C., Giannone, D., & Loris, I. (2009). "Sparse and Stable Markowitz Portfolios." Proceedings of the National Academy of Sciences, 106(30), 12267-12272.
- Jansen, R., & van Dijk, R. (2002). "Optimal Benchmark Tracking with Small Portfolios." The Journal of Portfolio Management, 28(2), 33-39.
- Tibshirani, R. (1996). "Regression Shrinkage and Selection via the Lasso." Journal of the Royal Statistical Society: Series B, 58(1), 267-288.
- Palomar, D. P. (2025). Portfolio Optimization: Theory and Application. Cambridge University Press, Chapter 13 (Index Tracking Portfolios), Sections 13.3 and 13.5.
Not investment advice. Past performance is not indicative of future results.