From-Scratch Build · Reinforcement Learning

Uncorrelated Returns

The closest thing to a free lunch in investing: stack fifteen or twenty return streams that don't move together, and the portfolio's risk collapses while its return holds. I rebuilt the engine that finds and combines them from scratch to understand why diversification — done honestly — is the only edge that compounds.

PythonNumPy / pandasPortfolio theory CorrelationRisk parityBacktesting

What it is

The "Holy Grail" of investing, in code

The premise is one chart that famously reshaped how a generation of investors thinks: as you add return streams that are uncorrelated with each other, your risk per unit of return falls off a cliff. Going from one bet to ten roughly cuts volatility in half — for the same expected return. Add more genuinely independent bets and the curve keeps dropping.

This build is the machinery behind that idea: take a universe of assets and strategies, measure how their returns actually co-move, and assemble the mix that squeezes the most return out of every unit of risk. The hard part isn't the math — it's being honest about how little real independence there is in a market that all sells off together when it panics.

~15
the number of truly uncorrelated bets it takes to cut portfolio risk by roughly 80% — the target the whole engine is built around.

The stack

From price series to allocation

A small, sharp toolkit — the value is in the statistics, not the framework count.

data

Return series

Daily price histories turned into return streams — the raw material every other step operates on.

core

Correlation matrix

The heart of the project: how every stream moves relative to every other. Low off-diagonal numbers are the prize.

sizing

Risk parity

Weight each bet by its risk contribution, not its dollar size, so no single stream quietly dominates the portfolio.

numerics

NumPy / pandas

Vectorised covariance, rolling windows and matrix algebra — fast enough to re-optimise as the data updates.

validation

Backtester

Walk the allocation forward through history and measure realised volatility, drawdown and Sharpe — not just the promised ones.

output

Efficient frontier

Plot risk against return for thousands of candidate mixes and read off where diversification stops paying.

Architecture

How an allocation is found

Each rebalance walks the same pipeline, from raw returns to a target weight vector:

  1. Ingest

    Load each asset's price history and convert it into a clean stream of periodic returns.

  2. Measure co-movement

    Compute the covariance and correlation matrix across all streams over a rolling window.

  3. Score independence

    Rank candidates by how little they add to existing risk — favouring genuinely uncorrelated additions.

  4. Optimise weights

    Solve for the allocation that maximises return per unit of risk under risk-parity constraints.

  5. Backtest & report

    Replay the weights through history and surface realised Sharpe, volatility and worst drawdown.

Reflection

What rebuilding it taught me