This article discusses three of the most interesting ways of modelling a random walk. Then we will construct a Monte Carlo simulation and overlay its distribution over the current SPY price. More interestingly, we have computed Monte Carlo on SPY prices from the prior 5 days & put a dot at where we are right now to see if we are at the extreme (distribution will tell that) or not.
Monte Carlo simulation is simply modelling thousands of random walks of the price and then at some point of time calculating the distribution of where those thousands of paths ended up. Take a look at Fig. 1. This simulation can be used to determine the probabilities of where over the amount of steps t, a value may end up.


As one might have guessed it, there are a lot of ways to simulating this movement. We can simulate it running around some mean, growing exponentially, being as volatile as stocks during financial crisis and so on- so what is the best? The most common approach is Geometric or Arithmetic Brownian Motion (“GBM”), (“ABM”). Difference between the two is the fact that GBM has a constant drift upwards, thus simulating a price for a growing stock, while ABM mean will stay close to the starting value at any time t. See the difference between the two shown in Fig. 2.


The formula itself for the Brownian Motion is not difficult, where the difference between arithmetic and geometric is simply in the drift component.
###
Variance = sigma * sigma
St. Deviation = sigma
dt = change
r = risk free rate
# Sigma = st. deviation
###
# Current Price
X[:,i]
# Drift Component
GBM = (r - 0.5 * sigma * sigma) * dt * X[:,i]
ABM = (r - 0.5 * sigma * sigma) * dt
# Volatility Component
St. Dev. * np.power(dt, 0.5)
# Randomness
Z[:, i]
Brownian Motion = Current Price + Drift + Volatility * Randomness
The ABM and GBM are very widely used due to the fact that they resemble a normal distribution and they work on a wide array of assets. However, we know that market is not following the normal distribution, hence a more interesting way can be used to simulate the prices that is closer to the real world.
A Jump Diffusion model takes the Brownian Motion and adds occasional jumps, to simulate a real-world scenario of… a missed earnings report! Or other events that lead to unexpected and sharp market behavior. This process should have fatter tails than our regular Brownian Motion models. We will not repeat the code as it is almost as simple as adding a jump component to the equation (It is Jump Amplitude * Occasional Jump * change in t (dt))
Notice a wider range of the movements & more volatility than in the standard Brownian Motion. Its current parameter was to make a small jump every 5% of steps.

Even if Jump Diffusion is an already more realistic way of modelling, there is a final one (of this article) approach called Ornstein-Uhlenbeck (“OU”) which’s spelling is more difficult than it is to understand the model itself. The idea behind it is that some time series, like interest rates, don’t really go away from the mean as the stock prices (where there is no mean whatsoever). So if we are trying to model interest rates, we would seek the Brownian Motion process to always revert to the mean. This is the core principle of the OU simulation. For visuals, refer to the Fig. 3.

As it is possible to see, the price quickly (depending on parameters) drops to the long term mean and keeps going back and forth around it after. We could use it for stocks by adding a Moving Average (“MA”) to the chart and defining a mean as the indicator, then researching how long it takes for the given stock to revert back to the MA and placing the OU algorithm on it.
With these Ideas in mind, I constructed a small script that takes SPY prices, calculates and makes a Monte Carlo simulation for the next 5 days (where every day has 32 steps (15min candles)), then draws a distribution of the Monte Carlo with +-2 St. Deviation marks as well as the mean. Additionally, I subtract 5 last days from the SPY to see how the distribution looked a week ago, so that I could compare the todays’ value to the distribution.
To be able to compare the algorithm correctly, we should train them on the exact data. See the code below:
# Generating a list full of random values
Z_single = np.random.normal(0.0,1.0,[NoOfPaths,NoOfSteps])
# Multiplying the same list to give to each algorithm
Z = np.tile(Z_single, (sims,1,1))
# Paths simulation
pathsr = GeneratePathsGBM(Z[0, :, :], settings)
pathsou = GeneratePathsOU(Z[1, :, :], settings)
pathsjdp = GenerateJDP(Z[2,:,:], settings)
After this is done and Monte Carlo has been done, we plot a single path for visual confirmation that prices indeed move how they are supposed to (OUs mean a.k.a. Moving Average was a little above the starting value; JDP has a few big jumps both up & down). We can then plot a distribution chart which demonstrates that while JDP has a small diffusion around the mean, it does have the fat tails which is what we are looking for. OUs mean is shifted upwards which is also what we are looking for, as price was below the Moving Average at that time. Refer to the Fig. 4.


Lastly, we plot the main charts to demonstrate a live Monte Carlo simulation.



So there we have it. We could use this indicator to see whether the values are on the extreme end of the spectrum. If they are, they may be a reversal or a range which could act as an entry opportunity.
Leave a Reply