Brownian motion with drift and volatility

Brownian motion with drift and volatility in R.

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 volatilidad (o difusión) \(\sigma\).

Proposició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)$$

# Función para generar trajectorias del movimiento Browniano con coeficiente de deriva y volatilidad
simMB.drift <- function(mu, sigma, t, nSteps, nReps){
  dt <- t/ nSteps
  # loop
  simMat <- matrix(nrow=nReps, ncol=(nSteps+1))
  simMat[ ,1] <- 0
  for(i in 1:nReps){
    for(j in 2:(nSteps + 1)){
      simMat[i,j] <- simMat[i,j-1] + mu*dt  + sigma*sqrt(dt)*rnorm(1,0,1)
    }
  }
  names <- c('Rep', sapply(0:nSteps, function(i) paste('S',i,sep='')))
  df <- data.frame('Rep'=1:nReps, simMat)
  colnames(df) <- names

  return(df)
}

Ejemplo 1: Una trayectoria

# Ejemplo
t <- 1
mu <- 0.3   
sigma <- 0.06
nSteps <- 1000   # número de pasos
nReps <- 1       # número de trayectorias

bm1 <- simMB.drift(mu, sigma, t, nSteps, nReps)
#print(bm1)

# data
df <- bm1 %>% 
  pivot_longer(!Rep, names_to='Step', values_to='value') %>%
  mutate('t' = as.numeric(substring(Step,2,10))*t/nSteps,
         Rep = as.character(Rep))

# Valores teóricos
moments <- data.frame('t1'=seq(from=0, to=1, length=nSteps+1)*t) %>%
  mutate('mean' = mu*t1,
          'sd_inf' = mean - 2*sqrt(sigma^2*t1),
          'sd_sup' = mean + 2*sqrt(sigma^2*t1)) 
head(df)
## # A tibble: 6 × 4
##   Rep   Step    value     t
##   <chr> <chr>   <dbl> <dbl>
## 1 1     S0    0       0    
## 2 1     S1    0.00119 0.001
## 3 1     S2    0.00129 0.002
## 4 1     S3    0.00146 0.003
## 5 1     S4    0.00194 0.004
## 6 1     S5    0.00561 0.005
# Gráfico 
options(repr.plot.width=16, repr.plot.height=8)
p1 <- ggplot(df, aes(x=t, y=value, color=Rep)) + 
  geom_line()  + 
  geom_line(moments, mapping=aes(x=t1,y=mean),col='red',size=0.7, alpha=0.5) +
  geom_line(moments, mapping=aes(x=t1,y=sd_sup),col='blue',size=0.7,linetype = "dashed") +
  geom_line(moments, mapping=aes(x=t1,y=sd_inf),col='blue',size=0.7,linetype = "dashed") +
  labs( title = paste(nReps, "Trajectorias del MB")) +
  theme(legend.position = "none") +
  scale_colour_grey(start = 0.2,end = 0.8) 
  #coord_cartesian(xlim = c(0, tmax))
p1

Ejemplo 2: Diez mil trayectorias

# valores
t <- 1
mu <- 0.3
sigma <- 0.06
nSteps <- 1000   # número de pasos
nReps <- 10000   # número de trayectorias

bm1 <- simMB.drift(mu, sigma, t, nSteps, nReps)
#data
df <- bm1 %>% 
  pivot_longer(!Rep, names_to='Step', values_to='value') %>%
  mutate(t = as.numeric(substring(Step,2,10))*t/nSteps,
         Rep = as.character(Rep))

# Valores teóricos
moments <- data.frame('t1'=seq(from=0, to=1, length=nSteps+1)*t) %>%
  mutate('mean' = mu*t1,
          'sd_inf' = mean - 2*sqrt(sigma^2*t1),
          'sd_sup' = mean + 2*sqrt(sigma^2*t1)) 

# Gráfico del Movimiento Browniano con coeficiente de deriva y volatilidad
options(repr.plot.width=16, repr.plot.height=8)
p1 <- ggplot(df, mapping=aes(x=t, y=value, color=Rep)) + 
  geom_line() + 
  geom_line(moments, mapping=aes(x=t1,y=mean),col='red',size=0.7, alpha=0.5) +
  geom_line(moments, mapping=aes(x=t1,y=sd_sup),col='blue',size=0.7,linetype = "dashed") +
  geom_line(moments, mapping=aes(x=t1,y=sd_inf),col='blue',size=0.7,linetype = "dashed") +
  labs( title = paste(nReps, "Trayectorias del MB")) +
  theme(legend.position = "none") +
  scale_colour_grey(start = 0.2,end = 0.8) 
  #coord_cartesian(xlim = c(0, tmax))
p1

Ejemplo:

Para \(\mu=0.3\), y \(\sigma = 0.06\) obtener

  • \(E[X(10)]\) = ?
  • \(Var(X(10))\) = ?
  • \(Cov(X(10, 20))\) = ?

Solución teórica:

  • \(E[X(10)] = \mu t = 0.3*10 = 3\)
  • \(Var(X(10)) = \sigma^2 * t = 0.036*10 = 0.036\)
  • \(Cov(X(10), x(20)) = \sigma^2 min(s, t) = 0.036*10 = 0.036\)

Simulación:

Dado que el proceso está escalado en el intervalo \([0, 1]\), las estimaciones deben multiplicarse por el número de pasos generados, es decir por \(nSteps\).

# Valor esperado  E[X(10)]
mean(bm1[,10+1])*nSteps
## [1] 2.713745
# Varianza
var(bm1[,10+1])*nSteps
## [1] 0.03206319
# Covarianza
cov(bm1[,10+1], bm1[,20+1])*nSteps
## [1] 0.03236365

Movimiento Browniano con coeficiente de deriva y volatilidad en dos dimensiones

#  Movimiento Browniano con coeficiente de deriva y valatilidad en dos dimensiones
plot.MB2d_drift <- function(base, n.steps){
  
  df <- base
  df_2d <- df  %>%
    gather(key='t',value='valor',-Rep) %>%
    filter(Rep == 1 | Rep== 2) %>%
    spread(Rep, valor)  %>%
    rename(Rep1 = '1', Rep2='2')%>%
    mutate(t = as.numeric(substring(t,2,10))) %>%
    arrange(t) %>%
    filter(t <= n.steps)
  b2 <- ggplot(df_2d,aes(x=Rep1,y=Rep2))+
    geom_point(color="blue") +
    geom_point(df_2d%>%filter(t == 0),mapping=aes(x=Rep1,y=Rep2), size=4, color="green") +
    geom_point(df_2d%>%filter(t == max(t)),mapping=aes(x=Rep1,y=Rep2), size=3, color="red") +
    geom_path() +
    theme(axis.title.x = element_blank(),
          axis.title.y = element_blank(),
          axis.text.x=element_blank(),
          axis.text.y=element_blank(),
          axis.ticks.x=element_blank(),
          axis.ticks.y=element_blank()
          )
  return(b2)
}

Ejemplo 1: Diez mil pasos

# Ejemplo 1:
t <- 1
mu <- 0.1
sigma <- 0.06
nSteps <- 10000   # número de pasos
nReps <- 10

# Gráfico
options(repr.plot.width=14, repr.plot.height=10)
df <- simMB.drift(mu, sigma, t, nSteps, nReps)
p3 <- plot.MB2d_drift(df, nSteps)
p3 
Julio Cesar Martinez
Julio Cesar Martinez

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