Learn R Programming

qrmtools (version 0.0-15)

Brownian: Brownian and Related Motions

Description

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.

Usage

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"))

Value

rBrownian() returns an \((N, n+1, d)\)-array containing the \(N\) paths of the specified \(d\)

stochastic processes simulated at the \(n+1\) time points (\(t_0 = 0, t_1,\dots, t_n\)).

deBrowning() returns an \((N, n, d)\)-array containing the \(N\) paths of the copula increments of the \(d\) stochastic processes over the \(n+1\) time points (\(t_0 = 0, t_1,\dots, t_n\)).

Arguments

N

number \(N\) of paths to simulate (positive integer).

x

\(n+1\)-vector containing one path of the specified stochastic process or \((n+1, d)\)-matrix containing one path of the specified \(d\) stochastic processes or \((N, n+1, d)\)-array containing \(N\) paths of the specified \(d\) stochastic processes.

t

\(n+1\)-vector of the form \((t_0,\dots,t_n)\) with \(0 = t_0 < \dots < t_n\) containing the time points where the stochastic processes are considered.

d

number \(d\) of stochastic processes to simulate (positive integer).

U

\((N\cdot n, d)\)-matrix of copula realizations to be converted to the joint increments of the stochastic processes.

drift

\(d\)-vector or number (then recycled to a \(d\)-vector) of drifts (typically denoted by \(\mu\)). Note that risk-neutral drifts are \(r - \sigma^2/2\), where \(r\) is the risk-free interest rate and \(\sigma\) the volatility.

vola

\(d\)-vector or number (then recycled to a \(d\)-vector) of volatilities (typically denoted by \(\sigma\)).

type

character string indicating whether a Brownian motion ("BM"), geometric Brownian motion ("GBM") or Brownian bridge ("BB") is to be considered.

init

\(d\)-vector or number (then recycled to a \(d\)-vector) of initial values (typically stock prices at time 0) for type = "GBM".

Author

Marius Hofert

Examples

Run this code
## 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