Last chance! 50% off unlimited learning
Sale ends in
Simulate paths of dependent Brownian motions, geometric Brownian motions and Brownian bridges based on given increment copula samples. And extract copula increments from paths of dependent Brownian motions and geometric Brownian motions.
rBrownian(N, t, d = 1, U = matrix(runif(N * n * d), ncol = d),
drift = 0, vola = 1, type = c("BM", "GBM", "BB"), init = 1)
deBrowning(x, t, drift = 0, vola = 1, type = c("BM", "GBM"))
rBrownian()
returns an
stochastic processes simulated at the
deBrowning()
returns an
number
number
matrix
of copula
realizations to be converted to the joint increments of
the stochastic processes.
character
string indicating whether
a Brownian motion ("BM"
), geometric Brownian motion
("GBM"
) or Brownian bridge ("BB"
) is to be considered.
type = "GBM"
.
Marius Hofert
## Setup
d <- 3 # dimension
library(copula)
tcop <- tCopula(iTau(tCopula(), tau = 0.5), dim = d, df = 4) # t_4 copula
vola <- seq(0.05, 0.20, length.out = d) # volatilities sigma
r <- 0.01 # risk-free interest rate
drift <- r - vola^2/2 # marginal drifts
init <- seq(10, 100, length.out = d) # initial stock prices
N <- 100 # number of replications
n <- 25 # number of time intervals
t <- 0:n/n # time points 0 = t_0 < ... < t_n
## Simulate N paths of a cross-sectionally dependent d-dimensional
## (geometric) Brownian motion ((G)BM) over n time steps
set.seed(271)
U <- rCopula(N * n, copula = tcop) # for dependent increments
X <- rBrownian(N, t = t, d = d, U = U, drift = drift, vola = vola) # BM
S <- rBrownian(N, t = t, d = d, U = U, drift = drift, vola = vola,
type = "GBM", init = init) # GBM
stopifnot(dim(X) == c(N, n+1, d), dim(S) == c(N, n+1, d))
## DeBrowning
Z.X <- deBrowning(X, t = t, drift = drift, vola = vola) # BM
Z.S <- deBrowning(S, t = t, drift = drift, vola = vola, type = "GBM") # GBM
stopifnot(dim(Z.X) == c(N, n, d), dim(Z.S) == c(N, n, d))
## Note that for BMs, one loses one observation as X_{t_0} = 0 (or some other
## fixed value, so there is no random increment there that can be deBrowned.
# \donttest{
## If we map the increments back to their copula sample, do we indeed
## see the copula samples again?
U.Z.X <- pnorm(Z.X) # map to copula sample
U.Z.S <- pnorm(Z.S) # map to copula sample
stopifnot(all.equal(U.Z.X, U.Z.S)) # sanity check
## Visual check
pairs(U.Z.X[,1,], gap = 0) # check at the first time point of the BM
pairs(U.Z.X[,n,], gap = 0) # check at the last time point of the BM
pairs(U.Z.S[,1,], gap = 0) # check at the first time point of the GBM
pairs(U.Z.S[,n,], gap = 0) # check at the last time point of the GBM
## Numerical check
## First convert the (N * n, d)-matrix U to an (N, n, d)-array but in
## the right way (array(U, dim = c(N, n, d)) would use the U's in the
## wrong order)
U. <- aperm(array(U, dim = c(n, N, d)), perm = c(2,1,3))
## Now compare
stopifnot(all.equal(U.Z.X, U., check.attributes = FALSE))
stopifnot(all.equal(U.Z.S, U., check.attributes = FALSE))
# }
# \donttest{
## Generate dependent GBM sample paths with quasi-random numbers
library(qrng)
set.seed(271)
U.. <- cCopula(to_array(sobol(N, d = d * n, randomize = "digital.shift"), f = n),
copula = tcop, inverse = TRUE)
S. <- rBrownian(N, t = t, d = d, U = U.., drift = drift, vola = vola,
type = "GBM", init = init)
pairs(S [,2,], gap = 0) # pseudo-samples at t_1
pairs(S.[,2,], gap = 0) # quasi-samples at t_1
pairs(S [,n+1,], gap = 0) # pseudo-samples at t_n
pairs(S.[,n+1,], gap = 0) # quasi-samples at t_n
# }
# \donttest{
## Generate paths from a Brownian bridge
B <- rBrownian(N, t = t, type = "BB")
plot(NA, xlim = 0:1, ylim = range(B),
xlab = "Time t", ylab = expression("Brownian bridge path"~(B[t])))
for(i in 1:N)
lines(t, B[i,,], col = adjustcolor("black", alpha.f = 25/N))
# }
Run the code above in your browser using DataLab