# Random Walks Have Never Been Funnier: Drifted Brownian Motion in Python

We are not in power to predict the outcome of everything that surrounds us. For instance, we do not know the exact number of people that will attend an event or the exact noise that is going to occur in a signal or electric circuit. Rather than that, we can think of rough estimates and compute the likelihood of the possible scenarios. Thus, it is not surprising at all that the answers for many phenomena lie in the realm of randomness.

The stochastic processes play a major role in the modeling of many time-dependent systems. One particular and
well-studied process is the *Brownian Motion* that we already covered in the previous
blog post.
This process has fascinating properties and is very handy in quite different and interdisciplinary areas
including quantum physics, economics, or chemistry.

Having only a bare *Brownian Motion* is of no use and can be considered as a jitter. For this reason, in
this blog post, we drill more and attach some properties to the standard *Brownian Motion*. These properties
include the *drift* (also called *bias*) which drives the process in a particular direction and the
volatility which increases the fluctuation of the process. We leverage *Python's* numerical capabilities
to simulate such a process. On top of everything, we enhance the visual experience with multiple animations
using the *Matplotlib's* Animation API.

Having said that, let us begin and **stay tuned!**

## Towards more inclusive Brownian Motion

The standard *Brownian Motion* has an interesting set of features making its pattern recognizable
in plentiful domains. The standard, non-avoidable pattern that we all know is the price of some stock over
the course of time. For example let's take a look at the
S&P 500 stock market index
from 1950 until 2018, depicted in the figure below.

At first glance, we can instantly recognize the random Brownian pattern. However, it is clear that there are other components hidden inside, it is not just plain randomness. We can notice that the process has a tendency to grow over time with some local drops and fluctuations. Thus, we must account for these observations.

In order to reason about the directional tendency of the process, we can think of an additive component resembling a slope growing over time. In mathematical terms it means we have some constant, let's say \( \mu \) multiplying the time variable \( t \). In this case of modeling a stock price, we interpret \( \mu \) as a mean of returns.

We can easily see that the fluctuations appear randomly, thus they must be directly tied with the random component. Moreover, some of the drops are more severe while others are milder. That indicates only one thing, as the process randomly ascends or descends, we magnify these relative changes by multiplying with some constant, let's say \( \sigma \). This is how we incorporate the diffusion factor or vvolatility.

Having said all of this, we come to a formal definition of a drifted *Brownian Motion* with volatility, which
is:

In the next few sections, we will analyze separately and visually illustrate with meaningful animations these two properties.

## Drifted Brownian Motion in Python

To simulate the drifted *Brownian Motion* with volatility, we basically extend the work from the previous
blog post
where we defined only a bare *Brownian Motion*. Having this component ready-to-use, the *Python*
implementation of this extended process is given below:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import numpy as np def drifted_brownian_motion(mu, sigma, N, T, seed=42): """Simulates a Brownian Motion with drift. :param float mu: drift coefficient :param float sigma: volatility coefficient :param int N : number of discrete steps :param int T: number of continuous time steps :param int seed: initial seed of the random generator :returns list: drifted Brownian motion """ # set the seed np.random.seed(seed) # standard brownian motion W, _ = brownian_motion(N, T ,1.0) # the normalizing constant dt = 1. * T/N # generate the time steps time_steps = np.linspace(0.0, N*dt, N+1) # calculate the Brownian Motion with drift X = mu * time_steps + sigma * W return X |

A picture is worth a thousand words, an animation even more. Using the *Matplotlib's* Animation API we analyze
and illustrate the effect of these two components separately. The visual way of thinking helps us to actually
comprehend the concepts in a striking and captivating manner, or in other words citing the popular
cognitive psychologist Steven Pinker:

For us to go from “I think I understand” to “I understand,” we need to see the sights and feel the motions.

## Animated illustration of the drift

By setting the diffusion coefficient \( \sigma \) to 1, and varying the drift coefficient, we can observe the difference between a process with and without drift (colored with orange and blue respectively). In the animation below, as time passes by, the gap between the processes becomes larger and larger.

This is a perfect demonstration that a *Brownian Motion* without bias is just a jitter, which means it
is an important property.

## Animated illustration of the volatility

On the other hand, by fixing the drift coefficient \( \mu \) to 0 and varying the diffusion coefficient, we can examine the volatile behavior of the process. As depicted in the animation below, the two processes, one with volatility (in orange) and another one without (in blue), have exactly the same tendency over time. However, the fluctuations of the volatile motion are severe, dropping instantly from high to low values and vice-versa.

We confirm that the volatility completely changes the pace of random processes, which implies that it is a key component to consider.

The full source code behind this simulation and animations can be found on my GitHub repo, called Amusive Blogging and Coding (ABC).

If you liked what you just saw, it would be really helpful to subscribe to the mailing list below. You will not get spammed that's a promise! You will get updates for the newest blog posts and visualizations from time to time.

## Conclusion

In this blog post, we extended the bare *Brownian Motion* with two important properties: *drift* and
*volatility*. Through the animated visualizations, we observed the impact of these key components. We saw that
without drift, the motion is a pure noise without any trend. On the other side, the volatility makes the process
to keep the same trend but within a wider span of possible values.

This process has additional ingredients which make it more inclusive and aligned with the reality. However,
it still exhibits an additive behavior which is not a natural way of expressing growth. For this reason we need
another trick, to switch from additive to multiplicative changes and think in terms of rates of changes.
One such process is the *Geometric Brownian Motion* which we will cover next time.

## References

[1] Peter Olofsson, Mikael Andersson, "Probability, Statistics, and Stochastic Processes"

## Leave a comment