Ito Process - Simulations

Overview

An Ito process is an extension of the brownian motion. It is the workhorse of continuous time stochastic processes.
{% dX = u(x,t)dt + \sigma(x,t) dW %}

Simulating an Ito Process

The standard way to simulate an Ito process is to convert the Ito process equation above into a finite step equation.
{% \Delta X = u(x,t)\Delta t + \sigma(x,t) \Delta W %}
That is, the change in {% X %} is {% u(x,t) %} times the change in {% t %}, plus {% \sigma(x,t) %} times a random number drawn from a normal distribution with 0 mean and a variance of 1.

import random data = [0.0] u = 0.05 sigma = 0.1 deltaT = 0.01 for i in range(100): deltaX = u*deltaT+sigma*random.normalvariate(0, 1) data.append(data[len(data)-1] + deltaX)

Using the Ito Library

Simulating an Ito process (or set of processes) can be accomplished using the ito module, hosted in the davinci library.

from davinci.python import val import ito data = [] for i in range(5): sims=[{"value":p, "sim":str(i+1)} for p in ito.generate(300, 0, 0.05)] for x in sims: data.append(x) val.set('data',data);

Where the ito.py script is given here:

import random def generate(iterations, time=0, vol=0.1, init=0, generator=None): def gen(): return random.normalvariate(0,1) if generator == None:generator = gen if not callable(time): _time = time def func(ans): return _time time = func if not callable(vol): _vol = vol def func2(ans):return _vol vol = func2 ans = [init] for i in range(iterations): dt = time(ans) cvol = vol(ans) ans.append(ans[len(ans)-1]+dt + generator()*cvol) pass return ans

Simulating and Ito Process

The following shows a set of simulations of a specified Ito Process.

Correlated Ito Process

To generate a set of correlated Ito processes requires generating correlated guassian variables. Generating correlated guassians are provided for by the generateMultiple method of the ito library. The third parameter is a function that returns the covariance matrix.

def generate_multiple(iterations, time, vol, init): rng = np.random.default_rng(seed=42) if not callable(time): _time = time def func(ans): return _time time = func if not callable(vol): _vol = vol def func2(ans):return _vol vol = func2 means = [0 for p in init] ans = [init] for i in range(iterations): dt = time(ans) cvol = vol(ans) samples = rng.multivariate_normal(mean=means, cov=cvol, size=1) for item in samples: last = ans[-1] next = [] for index,val in enumerate(item): next.append(last[index]+dt[index]+val.item()) pass ans.append(next) pass pass return ans

Geometric Brownian Motion

When simulating a Geometric Brownian Motion, care must be taken. The generic formula for a GBM is
{% d X(t) = \alpha X(t) dt + \sigma X(t) dW(t) %}
The important thing to note here is that the coefficients of each term are variable (that is, they each include an X(t) term). When running the simulation, we need to provide functions for the drift and volatility terms that multiply by the last value in the series.

from davinci.python import val import ito alpha = 0.01 vol = 0.2 mu = lambda series: alpha * series[-1] sigma = lambda series: vol * series[-1] data = [] for i in range(5): sims=[{"value":p, "sim":str(i+1)} for p in ito.generate(300, mu, sigma)] for x in sims: data.append(x) val.set('data',data)


There is a complication with this code however. Because we are discretizing the time interval, the value of X could go negative at some point, whereas in the theoretical geometric brownian motion, it cannot. The better way to run this simulation is to recognize the alternative way to write a geometric brownian motion as
{% d log X(t) = r dt + \sigma dW(t) %}
That is, we simulate the log of X, instead of X itself. Then to translate back, we just need the following:

sims = [{"value":math.exp(p), "sim":str(i+1)} for p in sims]


The full code is provided.

import ito import math alpha = 0.01 vol = 0.2 mu = lambda series: alpha * series[-1] sigma = lambda series: vol * series[-1] data = [] for i in range(5): sims=[{"value":math.exp(p), "sim":str(i+1)} for p in ito.generate(300, mu, sigma)] for x in sims: data.append(x)

Ito Script

For a listing of the complete ito.py script, see ito.py