Asset Returns Monte Carlo
Simulated one-day returns for three stocks, generated in your browser from a year of daily closing prices. The returns are drawn from a multivariate normal distribution fitted to the historical data — but the covariance matrix is never built.
Methodology
Start with a matrix R of historical log returns. Each row is a trading day, each column an asset, and each column has had its mean removed. With T days and N assets, R is T × N.
The usual way to simulate correlated normal returns is to estimate the N × N covariance matrix S, factor it as S = LL’ by Cholesky decomposition, and set r = Lz for a standard normal vector z of length N. That works, but it makes you form and factor S first.
You don’t have to. Draw one standard normal per day rather than per asset:
The covariance of is , which is the sample covariance of the historical returns. So has exactly the distribution you wanted, and was never constructed. Each draw costs O(TN) instead of the O(N³) of a factorization, and the gap widens as the number of assets grows relative to the length of the history. The method also stays well behaved when N exceeds T — the case where the sample covariance matrix is singular and Cholesky simply fails.
This is the approach described in Peter Benson and Peter Zangari, “A general approach to calculating VaR without volatilities and correlations”, RiskMetrics Monitor, Second Quarter 1997.
The same method, implemented six times over — in Python, Go, TypeScript, Rust, C++, and Java — is on GitHub at pbenson/var-without-covariance. All six share one specified random number generator, run against the same price data used on this page, and are tested to produce the same numbers.
Weighting the observations
Equal weighting treats a return from eleven months ago as being as informative as yesterday’s. Exponential weighting instead discounts day t by λ raised to its age in days, so recent market conditions dominate; RiskMetrics uses λ = 0.94 for daily data.
Weighting drops into the same expression. Scale row t of R by the square root of its weight w(t), normalized so the weights sum to one:
which gives covariance — the weighted sample covariance. Equal weighting is the special case , where the scale factor collapses to the familiar .
What is simulated
Each histogram below shows one-day continuously compounded returns, centered on zero. Dropping the historical drift is the usual convention for one-day risk: over a single day the estimated mean return is far smaller than the noise around it, so including it adds bias without adding information.
The three assets are simulated jointly — every point in the run shares one draw of z — so the correlations among them are preserved even though each panel shows only a marginal distribution.
251 aligned trading sessions, 2025-08-22 to 2026-08-21. Yahoo Finance chart API (adjusted close).
One shared axis, one hue: the three distributions differ only in width. Solid bars fall below the 5th percentile, left of the dashed one-day 95% value at risk.
What the histograms cannot show
Three near-identical bells, and yet these assets do not move independently. A marginal distribution is silent about joint behavior — and joint behavior is the whole reason a portfolio is not simply the sum of its risks. The matrix below is the same simulation, viewed as pairs.
The bars land on their ticks: r = R'z reproduces the historical correlations without ever estimating one. Sampling error is the only gap, and it shrinks as you raise the number of simulations.
What to look for
Switch from equal to exponential weighting and watch the histograms breathe: if the last few weeks have been calmer than the year as a whole, the distributions tighten and the 95% value at risk pulls in toward zero. That responsiveness is the point of exponential weighting, and it is also its cost — the estimate reacts to recent quiet just as eagerly as to recent turbulence.
Then watch the correlogram under the same switch. Volatility and correlation move independently: a pair can grow more volatile while becoming less correlated, which is why a risk estimate built from volatilities alone can be right about each asset and wrong about the portfolio.
Raise the simulation count and the bars converge on their ticks. That convergence is the claim being tested — sampling error shrinks, and what remains is the historical covariance structure, reproduced exactly, from a matrix that was never built.