Every risk model eventually writes down a sentence like these two things are independent. It takes four words. It deletes whole rows from a covariance matrix. And it rarely gets checked as carefully as the algebra that follows it.
I built this model for a stochastic processes course to see exactly what that sentence buys, and what it costs. It has three moving parts: a market return, a sector’s volatility that reacts to the market, and an outside shock that I declare independent of both. Every chart in this note runs in your browser from a seeded simulation, so you can break the assumptions yourself.
Start with the simplest market there is: one price and one source of noise.
One price, one source of noise
The paths above follow geometric Brownian motion, or GBM, the same model that sits underneath Black–Scholes. Think of it as compound growth with a steady hiss of random noise, where the noise scales with the price. A $100 stock and a $10 stock get the same percentage wobble.
There are two knobs. The drift sets the expected growth rate. The volatility sets the size of the hiss. is Brownian motion,Named after the botanist Robert Brown, who in 1827 watched particles from pollen grains jitter in water. Louis Bachelier used the same idea to model Paris bond prices in 1900, five years before Einstein explained the jitter. the mathematician’s version of a random walk: over any interval of length , its step is normally distributed with variance and independent of every step before it.
Drag volatility to zero and every path collapses onto the same smooth curve. Now turn it up, and notice what doesn’t happen: the paths don’t all grow faster. The spread of possible futures widens instead. Volatility isn’t a direction. It’s fog.
The equation has an exact solution:
That is the least intuitive term in this article. The short version: when a price wobbles symmetrically in percentage terms, losses hurt more than gains help,Fall 50%, then rise 50%, and $100 becomes $75. The two moves are the same size in percentage terms, but they don’t cancel. so the typical path drifts below the average one. The logarithm of the price feels that drag directly, which is why the drift of log-price differs from the expected growth rate of price. The derivation is below if you want it.
DerivationFrom price changes to log-returnsItô’s lemma · about 2 minutes
Apply Itô’s lemma to , with and :
Using gives:
Integrate from zero to , then exponentiate to recover the solution above. Over any interval , the log-return is therefore normal:
Daily steps use , so the daily standard deviation is .
What GBM gets right, and wrong on purpose
GBM gets two things right. Prices stay positive, and the model can be simulated exactly, with no discretisation error. It also gets at least one thing wrong on purpose: volatility is constant. Real markets have calm stretches and storms, and the storms cluster. Keep an eye on the rolling volatility view below. In GBM it hovers around one level by construction. When we meet real data later, it very much doesn’t.
The defaults are an annual drift of and volatility of . Resampling draws fresh noise. Moving the volatility slider keeps the same noise, so the only thing you’re seeing change is .
Three sources of trouble
A single lumps every kind of risk together. I wanted to pull them apart into three variables, each with its own story, so I could say precisely how they relate.
The market return, . Daily market log-returns follow a normal distribution. I calibrated it on S&P 500 data from 2020 to 2024: a daily mean of and a daily standard deviation of , or about a year.Annualising multiplies the daily standard deviation by , the number of trading days in a year: .
Sector volatility, . This one reacts to the size of the market’s move. Given , its logarithm is normal:
I use , and . These are illustrative parameters I chose, not estimates fitted to sector data. The absolute value is the interesting part: a 2% rally and a 2% crash rattle the sector by exactly the same amount.
Drag the market return in either direction and watch the sector’s distribution slide to the right. That symmetry is a convenient simplification and a real limitation. It’s a same-day magnitude effect. It doesn’t produce volatility that lingers for weeks, and it ignores the well-documented habit of crashes rattling markets more than rallies do.Usually called the leverage effect: volatility tends to rise more after a fall than after a gain of the same size.
The outside shock, . Some disturbances don’t diffuse. They arrive as jumps. I model them as a compound Poisson variable over one trading day:
A rate of means one jump every twenty trading days on average. The chance of at least one on a given day is , slightly under 5%, because a few days get more than one. Jump sizes are independent of each other and of how many jumps occur.
And here is the sentence this whole project is about: I also assume the shock is independent of the market and the sector together.
(The ↯ button in the first chart is something else, by the way: a fixed 20% drop on day 126 applied to every path. It’s a stress test for comparing the same futures with and without a sudden fall, not a draw from this model.)
What independence buys, and what it costs
Calling a shock “external” doesn’t make it statistically independent. A pandemic moves the market and every sector at once. I impose independence anyway, to see exactly what it buys:
The joint law then splits into a market–sector part and a shock part. Notice what doesn’t split: the market and the sector stay tangled, because the sector’s distribution depends on the market’s return.
There’s a small technical trap here. On most days no jump happens, so has a point mass at zero,Measure theorists call a point mass like this an atom. A density can describe a smooth spread of probability, but not a lump sitting on a single value. and a single ordinary density can’t describe it. The factorisation is safest written in terms of probability laws:
Independence also zeroes out every covariance involving :
Now the part that catches people out. The reverse doesn’t hold: zero covariance does not mean independence, and this model contains a perfect example. If market returns were symmetric around zero, and any function of would have zero covariance. Yet is literally computed from . You dragged that U-shape a minute ago.
A correlation near zero means no straight-line relationship. It does not mean nothing to do with each other.
The diagnostics below check that my simulator agrees with its own assumptions. That’s a necessary test and a weak one. A simulator can implement a wrong model flawlessly, and these checks can’t tell the difference.
Meeting real data
The calibration window is a greatest-hits compilation: the COVID crash, the recovery, the 2022 bear market and the 2023–24 rally. That variety is useful, but a single fitted volatility squeezes four very different regimes into one number.
Look at rolling volatility in that explorer: lumpy, clustered, nothing like the flat line GBM promises. It’s the best one-chart argument against constant volatility I know.
Two caveats about units. The project’s parameters came from daily observations, while this explorer uses a separately sourced monthly series, so their returns and volatilities won’t match exactly. Sector and shock parameters remain illustrative choices. And a daily log-return mean is not the GBM price drift divided by 252: the correction sits between them. The opening chart keeps as an illustrative price drift rather than claiming it reproduces the fitted daily mean.
Turning three risks into one number
To combine the three variables into a single loss, the project defines:
This is a stylised score in model loss units, not dollars and not a percentage return. A rising market lowers it. A shock in either direction raises it, through . With this sign convention a higher lowers the score, which is a particular exposure I chose, not a claim that volatility is good for anyone.
Two numbers summarise the tail. Value at Risk answers “how bad is a bad day?”: the loss threshold that a given share of outcomes stays below. Expected shortfall asks the follow-up question VaR can’t: “and when it’s worse than that, how bad on average?”That gap is why the Basel market-risk rules moved from 99% VaR to 97.5% expected shortfall: VaR says where the tail starts, but nothing about how deep it goes.
Both estimates come from the scenarios the explorer just generated, so they move as you change the seed or the sample size. That wobble is honest. A risk number computed from a finite sample has its own uncertainty, and it’s worth seeing it.
Independence pays off one last time in the variance. Every cross-term involving the shock vanishes:
At the default weights, the sector term dominates. Turn its weight down in the explorer and watch the attribution shift.
What I’d revisit
The independence assumption is the first thing I’d question. Real shocks move market returns and sector volatility together. Parameters drift. Volatility persists. A constant-volatility process with an independent jump component leaves every one of those mechanisms out.
Stochastic volatility would let uncertainty evolve over time. Regime switching would allow calm and turbulent market states. A richer joint model could relax the independence of the shock. I’d add them one at a time and compare each against this baseline, rather than piling on parameters at once.
What I valued most was following a single assumption all the way through: from one sentence, into the algebra, and out into the simulation. Independence deletes terms from a covariance matrix with a stroke of the pen. Whether those terms deserved to go is a question the pen can’t answer. That still takes data.
Reading further
The theoretical background includes Black and Scholes (1973), The Pricing of Options and Corporate Liabilities; Merton (1976), Option Pricing When Underlying Stock Returns Are Discontinuous; Heston (1993), A Closed-Form Solution for Options with Stochastic Volatility; and Cont (2001), Empirical Properties of Asset Returns: Stylized Facts and Statistical Issues.
Prepared for CSI 5138: Stochastic Processes. Interactive charts use seeded browser simulations. The historical chart uses monthly Shiller/FRED data distributed by the datasets project.