A portfolio can look precise because its weights have many decimal places. That precision says nothing about stability. Change a few observations, and the mean-variance optimizer may send the portfolio somewhere else.
Resampled Efficient Frontier (REF) makes that sensitivity visible. We resample the return rows, estimate new moments, rebuild a frontier for each replicate, and average comparable portfolios. The last phrase is the heart of the method: we must preserve frontier rank. Minimum-variance portfolios are comparable to minimum-variance portfolios; middle-ranked portfolios are comparable to middle-ranked portfolios. Averaging every optimized weight together produces a number, but not a resampled efficient frontier.
This tutorial gives you a deterministic, inspectable version. You will see the exact sampled rows, moment estimates, rank targets, inner weights, correct average, and wrong global-average shortcut.
Starting toolkit
Read Black–Litterman’s toolkit for the simplex and portfolio-variance notation. Here the new idea is sampling variability: the optimizer receives different estimated moments when the observed rows change. You should leave able to reconstruct every replicate and explain precisely what is being averaged.
Why rebuild the optimizer?
Mean-variance weights depend on estimated means and covariances. Those estimates depend on the particular observations in the sample. REF treats the frontier as a statistical object: if plausible resamples produce very different portfolios at the same rank, the original weights deserve skepticism.
The method does not magically create information. It reorganizes information already in the sample and reveals how the optimizer reacts. A bad split, omitted cash dividend, impossible mark, stale security mapping, or inconsistent FX conversion will be resampled too. More replications can make a data error look consistently wrong.
What “same rank” means
Each replicate has its own global-minimum-variance (GMV) expected return and its
own maximum asset mean. For rank q between zero and one, define
At q=0, solve the replicate's GMV portfolio. At q=1, solve its maximum-mean
endpoint. At q=0.5, solve halfway through that replicate's feasible return
interval. This mapping lets us associate portfolios by economic position even
when raw expected returns move between samples.
The two computed curves use their own moments. Dots mark the selected common rank; the final average is an average of weights, not chart coordinates.
Rank association and weight averaging are described in the MOSEK estimation-error chapter and the original public method record. The linear return-rank mapping, population divisor, and explicit resample indices here are declared implementation choices.
The canonical algorithm
For each explicit bootstrap index row:
- Select source rows with replacement.
- Calculate the replicate mean and population covariance (
ddof=0). - Solve the long-only GMV portfolio.
- Find the replicate maximum mean.
- Map every requested
qtobeta_b(q). - Solve minimum variance subject to that return target.
- Store the rank label, target, weights, and diagnostics.
Then average only weights with the same q:
Because every inner portfolio lies in the same convex simplex, its rank-wise average also lies in the simplex. If a later layer imposes nonconvex cardinality or lot constraints, that property no longer guarantees feasibility and any repair must be named separately.
A fixture you can calculate
The example uses six synthetic two-asset decimal-return rows:
[0.00, 0.00]
[0.20, 0.00]
[0.10, 0.10]
[0.10, 0.00]
[0.05, 0.10]
[0.15, 0.05]
We do not ask a random generator to hide the evidence. The two resample index rows are stored explicitly:
[0,1,2,3]
[0,1,4,5]
For the first replicate, mu=[0.10,0.025] and
Sigma=[[0.005,0],[0,0.001875]]. The GMV weights are
[0.2727272727,0.7272727273]. For the second, mu=[0.10,0.0375] and
Sigma=[[0.00625,-0.000625],[-0.000625,0.00171875]]; the GMV weights are
[0.2542372881,0.7457627119].
Average those two rank-zero portfolios and we get
[0.2634822804,0.7365177196]. Both maximum-mean endpoints are [1,0], so the
rank-one average is [1,0].
Now consider the wrong shortcut: mix both endpoints and both GMV portfolios into one global average. The result no longer answers any named rank. It blends two different investor positions and discards the mapping that defines REF.
Reproducibility needs more than a seed
The reference package includes a small seeded bootstrap generator, but the fixture stores the full index matrix. That distinction matters. Different languages and libraries can turn the same integer seed into different streams. If you need exact replay, serialize the selected row indices, estimator convention, ranks, constraints, solver tolerance, and source-row identity.
Reordering the original return table while keeping the same numeric indices does not preserve a sample; the indices now select different observations. Either keep a stable row identifier or remap the indices to the same original rows.
The data contract comes first
In portfolio work, the return matrix is not just numbers. Every row needs an observation period and availability date. Every column needs a point-in-time security identity. The full panel needs a base currency, FX timestamp and quote direction, split/dividend treatment, missing-data policy, and survivorship rule.
I care about this because old portfolios often contain exactly the data defects that optimization amplifies: quantities entered with the wrong unit, marks that do not belong to that instrument or date, and holdings from several currencies compared before conversion to the portfolio's reporting currency. REF is a sensitivity tool after those checks—not a substitute for them.
Resampling assumptions are part of the model
An ordinary row bootstrap treats observations as exchangeable; the common justification is independent, identically distributed observations. Serial dependence, changing regimes, and overlapping returns weaken that justification. A block bootstrap samples consecutive stretches together to retain some temporal structure. It needs a declared block length and a new index-generation policy; it is not implemented by the simple IID helper.
Draw whole rows so asset returns stay aligned. Sampling each column independently destroys contemporaneous dependence. The teaching fixture uses four observations from six source rows, a deliberate -out-of- example. The conventional -out-of- bootstrap would draw six. Neither two replicates nor these artificial rows establish a useful sampling distribution in practice.
Our moments use divisor (ddof=0). Changing to rescales a replicate covariance uniformly; under the same constraints it does not change its minimum-variance weights, but it changes reported variances and must be recorded.
What the rank average actually says
At rank 0.5, replicate A weights are [0.6363636364,0.3636363636]; replicate B weights are [0.6271186441,0.3728813559]. Their mean asset-A weight is 0.6317411402. Their population standard deviation is 0.0046224961, or 0.46225 percentage points of weight. This is dispersion across the two specified replicates, not a confidence interval.
Compare that with mixing rank 1 from replicate A and rank 0.5 from replicate B: . The arithmetic is valid; the association is wrong. Conversely, averaging both assets across every portfolio trivially gives 0.5 because each portfolio sums to one. That tautology cannot test rank matching.
Evaluate the final averaged weights against one common full-panel mean and covariance before plotting a resulting portfolio on a common risk-return chart. In general,
The curve of averaged weights need not itself be efficient for the full-panel moments. The word “frontier” in the method name does not prove that property.
Equal means and singular samples
If all means equal the target, the return equality adds no information to the budget equation. The solver must still minimize variance. With equal means and covariance diag(0.005,0.005), every rank returns [0.5,0.5].
A bootstrap can also produce singular covariance. The two rows [0.1,-0.1] and [-0.1,0.1] admit a zero-variance hedge at [0.5,0.5]. Discarding the singular face and reporting a corner as optimal is wrong. The reference now solves scaled KKT equations with redundant constraints and free variables, checks residuals, and supports positive-semidefinite sample covariances without adding hidden jitter. Numerically unresolved problems fail explicitly.
How many replications are enough?
There is no universal adequate . Compare rank-specific mean weights and dispersion at increasing , replay several fixed seeds, and report the maximum change in weight at the investor’s chosen rank. Stable bootstrap averages can still be stably wrong under a misspecified resampling model. Out-of-sample evaluation and costs answer a different question from numerical convergence of the bootstrap average.
Try it: repeat one replicate twice. Its own rank weights should be unchanged by averaging. Then permute the source rows and remap the stored indices. The answer should again be unchanged.
Implementation without a mystery solver
The Python implementation and TypeScript implementation use a small active-set enumerator. For each candidate set of positive weights, they solve the equality-constrained minimum-variance equations, discard negative or residual-failing candidates, and keep the feasible minimum. This is readable and independently checkable for at most 12 assets.
Production universes need a reliable quadratic solver. Preserve per-cell solver statuses. One inaccurate inner solution does not become accurate because it is averaged with other solutions; an incomplete matrix of ranks and replicates must be reported as partial.
Learn by stepping through the lab
Open the rank-matching playground. The initial view shows the computed rank-0.5 result; the input stage exposes the synthetic rows. Step through row selection, moment estimation, endpoint construction, rank alignment, and averaging. Switch to equal means or the singular hedge to inspect the degenerate cases. The failure case introduces an invalid index and shows the calculation stop before a frontier is drawn.
What to notice: the average is the final operation, not the first. Every member of an average must carry its rank and feasibility evidence.
What the tests prove
The shared JSON fixture reproduces both replicate means, covariances, GMV
weights, maximum-mean endpoints, and averaged weights. Tests cover B=1, seeded
determinism, invalid ranks and indices, the anti-global-mean regression, and
Python/TypeScript parity.
They prove that the implementation follows the selected algorithm. They do not prove that resampled weights have higher Sharpe ratio, lower realized risk, or better performance after costs. Those are empirical questions requiring point-in-time out-of-sample data.
Boundaries and historical evidence
The historical-example decision is deferred. A named market panel would need licensed data, point-in-time constituents, corporate-action and FX basis, an estimator record, and an out-of-sample comparison with costs. The public US patent record is useful for method history and rank/vector-averaging evidence; its public metadata currently labels the record “Expired - Lifetime.” That is not a statistical result or legal opinion. This package uses original code and short factual citations.
Run the calculation yourself
From this topic folder, use Python 3.10 or later. No third-party numerical library is required:
python examples/python_example.py
python -m unittest discover -s tests -p "test_*.py"
The key call is shown below. For an interactive Python session, first make the local implementation importable:
import sys
sys.path.insert(0, "implementations/python")
from resampled_efficient_frontier import resampled_efficient_frontier
R=[[0,0],[.2,0],[.1,.1],[.1,0],[.05,.1],[.15,.05]]
print(resampled_efficient_frontier(R,[[0,1,2,3],[0,1,4,5]],[0,.5,1]).to_dict())
The TypeScript example uses the same inputs. See the runnable commands for compilation and execution. Shared cases in the shared regression cases exercise boundary states in both languages; strings NaN and Infinity are test sentinels, not valid numerical inputs.
Summary
REF is valuable when it keeps the entire evidence chain: selected rows, replicate moments, replicate endpoints, common ranks, inner weights, and the rank-wise average. Its best lesson is not “averaging is safer.” It is that an optimized portfolio can be unstable, and stability must be measured without changing the object being compared.
Next, Robust Mean-Variance replaces repeated samples with an explicit set of possible mean vectors and asks for the best objective under the weakest member of that set.
Choose the family method by the decision you face
| Your real question | Start with | What changes | What it does not solve |
|---|---|---|---|
| How should uncertain views modify a market prior? | Black-Litterman | Expected returns through a prior and views | Sampling stability by itself |
| How unstable are optimized weights across plausible samples? | Resampled Efficient Frontier | Rows, replicate moments, and rank-matched frontiers | Structural errors repeated in every sample |
| How should a bounded error in the mean affect allocation? | Robust Mean-Variance | Mean vector inside a declared ellipsoid | Resampling or posterior beliefs |
| Which portfolio ranks best under a declared distribution class and loss event? | Distributionally Robust Portfolio | The admissible return distribution | Universal or assumption-free safety |
| Which scenario mix maximizes long-run log growth? | Kelly Allocation | Objective and scenario wealth factors | Weight-stability evidence |
Related concepts and learning handoff
The reviewed The Fintech Builder chapter KKT checks and limits of an optimality claim (17:33–18:43) supports the inner frontier solver review: a feasible target and a stationarity check matter before any replicate weight is averaged. It does not derive resampling or justify the rank grid.
Rendered from the canonical Mermaid sources linked by this article.
resampled frontier flow
ReferencesPrimary sources and evidence notesExpand the source trail, evidence role, and limitations behind the engineering choices.
Expand the source trail, evidence role, and limitations behind the engineering choices.
PATENT-6003018 — Portfolio optimization by means of resampled efficient frontiers
- Organization or authors: US patent record; inventors Richard O. Michaud and Robert Michaud.
- Source type: Official public patent record.
- Publication or effective date: 14 December 1999; priority 27 March 1998.
- Version: US6003018A, current record labels legal status “Expired - Lifetime”.
- URL or DOI: Google Patents record.
- Accessed: 2026-09-15.
- Jurisdiction: United States intellectual-property record.
- Supports: Recalculation on resampled inputs, index/rank association, and vector averaging of associated portfolios.
- Limitations: Legal-status labels include database caveats; the record does not prove statistical superiority or grant permission to copy protected text/code.
MOSEK-REF — Resampled optimization
- Organization or authors: MOSEK ApS.
- Source type: Maintained official technical documentation.
- Publication or effective date: Online edition accessed 2026-09-15.
- Version: Portfolio Optimization Cookbook, estimation-error chapter.
- URL or DOI: Resampled optimization section.
- Accessed: 2026-09-15.
- Jurisdiction: None.
- Supports: Parametric and nonparametric resampling, matching portfolios across simulated frontiers, averaging, and computational limitations.
- Limitations: Vendor documentation is a secondary technical explanation; package behavior is defined by the explicit contract and tests.
MICHAUD1998 — Efficient Asset Management
- Organization or authors: Richard O. Michaud.
- Source type: Original book-length method exposition.
- Publication or effective date: 1998.
- Version: Public author-hosted PDF copy; edition pagination should be checked before quoting.
- URL or DOI: New Frontier Advisors PDF.
- Accessed: 2026-09-15.
- Jurisdiction: None.
- Supports: Historical context for simulated efficient frontiers and rank-associated portfolio averaging.
- Limitations: No text or code is reproduced; the source does not make the package's synthetic fixture empirical evidence.
Full dependency-light reference implementations in both supported languages.
export class ContractError extends Error {
}
type Vector = number[];
type Matrix = number[][];
const dot = (a: Vector, b: Vector) => a.reduce((s, x, i) => s + x * b[i], 0);
const mv = (a: Matrix, x: Vector) => a.map(r => dot(r, x));
function* combos(n: number, k: number, s = 0, p: number[] = []): Generator<number[]> { if (p.length === k) {
yield p;
return;
} for (let i = s; i < n; i++)
yield* combos(n, k, i + 1, [...p, i]); }
function moments(rows: Matrix): [
Vector,
Matrix
] { const t = rows.length, n = rows[0].length, mu = Array.from({ length: n }, (_, j) => rows.reduce((s, r) => s + r[j], 0) / t); return [mu, Array.from({ length: n }, (_, i) => Array.from({ length: n }, (_, j) => rows.reduce((s, r) => s + (r[i] - mu[i]) * (r[j] - mu[j]), 0) / t))]; }
function consistentSolve(a: number[][], b: number[]): number[] {
const g = a.map((row, i) => { const s = Math.max(...row.map(Math.abs), Math.abs(b[i]), 1e-300); return [...row.map(x => x / s), b[i] / s]; });
const columns = a[0].length, pivots: number[] = [];
let pr = 0;
for (let col = 0; col < columns && pr < g.length; col++) {
let p = pr;
for (let r = pr + 1; r < g.length; r++)
if (Math.abs(g[r][col]) > Math.abs(g[p][col]))
p = r;
if (Math.abs(g[p][col]) < 1e-12)
continue;
[g[pr], g[p]] = [g[p], g[pr]];
const z = g[pr][col];
g[pr] = g[pr].map(x => x / z);
for (let r = 0; r < g.length; r++)
if (r !== pr) {
const f = g[r][col];
g[r] = g[r].map((x, j) => x - f * g[pr][j]);
}
pivots.push(col);
pr++;
}
if (g.some(row => Math.max(...row.slice(0, -1).map(Math.abs)) < 1e-10 && Math.abs(row[columns]) > 1e-9))
throw new ContractError("inconsistent KKT system");
const x = Array(columns).fill(0);
pivots.forEach((col, r) => x[col] = g[r][columns]);
return x;
}
/** PSD face enumeration with scaled, possibly redundant equality constraints. */
function minVariance(mu: number[], sigma: number[][], target: number | null): number[] {
const n = mu.length, scale = Math.max(...sigma.flat().map(Math.abs), 1e-300);
let best: {
v: number;
w: number[];
} | undefined;
for (let size = 1; size <= n; size++)
for (const active of combos(n, size)) {
const constraints = [Array(size).fill(1)], rhs = [1];
if (target !== null) {
const spread = Math.max(...active.map(i => Math.abs(mu[i] - target)));
if (spread > 1e-14) {
constraints.push(active.map(i => (mu[i] - target) / spread));
rhs.push(0);
}
}
const k = constraints.length, a = active.map((i, pos) => [...active.map(j => sigma[i][j] / scale), ...constraints.map(c => c[pos])]);
a.push(...constraints.map(c => [...c, ...Array(k).fill(0)]));
const b = [...Array(size).fill(0), ...rhs];
let z: number[];
try {
z = consistentSolve(a, b);
}
catch {
continue;
}
if (z.some(x => !Number.isFinite(x)) || Math.min(...z.slice(0, size)) < -1e-10)
continue;
if (Math.max(...a.map((row, i) => Math.abs(dot(row, z) - b[i]))) > 1e-8)
continue;
const w = Array(n).fill(0);
active.forEach((i, pos) => w[i] = Math.max(0, z[pos]));
if (Math.abs(w.reduce((s, x) => s + x, 0) - 1) > 1e-9 || (target !== null && Math.abs(dot(mu, w) - target) > 1e-10))
continue;
const v = dot(w, mv(sigma, w));
if (!best || v < best.v - 1e-14 * scale)
best = { v, w };
}
if (!best)
throw new ContractError("frontier target infeasible or numerically unresolved");
return best.w;
}
export interface Replicate {
indices: number[];
mean: Vector;
covariance: Matrix;
gmvReturn: number;
maxReturn: number;
weightsByRank: Vector[];
}
export interface ResampledFrontierResult {
ranks: Vector;
averagedWeights: Vector[];
replicates: Replicate[];
status: "optimal";
}
export function resampledEfficientFrontier(returns: Matrix, resampleIndices: number[][], ranks: Vector): ResampledFrontierResult { const rows = returns.map(r => r.map(Number)); if (rows.length < 2 || !rows[0]?.length || rows.some(r => r.length !== rows[0].length) || rows.flat().some(v => !Number.isFinite(v)))
throw new ContractError("returns must be a finite rectangular matrix with at least two rows"); if (rows[0].length > 12)
throw new ContractError("reference solver supports at most 12 assets"); if (!ranks.length || ranks.some(q => !Number.isFinite(q) || q < 0 || q > 1))
throw new ContractError("ranks must lie in [0,1]"); if (!resampleIndices.length)
throw new ContractError("at least one resample is required"); const replicates = resampleIndices.map(raw => { const indices = raw.map(Number); if (indices.length < 2 || indices.some(i => !Number.isInteger(i) || i < 0 || i >= rows.length))
throw new ContractError("resample index is out of range"); const [mean, covariance] = moments(indices.map(i => rows[i])); const gmv = minVariance(mean, covariance, null), gmvReturn = dot(mean, gmv), maxReturn = Math.max(...mean); const weightsByRank = ranks.map(q => minVariance(mean, covariance, gmvReturn + q * (maxReturn - gmvReturn))); return { indices, mean, covariance, gmvReturn, maxReturn, weightsByRank }; }); const averagedWeights = ranks.map((_, ri) => Array.from({ length: rows[0].length }, (_, j) => replicates.reduce((s, r) => s + r.weightsByRank[ri][j], 0) / replicates.length)); return { ranks: [...ranks], averagedWeights, replicates, status: "optimal" }; }
export function seededBootstrapIndices(rowCount: number, sampleSize: number, replications: number, seed: number): number[][] { if ([rowCount, sampleSize, replications].some(x => !Number.isSafeInteger(x) || x <= 0) || !Number.isInteger(seed) || seed < 0 || seed > 4294967295)
throw new ContractError("bootstrap sizes must be positive"); let state = seed >>> 0; return Array.from({ length: replications }, () => Array.from({ length: sampleSize }, () => { state = (Math.imul(1664525, state) + 1013904223) >>> 0; return Math.floor((state / 4294967296) * rowCount); })); }
The embedded lab now expands to its full document height, keeping the article as the only scroll surface.
