Reiad's Library
Case study · Portfolio construction · Interactive

A Shariah and ESG screened FTSE 250 fund, built in 2015 and held to 2020.

Ten mid-cap holdings chosen by a screen that runs before any price is looked at: leverage under a third of equity, sustainability away from the laggards, returns on capital above the cost of it, and a required return set for each one off the security market line. Weights chosen at the end of 2015 by minimising the variance the holdings contribute, then held, unchanged, through the five years that followed. £10m at the start, and every number on this page computed in your browser from the daily closes rather than copied out of a spreadsheet.

Five years held

Hold-out returnCumulative over the five years
AnnualisedCompound, after the whole period
Portfolio betaWeighted, against the FTSE 250
SharpeRealised, on the held-out years
Deepest drawdownPeak to trough, along the way
Average year, vs indexMean annual return against the FTSE 250
The efficient frontier, estimated on 2015annualised, long only, capped

What five years did to itThe fundEqual weight

What got in, and what the screen threw out

The universe starts as the FTSE 250 and is cut by rules that are stated before any price is looked at: leverage below a third of equity, a sustainability score away from the laggards, a return on equity in double figures, and a return on invested capital above the cost of it. Sector caps then stop the survivors from being ten versions of the same bet.

Everything the optimiser knows

One year of daily closes. From it: an average return and a volatility for each holding, and a correlation with every other. That is fifty-five numbers estimated from 252 days, and the optimiser will treat all of them as though they were facts.

Risk and return, one yeareach holding, annualised
Correlationsdaily, over the estimation window
Why there is a shrinkage dial

A covariance matrix estimated from a single year is mostly signal in its diagonal and mostly noise off it. A minimum-variance objective is drawn to whichever pair of holdings looks least correlated, which is exactly where the estimate is least trustworthy, so the optimiser reliably falls in love with an artefact. Pulling the off-diagonal terms towards zero is the standard defence. Move the dial and watch how much of the answer was resting on those numbers.

Solving it, forty times

Every point on the curve above is a constrained optimisation, solved here, of

maximise w′μ − (γ/2)·w′Σw subject to Σw = 1, 0 ≤ w ≤ cap

Sweeping the risk aversion γ from large to small traces the whole frontier without ever fixing a target return. The projection onto the constraint set is exact rather than a clip followed by a renormalisation, which matters more than it sounds: clipping quietly pushes every solution towards the cap and makes the frontier look better behaved than it is.

Weights are not risk

A holding's share of the portfolio's volatility is not its share of the money. The component contributions below add up to the portfolio volatility exactly, which is what makes them worth quoting: a small position in something wild can carry more risk than a large position in something dull.

Share of money against share of riskWeightRisk

The only test that counts

The weights are fixed at the end of the estimation window and held through 2016 to 2020. Nothing is re-estimated, nothing is re-optimised, and no holding is replaced. Every number below comes from days the optimiser never saw.

Underwaterhow far below the previous peak
Calendar yearsPortfolioFTSE 250

The index comparison is annual because the index history collected for this work was annual. Anywhere the portfolio is set against the FTSE 250 it is set against five numbers, not a daily series, and a five-point comparison is worth exactly as much as it sounds.

The security market line

The screen says which companies are sound. It says nothing about what return to ask of them, so the next step sets a required return for each one out of the market risk it carries,

E[rᵢ] = r_f + βᵢ(E[r_m] − r_f)

which is the dashed line below. It is a single-factor model and its limits are well known: beta is estimated from the past, and the line says nothing about size, value or momentum. It is here because it is a stated rule applied to every candidate the same way, which at this stage is worth more than a better model applied by eye.

The dots are what each share actually did over the year the fund was built on. The vertical distance between a dot and the line is the part of that year the model does not explain, and the striking thing is how large it is in both directions: a year of prices is not an estimate of expected return, it is one draw from a wide distribution. That is the whole case for the weighting step that follows, which reads the volatilities and takes no view on returns at all.

What the line asks for, and what 2015 delivered

The fund, as it went in

Ten holdings across nine sectors, weighted by the optimisation and left alone. The second chart is the one worth reading twice: a holding's contribution to the fund's market sensitivity is its weight times its beta, and one of these ten carries a negative beta, which is why the fund as a whole ends up at roughly half the market's.

Weightsas at 1 January 2016
Beta contributionweight × beta

Five years, reported the way a fund is reported

Return against the index, the excess over what the fund's market exposure alone would have earned, and both risk-adjusted ratios. Sharpe divides the excess by everything that moved; Treynor divides it only by the part the market explains. For a fund deliberately run at a low beta the two say different things, which is the reason to quote both.

α = R_p − [r_f + β_p(R_m − r_f)] · Sharpe = (R_p − r_f)/σ_p · Treynor = (R_p − r_f)/β_p

The rally it beat, and the crash it did not cushion

2017 · the rally

Half the beta, twice the rise

2020 · the crash

Diversification going missing exactly when it was needed

A fund at half the market's beta is supposed to lag a rally and cushion a fall. Across these five years it did neither. It beat the index in 2017 by a margin no amount of market exposure explains, which is stock selection and not a low beta doing the work; and in February and March 2020 it fell as hard as anything else, because correlations across almost everything went to one at the same moment. That is the standing complaint about diversification as a defence: it is measured in calm markets and spent in violent ones.

What this is not

1 · One window, one path

A single five-year run is one observation

Everything here rests on one estimation window and one hold-out period. A stronger answer would roll the whole exercise forward month by month over decades and report the distribution rather than the anecdote.

2 · A single factor

Beta captures market risk and nothing else

The screening test is CAPM, so size, value, profitability and momentum are all invisible to it. A five-factor version of the same screen would keep a different ten, and no claim here survives that being tried.

3 · ESG data is not one thing

Providers disagree with each other

Sustainability scores diverge sharply between vendors for the same company, so a cut at one threshold on one provider's scale is a rough instrument. It is applied here as a filter, not as a measurement.

4 · A simplified compliance test

Leverage, not the full standard

The Shariah screen here is a debt-to-equity limit plus sector exclusions. A full AAOIFI screen also tests interest income and cash purity, which needs statement-level data this exercise did not carry.

5 · Prices only, and no costs

No dividends in the path, no spread paid

The return series is built from closing prices, so income is missing from the compounding on a book yielding three to four per cent. Nothing pays commission, spread or stamp duty either, and holding the weights constant means trading every day.

6 · Survivorship

The universe is a list that survived

Candidates were drawn from an index membership list, so companies that left the index or the market are absent. That biases every backtest built this way upwards, including this one.

Solved, not stored

The covariance matrix, the frontier and the weights are computed in the browser from the daily prices in the repository. Move the cap and forty optimisations run again. There is no stored answer to drift away from the code that produced it.

An exact projection

The constraint set is handled by projecting onto it exactly, through a one-dimensional root find on the multiplier. Clipping and renormalising is the usual shortcut and it biases every weight towards the cap.

The estimation window is sealed

Weights are chosen using 2015 and nothing else. The hold-out years are never touched until the weights are fixed, which is the whole point and is the step most easily lost when a backtest is written in a hurry.

Checked against closed forms

The minimum-variance weights must equal Σ⁻¹1/(1′Σ⁻¹1) where that solution is interior. The variance of the realised return series must equal w′Σw. Equal-weight buy and hold must end at the average price relative. All three hold to machine precision or the tests fail.

Both conventions, stated

The fund held its weights constant, which is what the headline figures report. Buying once and never trading is a different strategy and is offered as a switch rather than left ambiguous, because on this data the two differ by about a fifth of the final value.

118 checks on the engine

Including the identities above, the projection tested against a grid search for nearest point, the frontier checked for dominated points, and a hold-out return reproduced from a figure computed independently in a spreadsheet.

Working together

Need a portfolio built and then honestly tested?

Screening, covariance estimation, constrained optimisation, and the out-of-sample work that says whether any of it survives contact with the years that follow. In Python or Excel, with the data and the code handed over.