Random Equity Returns

Overview


The standard quantitative model of equities is the Geometric Brownian Motion. (see quantitative equity modeling).
{% d S(t) = \mu S(t) dt + \sigma S(t) dW(t) %}
  • {% \mu %} - the arithmetic average return
  • {% \sigma %} - the volatility

The analysis assumes that there is an equity index that the retiree has their money invested in. That is, we ignore the fact that the retiree could be investing in multiple different stocks and just approximate it by a single index.

Tethering the Ito Growth Rate


The simple version of Ito process has some downsides when using it to model equities over the long term. That is, it is virtually unlimited to the upside. (that is, it can continue off to infinity) To some degree, this can make sense for shorter time frames. Bubbles do form where stocks can become detached from fundamentals. However, it is believed that equity prices are tethered to fundamental value over the long run, and value has an upper limit to how fast it can grow.

One way to tackle this issue is to simulate equities using a Brownian Bridge. The Brownian bridge is designed to achieve a pre-defined growth rate over the period of the simulation. In the case of simulating equities, you simulate a long period, such as 50 years, by setting the growth rate of the Brownian bridge to equal the long term growth rate of the equity market.

The trick to this simulating using the brownian bridge is set the simulation period longer than the period under consideration. That is, if you are simulating a period of 30 years, then choose the Brownian bridge period to be longer, say 50 or 60 years.


let ito = await import('/lib/statistics/simulations/v1.0.0/ito.mjs');
let wealth = 500000;
let init = Math.log(wealth);
let final = Math.log(wealth*Math.exp(0.1*50)); 
let withdrawal = 40000;
let data = [];
let log = Math.log(wealth);
for(let i=0;i<100;i++){ 
	let bridge = ito.brownianBridge(1000, ()=>0.15, final, init);
    bridge = bridge.map(p=>Math.exp(p));
    let index = -1;
	let sum = 0;
	for(let j=0;j<bridge.length;j++){
		bridge[j] = bridge[j] - sum;
        sum+=withdrawal;
        if(bridge[j]<=0) {
            index = j;
            break;
        }
	}
	data.push(index);
}
					
Try it!

Contents