Some Stochastic Models

Simulation of some basic stochastic processes in Python such as simple random walk, Brownian motion, Brownian bridge, Brownian motion with drift and volatility, and Geometric Brownian motion.

import pandas as pd  
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns  
from random import sample
#!pip install mplcyberpunk
#import mplcyberpunk
#plt.style.use("cyberpunk")
sns.set()
class StochasticSimulation:
  
    def __init__(self, steps=100, n_times=1, t=1):
        self.steps = steps
        self.n_times = n_times 
        self.dt = t  / steps
    
    
    def SimpleRandomWalk(self, p):
        # creating array
        rw = np.zeros( (self.n_times, self.steps+1))
        # initiate the loop
        for j in range(rw.shape[1]-1):
            for i in range(rw.shape[0]):
                rw[i][j+1] = rw[i][j] + np.random.choice([-1,1], p=[1-p, p])#sample([-1,1], 1)
    
        df = pd.DataFrame(rw) 
        return df 
    
    def BrownianMotion(self):
        # creating array
        bm = np.zeros( (self.n_times, self.steps+1))
        # initiate the loop
        for j in range(bm.shape[1]-1):
            for i in range(bm.shape[0]):
                bm[i][j+1] = bm[i][j] + np.random.normal(size=1)
    
        df = pd.DataFrame(bm)  
        return df

    def BrownianBridge(self):
        # creating Brownian motion
        bm = np.zeros( (self.n_times, self.steps+1))
        # initiate the loop
        for j in range(bm.shape[1]-1):
            for i in range(bm.shape[0]):
                bm[i][j+1] = bm[i][j] + np.random.normal(size=1)
        # array of Brownian Bridge
        bb = np.zeros( (self.n_times, self.steps+1))
        # initiate the loop
        for j in range(bb.shape[1]-1):
            for i in range(bb.shape[0]):
                bb[i][j+1] = bm[i][j] + -(j/self.steps)*bm[i][self.steps]
    
        df = pd.DataFrame(bb)  
        return df

    def BrownianMotionDrift(self, mu, sigma):
        # creating array
        bmd = np.zeros( (self.n_times, self.steps+1))
        # initiate the loop
        for j in range(bmd.shape[1]-1):
            for i in range(bmd.shape[0]):
                bmd[i][j+1] = bmd[i][j] + mu*self.dt  + sigma*np.sqrt(self.dt)*np.random.normal(size=1)
    
        df = pd.DataFrame(bmd)  
        return df
        
    def GeometricBrownianMotion(self, S0, alpha, beta):
        # creating array
        gbm = np.zeros( (self.n_times, self.steps+1))
        # initiate the loop
        for j in range(gbm.shape[1]):
            for i in range(gbm.shape[0]):
              if(j == 0):
                gbm[i][j] = S0
              else:
                gbm[i][j] = gbm[i][j-1]*np.exp(np.random.normal(loc=(alpha - (beta**2)/2)*self.dt, scale=np.sqrt(self.dt)*beta, size=1)) 
    
        df = pd.DataFrame(gbm)  
        return df

Movimiento Browniano

Definición:

Un proceso estocástico \(\{B(t), t\geq 0\}\) se dice que es un movimiento Browniano si:

1.- \(B(0) = 0\)

2.- \(\{B(t), t\geq 0\}\) tiene incrementos independientes y estacionarios.

3.- Para \(t>0\), B(t) tiene distribución normal con media cero y varianza \(t\).

Movimiento Browniano (1-D)

# simulación
steps = 10000  # pasos
n = 100       # trayectorias
bm_sim = StochasticSimulation(steps=steps, n_times=n).BrownianMotion()


# gráfico
plt.figure(figsize=(16,7))
for i in range(bm_sim.shape[0]):
    plt.plot(list(bm_sim.columns), bm_sim.iloc[i][:], color='grey')
plt.title('Brownian Motion Simulation: {} steps and {} paths'.format(steps, n))
plt.xlabel('Time')
#mplcyberpunk.add_glow_effects()
plt.show()

Movimiento Browniano (2-D)

# Brownian Bridge
plt.figure(figsize=(16,10))
for i in range(bm_sim.shape[0]):
    plt.plot(bm_sim.iloc[0][:], bm_sim.iloc[1][:], color='blue', linewidth=0.4)
    plt.plot(bm_sim.iloc[0][:], bm_sim.iloc[1][:], 'o', color='black', markersize=0.4)
plt.title('Brownian Motion Simulation: {} steps'.format(steps))
plt.xlabel('Time')
#mplcyberpunk.add_glow_effects()
plt.show()

Puente Browniano

Definición:

Un procesos estocástico \(\{X(t)= B(t) - \frac{t}{T} B(T) , 0 \leq t \leq T \}\), es un puente Browniano si satisface las siguientes propiedades:

1.- \(X(0)=X(T)=0\)

2.- \(X(t)\) se distribuye como una normal con media cero y varianza \(t(1-t/T)\)

$$E(X(t)) = 0$$, y $$Var(X(t)) = t(1-t/T)$$

3.- \(Cov(X(s), X(t)) = min(s, t) - \frac{st}{T}\)

Puente Browniano (1-D)

# simulación
steps = 100000  # número de pasos
n = 100         # número de trayectorias
bm_sim = StochasticSimulation(steps=steps, n_times=n).BrownianBridge()


# gráfico
plt.figure(figsize=(16,7))
for i in range(bm_sim.shape[0]):
    plt.plot(list(bm_sim.columns), bm_sim.iloc[i][:], color='grey')
plt.title('Brownian Bridge Simulation: {} steps and {} paths'.format(steps, n))
plt.xlabel('Time')
#mplcyberpunk.add_glow_effects()
plt.show()

Puente Browniano (2-D)

# Brownian Bridge
plt.figure(figsize=(16,10))
for i in range(bm_sim.shape[0]):
    plt.plot(bm_sim.iloc[0][:], bm_sim.iloc[1][:], color='blue', linewidth=0.4)
    plt.plot(bm_sim.iloc[0][:], bm_sim.iloc[1][:], 'o', color='black', markersize=0.4)
plt.title('Brownian Bridge Simulation: {} steps'.format(steps))
plt.xlabel('Time')
#mplcyberpunk.add_glow_effects()
plt.show()

Caminata aleatoria simple

Definición:

La caminata aleatoria en \(\mathbb{Z}\), es la más simple de todas, de ahí su nombre. \(X_i\) toma valores en \(\{−1,1\}\), y la caminata comienza en \(S_n = 0\) y está definida para valores enteros. Las probabilidades de ir a la derecha o a la izquierda se denotan como \(P(X_i=1)\) y \(P(X_i=-1)\), respectivamente, con las siguientes probabilidades para el caso de una caminata aleatoria simétrica:

\begin{equation*} P(X_i=1)=P(X_i=−1)=1/2 \end{equation*}

Considerando el caso más general, se tiene que el caminante puede ir a la derecha con probabilidad \(p\), y a la izquierda con probabilidad \(1-p\)

\begin{equation*} P(X_i=1)=p \ \text{ y } \ P(X_i=−1)=1−p \end{equation*}

Caminata aleatoria simple (1-D)

# simulación
steps = 100000  # número de pasos
n = 100         # número de trayectorias
bm_sim = StochasticSimulation(steps=steps, n_times=n).SimpleRandomWalk(p=0.5)


# gráfico
plt.figure(figsize=(16,7))
for i in range(bm_sim.shape[0]):
    plt.plot(list(bm_sim.columns), bm_sim.iloc[i][:], color='grey')
plt.title('Brownian Bridge Simulation: {} steps and {} paths'.format(steps, n))
plt.xlabel('Time')
#mplcyberpunk.add_glow_effects()
plt.show()

Caminata aleatoria simple (2-D)

# Brownian Bridge
plt.figure(figsize=(16,10))
for i in range(bm_sim.shape[0]):
    plt.plot(bm_sim.iloc[0][:], bm_sim.iloc[1][:], color='blue', linewidth=0.4)
    plt.plot(bm_sim.iloc[0][:], bm_sim.iloc[1][:], 'o', color='black', markersize=0.4)
plt.title('Simple Random Walk Simulation: {} steps'.format(steps))
plt.xlabel('Time')
#mplcyberpunk.add_glow_effects()
plt.show()

Movimiento Browniano con deriva y volatilidad

Definición:

Sea \(\{B(t), t \geq 0\}\) un movimiento Browniano estándar. El procesos estocástico \(\{X(t)= \mu t + \sigma B(t), t \geq 0\}\) recibe el nombre de movimiento Browniano con coeficiente de deriva (drift) \(\mu\), y coeficiente de volatilidad (o difusión) \(\sigma\).

Poposición:

La distribucuión de \(X(t)\) es normal con media \(\mu t\), y varianza \(\sigma^2 t\). Y la covarianza entre \(X(s)\) y \(X(t)\) es $$Cov(X(s), X(t)) = \sigma^2 min(s, t)$$.

Movimiento Browniano con coeficiente de deriva y volatilidad (1-D)

# simulación
steps = 100000     # pasos
n = 100         # trayectorias
bmd_sim = StochasticSimulation(steps=steps,n_times=n).BrownianMotionDrift(mu=1.4, sigma=0.8)


# gráfico
plt.figure(figsize=(16,7))
for i in range(bmd_sim.shape[0]):
    plt.plot(list(bmd_sim.columns), bmd_sim.iloc[i][:], color='grey', linewidth=0.4)
plt.title('Brownian motion with drift and volatility Simulation: {} steps and {} paths'.format(steps, n))
plt.xlabel('Time')
#mplcyberpunk.add_glow_effects()
plt.show()

Movimiento Browniano con coeficiente de deriva y volatilidad (2-D)

# Brownian motion with drift and volatility
plt.figure(figsize=(14,10))
for i in range(bmd_sim.shape[0]):
  plt.plot(bmd_sim.iloc[0][:], bmd_sim.iloc[1][:], color='black', linewidth=0.4)
  plt.plot(bmd_sim.iloc[0][:], bmd_sim.iloc[1][:], 'o', color='blue', markersize=0.4)
plt.title('Brownian motion with drift and volatility Simulation: {} steps'.format(steps))
plt.xlabel('Time')
plt.show()

Movimiento Browniano Geométrico

Definición:

Sea \(\{W(t), t\geq 0\}\) es un movimiento Browniano estándar (Proceso de Wiener), el proceso estocástico \(\{S(t)= S(0) \exp\{(\mu t - \sigma^2/2)t + \sigma W(t)\}, S(0)=S_0, t\geq 0\}\) es un movimiento Browniano geométrico con valor esperado y varianza:

\begin{eqnarray} E[S(t)] & = & S(0) e^{\mu t}, \ \ y \\ Var(S(t)) & = & S(0)^2 \left(e^{2\mu t}\right) \left(e^{\sigma^2 t} -1 \right) \end{eqnarray}

Movimiento Browniano Geométrico (1-D)

# simulation
steps = 100000    # número de pasos
n = 100         # número de trayectorias
S0 = 7.1
alpha=0.3
beta=0.08
gbm_sim = StochasticSimulation(steps=steps, n_times=n).GeometricBrownianMotion(S0=S0, alpha=alpha, beta=beta)


# Geometric Brownian motion 
plt.figure(figsize=(16,7))
for i in range(gbm_sim.shape[0]):
    plt.plot(list(gbm_sim.columns), gbm_sim.iloc[i][:], color='grey')
plt.title('Geometric Brownian Motion Simulation: {} steps and {} paths'.format(steps, n))
plt.xlabel('Time')
#mplcyberpunk.add_glow_effects()
plt.show()

Movimiento Browniano Geométrico (2-D)

# Geometric Brownian Motion
plt.figure(figsize=(14,10))
for i in range(gbm_sim.shape[0]):
  plt.plot(gbm_sim.iloc[0][:], gbm_sim.iloc[1][:], color='black', linewidth=0.4)
  plt.plot(gbm_sim.iloc[0][:], gbm_sim.iloc[1][:], 'o', color='blue', markersize=0.4)
plt.title('Geometric Brownian motion Simulation: {} steps'.format(steps))
plt.xlabel('Time')
plt.show()
Julio Cesar Martinez
Julio Cesar Martinez

My research interests include statistics, stochastic processes and data science.