Lab

M/08 — Robust portfolio construction

Universe-saturation of minimum-variance portfolios

How OOS volatility, MaxDD and CVaR-95 of a min-variance portfolio scale with the strategy-universe size N — across Ledoit–Wolf, Huber-robust and sample covariance estimators.

The mathematics

Given an N × T matrix of strategy returns R (each column a bar, each row a strategy) on a training window, the minimum-variance portfolio with full investment is

At large N, the conditioning of Σ̂ dominates portfolio behaviour on unseen data: the smallest eigenvalues of the sample covariance are biased downward (Marchenko–Pastur distortion at q = N/T), so Σ̂⁻¹ blows up the corresponding directions and the resulting w* chases noise. Three remedies are compared here.

Ledoit–Wolf shrinkage

F is a low-parameter target (constant correlation or scalar identity); the Ledoit–Wolf 2004 closed form gives a consistent estimator of α* from the data itself.

Huber-style robust M-estimator

with ψ Huber's bounded influence function. The estimator is iterated to convergence; on roughly Gaussian centered returns it coincides numerically with the sample covariance, which explains why the LW and Huber curves below are visually indistinguishable.

Saturation

Under independence, OOS portfolio variance scales as O(N⁻¹). With correlated factor structure the rate is slower and an effective number of independent directions caps the gain. The empirical saturation point N* is the universe size at which adding strategies stops moving the OOS metric materially.

Empirical setup

We run a deep walk-forward analysis on 10 USDT crypto pairs at 30-minute resolution. The largest universe is AVAX with N = 49,068 candidate strategies on T_train = 1,240 bars (q = N/T ≈ 39.6 — far above the Marchenko–Pastur regime). For each anchor N ∈ {25, 100, 500, 2,000} we sample N strategies, fit each estimator on the training window, build w*, and evaluate vol_oos, MaxDD_oos and CVaR-95_oos on the held-out window.

Concretely, on AVAX (LW) the OOS volatility falls from σ ≈ 149.5 at N = 25 to σ ≈ 116.7 at N = 100, σ ≈ 84.5 at N = 500 and σ ≈ 70.4 at N = 2,000 — a 53% reduction with two-thirds of it captured by N = 500. CVaR-95 follows the same shape, dropping from −18.8 to −7.1. On BTC (LW) the curve is steeper still: σ goes from 87.0 (N = 25) to 25.6 (N = 2,000).

Loading saturation curves…

Method comparison

At small N the three estimators differ visibly: sample covariance has lower OOS volatility (e.g. AVAX N = 500: σ_sample ≈ 73.0 vs σ_LW ≈ 84.5), because with full rank still attainable the unbiased sample estimate beats the shrunk one. As N grows, q = N/T crosses the conditioning threshold and the sample inverse becomes unstable; LW and Huber overtake on every asset for N ≳ 5,000. MaxDD is more idiosyncratic: sample sometimes wins on MaxDD even at large N (AVAX N = 2,000: MaxDD_sample ≈ −222 vs MaxDD_LW ≈ −311), which we attribute to the sample portfolio concentrating in a few well-conditioned eigen-directions during the test window.

OOS volatility saturation curves
Fig. 1OOS portfolio volatility vs N for the three estimators. The knee around N ≈ 500–1,000 is consistent across assets; doubling the universe past N = 5,000 yields sub-percent improvements in vol_oos.
OOS CVaR-95 saturation curves
Fig. 2OOS CVaR-95 saturation. The same N* ≈ 500 plateau appears: tail risk reduction tracks vol reduction once the portfolio has enough breadth to diversify.
LW vs Huber vs sample comparison
Fig. 3Method comparison. LW and Huber overlay almost exactly across N; sample diverges at small N (lower vol) and remains marginally better on MaxDD on a subset of assets.
Cross-asset saturation overlay
Fig. 4Saturation curves overlaid for the 10 deep-WFO partitions of the 30-asset corpus. The N* knee is asset-specific (BTC saturates earlier, AVAX/ETH later) but the qualitative shape is universal across every other partition the firm has examined.

Why this matters

The practical takeaway is to budget your strategy-mining effort against diminishing returns. Past the N* of an asset, additional strategies add operational cost without buying OOS risk reduction; below it, the portfolio is volatility-inefficient. The exported curves let a desk pick the smallest universe consistent with its risk target, and the LW/Huber convergence means the cheap shrinkage estimator is sufficient — the heavy robust pipeline rarely earns its compute budget on this data.

Reproducibility

DaruFinance / strategy-robust-portfolio

Python — open source reference implementation

Minimal invocation

import json
from strategy_robust_portfolio import build_min_variance, sweep_universe

# returns_train: T x N strategy returns matrix (in-sample)
# returns_test:  T' x N strategy returns matrix (out-of-sample)
weights = build_min_variance(
    returns_train,
    method="lw",        # one of {"lw", "robust", "sample"}
    rho=1e-3,           # correlation regulariser added to the diagonal
)

# Saturation sweep over universe size N
curve = sweep_universe(
    returns_train, returns_test,
    n_grid=[25, 100, 500, 2000, 10000, 49068],
    methods=["lw", "robust", "sample"],
    seed=0,
)
print(json.dumps(curve.summary(), indent=2))

References

  1. [1]Ledoit, O. & Wolf, M. (2004). A well-conditioned estimator for large-dimensional covariance matrices. Journal of Multivariate Analysis 88(2), 365–411.
  2. [2]Maronna, R. A. (1976). Robust M-estimators of multivariate location and scatter. The Annals of Statistics 4(1), 51–67.
  3. [3]Rockafellar, R. T. & Uryasev, S. (2000). Optimization of conditional value-at-risk. Journal of Risk 2(3), 21–41.
  4. [4]Bun, J., Bouchaud, J.-P. & Potters, M. (2017). Cleaning large correlation matrices: tools from random matrix theory. Physics Reports 666, 1–109.