9 votos

Simular Movimiento Browniano Geométrico correlacionado en el lenguaje de programación R

En respuesta a esta pregunta: ¿Cómo simular el movimiento browniano geométrico correlacionado para n activos?

Una de las respuestas proporciona una implementación en MATLAB: http://www.goddardconsulting.ca/matlab-monte-carlo-assetpaths-corr.html

Intenté trasladar este código al lenguaje de programación R. La implementación es:

# Parámetros de entrada:
S0 <- c(50, 48)
mu <- c(0.03, 0.03)
sig <- c(0.05, 0.05)
corr <- cbind(c(1,0.1), c(0.1,1))
dt <- 1/365
steps <- 10000
nsims <- 100

# Obtener el número de activos:
nAssets <- length(S0)

# Calcular el drift:
nu <- mu - sig * sig/2

# Realizar una factorización de Cholesky en la matriz de correlación:
R <- chol(corr)

# Alocar previamente la salida:

S <- array(1, dim=c(steps+1, nsims, nAssets))

# Generar secuencias y caminos aleatorios correlacionados:

for(idx in 1:nsims)
{
  # generar secuencia aleatoria no correlacionada 
  x <- matrix(rnorm(steps * nAssets), ncol = nAssets, nrow = steps)

  # correlacionar las secuencias 
  ep <- x %*% R

  # generar posibles caminos 

  S[,idx,] <- rbind(rep(1,nAssets), apply(exp(matrix(nu*dt,nrow=steps,ncol=2,byrow=TRUE) + (ep %*% diag(sig)*sqrt(dt))), 2, function(x) cumprod(x)) ) %*% diag(S0)
}

# PRUEBA: Calcular la correlación de muestra promedio 
sum = 0
for(i in 1:nsims) 
{
  sum = sum + cor(S[,i,1], S[,i,2])
}
correlacionMuestra = sum / nsims 

Para probar si la implementación funciona como se prometió, calculo la correlación de muestra promedio entre dos activos en muchas simulaciones. Por la ley de los grandes números, la correlación de muestra debería estar bastante cerca de la matriz de correlación teórica proporcionada como parámetro de entrada. En el ejemplo proporcionado, la correlación de muestra entre los dos activos debería estar bastante cerca de 0.1 en promedio. Sin embargo, este no es el caso. Por lo tanto, debe haber un problema en el código R proporcionado. También probé el código MATLAB en un simulador de MATLAB en línea gratuito (http://octave-online.net/): dio el resultado correcto para la correlación de muestra promedio entre los activos. Por lo tanto, debe haber un problema de traslado, que no logro determinar. ¿Puedes identificar el problema?

3voto

Kris Puntos 3781

¿Ya lo has resuelto? Por ejemplo en el parámetro de drift, el dt debe ser un vector de tiempo de 0 a 1 por dt.

Mi código es:

  GBM<-apply(BM,2,function(x) 100*exp((cumsum((r-0.5*sigma*sigma)*time)+sigma*x)))

donde estoy utilizando GBM en Movimiento Browniano ya acumulado (x).

1voto

user984260 Puntos 146

Puedes usar una distribución normal estándar multivariante para obtener los resultados deseados.

require(mvtnorm)
require(matrix)

Matriz.de.Covarianza <- # tu matriz de covarianza aquí
Deriva <- # tus términos de deriva aquí
Vol <- # tus términos de volatilidad aquí
n <- # número deseado de muestras
z <- rmvnorm(n, simga=nearPD(Matriz.de.Covarianza), method="chol")
GBM <- Deriva + z * Vol

Si no deseas asumir normalidad, puedes usar Cornish-Fisher u algo similar para ajustar la asimetría y la curtosis de cada divisa individual.

0voto

greg Puntos 11

Asegúrate de hacer la correlación de RETORNO, no la correlación de precios. Además, si el número no está convergiendo, aumenta la cantidad de pasos para que sea suficiente para que entre en vigor la ley de los grandes números.

Finanhelp.com

FinanHelp es una comunidad para personas con conocimientos de economía y finanzas, o quiere aprender. Puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X