01 · THE DECISIONTwo questions every portfolio must answer
Before anyone debates models, a portfolio has to answer two questions: how should the money be split, and how much of it could disappear in a bad month? The first is an allocation decision; the second is the risk number that makes the allocation honest. This project answers both — and then stress-tests the second answer by computing it three independent ways, because a risk number you've only computed one way is a number you haven't questioned.
02 · MEASUREThe data, made comparable
Daily Bloomberg closing prices (PX_LAST) for six assets spanning deliberately different risk profiles: GOOGL, AMZN, TSLA (growth equities), Goldman Sachs (financials), BNDX (an international bond ETF — the ballast) and the DAX index. The DAX trades in euros, so every observation was converted to USD using the matching EUR/USD rate — skip that step and you're measuring currency noise as equity risk.
Prices were resampled to month-end and converted to simple monthly returns, alongside a synthetic risk-free savings asset compounding at 3.5% a year — the benchmark every risky allocation has to beat to justify its existence.
03 · EXPLOREKnow your assets before you weight them
Diversification lives in the correlation structure, so the full pairwise matrix was computed from the monthly returns:
| GOOGL | AMZN | TSLA | GS | BNDX | DAX | |
|---|---|---|---|---|---|---|
| GOOGL | 1.00 | 0.66 | 0.37 | 0.46 | 0.42 | 0.53 |
| AMZN | 0.66 | 1.00 | 0.43 | 0.30 | 0.42 | 0.45 |
| TSLA | 0.37 | 0.43 | 1.00 | 0.30 | 0.20 | 0.35 |
| GS | 0.46 | 0.30 | 0.30 | 1.00 | 0.20 | 0.68 |
| BNDX | 0.42 | 0.42 | 0.20 | 0.20 | 1.00 | 0.33 |
| DAX | 0.53 | 0.45 | 0.35 | 0.68 | 0.33 | 1.00 |
04 · MODELTracing the efficient frontier
With expected returns, volatilities and the covariance matrix estimated, 10,000 random portfolios were simulated across the risky assets — each a different weighting, each scored on return, risk and Sharpe ratio against the monthly risk-free rate. Plotted together they trace the Markowitz frontier: the upper-left edge is the set of portfolios you can't improve without paying for it in risk. Portfolio return is the weighted average of asset returns; portfolio risk is not — it's √(w′Σw), where the covariance matrix Σ lets offsetting movements partly cancel. That quadratic term is why diversification works, and why the cloud bows toward the top-left instead of forming a straight line.
05 · DECIDEValue-at-Risk, three ways
Now the risk number. One-month 95% VaR answers: what loss should we not expect to exceed more than one month in twenty? Three methods, three philosophies:
- Normal (parametric) — 7.60%. VaR = −(μ + z0.05σ) with constant volatility and normally distributed returns. Clean, fast, and blind to everything interesting about markets.
- GARCH(1,1) — 7.74%. Volatility becomes time-varying: the model conditions on recent turbulence, so the risk estimate responds to current market state. The fitted conditional-volatility series spikes exactly where it should — early 2020 (COVID) and late 2022 — confirming it tracks real stress, not noise.
Which number goes in the report? My answer: the range, with the assumptions attached. Presenting 7.60% alone smuggles "volatility is constant and returns are normal" past the reader. The spread between methods is the finding — it quantifies how much the risk estimate depends on what you assumed, which is exactly what a decision-maker deserves to see before sizing a position.
06 · EXTENDSimulating futures, not summarising the past
To complete the picture, Geometric Brownian Motion paths were simulated from the portfolio's drift and volatility — ten possible one-year futures fanning out from the same starting point under the standard stochastic price model dS = μS dt + σS dW.
07 · TRANSFERWhy a growth analyst does quant finance
Volatility clustering — calm periods and turbulent periods that persist — is the same statistical animal whether the series is portfolio returns or the UK electricity prices in my battery trading project. Distributions, tail risk, confidence intervals and “how wrong could this number be?” are the foundation under every experiment readout and revenue forecast I produce at work. This project is where that foundation got load-tested.
Stack: Python · pandas · NumPy · SciPy · arch (GARCH) · matplotlib / seaborn · Bloomberg data · Markowitz mean-variance · Monte Carlo · GBM