VaR {cvar} | R Documentation |
Compute Value-at-Risk (VaR)
Description
VaR
computes the Value-at-Risk of the distribution specified by the
arguments. The meaning of the parameters is the same as in ES
, including
the recycling rules.
Usage
VaR(dist, p_loss = 0.05, ...)
VaR_qf(
dist,
p_loss = 0.05,
...,
intercept = 0,
slope = 1,
tol = .Machine$double.eps^0.5,
x
)
VaR_cdf(
dist,
p_loss = 0.05,
...,
intercept = 0,
slope = 1,
tol = .Machine$double.eps^0.5,
x
)
## Default S3 method:
VaR(
dist,
p_loss = 0.05,
dist.type = "qf",
...,
intercept = 0,
slope = 1,
tol = .Machine$double.eps^0.5,
x
)
## S3 method for class 'numeric'
VaR(dist, p_loss = 0.05, ..., intercept = 0, slope = 1, x)
Arguments
dist |
specifies the distribution whose ES is computed, usually a function or a name of a function computing quantiles, cdf, pdf, or a random number generator, see Details. |
p_loss |
level, default is 0.05. |
... |
passed on to |
intercept , slope |
compute VaR for the linear transformation |
tol |
tollerance |
x |
deprecated and will soon be removed. |
dist.type |
a character string specifying what is computed by |
Details
VaR
is S3 generic. The meaning of the parameters for its default method is the
same as in ES
, including the recycling rules.
VaR_qf
and VaR_cdf
are streamlined, non-generic, variants for the common
case when the "..."
parameters are scalar. The parameters x
,
intercept
, and slope
can be vectors, as for VaR
.
Argument dist
can also be a numeric vector. In that case the ES is computed,
effectively, for the empirical cumulative distribution function (ecdf) of the
vector. The ecdf is not created explicitly and the quantile
function is used instead for the computation of VaR. Arguments in "..."
are
passed eventually to quantile()
and can be used, for example, to select a
non-defult method for the computation of quantiles.
In practice, we may need to compute VaR associated with data. The distribution comes
from fitting a model. In the simplest case, we fit a distribution to the data,
assuming that the sample is i.i.d. For example, a normal distribution N(\mu,
\sigma^2)
can be fitted using the sample mean and sample variance as estimates of the
unknown parameters \mu
and \sigma^2
, see section ‘Examples’. For
other common distributions there are specialised functions to fit their parameters and
if not, general optimisation routines can be used. More soffisticated models may be
used, even time series models such as GARCH and mixture autoregressive models.
Note
We use the traditional definition of VaR as the negated lower quantile. For example,
if X
are returns on an asset, VAR{}_\alpha
= -q_\alpha
,
where q_\alpha
is the lower \alpha
quantile of X
.
Equivalently, VAR{}_\alpha
is equal to the lower 1-\alpha
quantile of -X
.
See Also
ES
for ES,
predict
for examples with fitted models
Examples
cvar::VaR(qnorm, c(0.01, 0.05), dist.type = "qf")
## the following examples use these values, obtained by fitting a normal distribution to
## some data:
muA <- 0.006408553
sigma2A <- 0.0004018977
## with quantile function, giving the parameters directly in the call:
res1 <- cvar::VaR(qnorm, 0.05, mean = muA, sd = sqrt(sigma2A))
res2 <- cvar::VaR(qnorm, 0.05, intercept = muA, slope = sqrt(sigma2A))
abs((res2 - res1)) # 0, intercept/slope equivalent to mean/sd
## with quantile function, which already knows the parameters:
my_qnorm <- function(p) qnorm(p, mean = muA, sd = sqrt(sigma2A))
res1_alt <- cvar::VaR(my_qnorm, 0.05)
abs((res1_alt - res1))
## with cdf the precision depends on solving an equation
res1a <- cvar::VaR(pnorm, 0.05, dist.type = "cdf", mean = muA, sd = sqrt(sigma2A))
res2a <- cvar::VaR(pnorm, 0.05, dist.type = "cdf", intercept = muA, slope = sqrt(sigma2A))
abs((res1a - res2)) # 3.287939e-09
abs((res2a - res2)) # 5.331195e-11, intercept/slope better numerically
## as above, but increase the precision, this is probably excessive
res1b <- cvar::VaR(pnorm, 0.05, dist.type = "cdf",
mean = muA, sd = sqrt(sigma2A), tol = .Machine$double.eps^0.75)
res2b <- cvar::VaR(pnorm, 0.05, dist.type = "cdf",
intercept = muA, slope = sqrt(sigma2A), tol = .Machine$double.eps^0.75)
abs((res1b - res2)) # 6.938894e-18 # both within machine precision
abs((res2b - res2)) # 1.040834e-16
## relative precision is also good
abs((res1b - res2)/res2) # 2.6119e-16 # both within machine precision
abs((res2b - res2)/res2) # 3.91785e-15
## an extended example with vector args, if "PerformanceAnalytics" is present
if (requireNamespace("PerformanceAnalytics", quietly = TRUE)) withAutoprint({
data(edhec, package = "PerformanceAnalytics")
mu <- apply(edhec, 2, mean)
sigma2 <- apply(edhec, 2, var)
musigma2 <- cbind(mu, sigma2)
## compute in 2 ways with cvar::VaR
vAz1 <- cvar::VaR(qnorm, 0.05, mean = mu, sd = sqrt(sigma2))
vAz2 <- cvar::VaR(qnorm, 0.05, intercept = mu, slope = sqrt(sigma2))
vAz1a <- cvar::VaR(pnorm, 0.05, dist.type = "cdf",
mean = mu, sd = sqrt(sigma2))
vAz2a <- cvar::VaR(pnorm, 0.05, dist.type = "cdf",
intercept = mu, slope = sqrt(sigma2))
vAz1b <- cvar::VaR(pnorm, 0.05, dist.type = "cdf",
mean = mu, sd = sqrt(sigma2),
tol = .Machine$double.eps^0.75)
vAz2b <- cvar::VaR(pnorm, 0.05, dist.type = "cdf",
intercept = mu, slope = sqrt(sigma2),
tol = .Machine$double.eps^0.75)
## analogous calc. with PerformanceAnalytics::VaR
vPA <- apply(musigma2, 1, function(x)
PerformanceAnalytics::VaR(p = .95, method = "gaussian", invert = FALSE,
mu = x[1], sigma = x[2], weights = 1))
## the results are numerically the same
max(abs((vPA - vAz1))) # 5.551115e-17
max(abs((vPA - vAz2))) # ""
max(abs((vPA - vAz1a))) # 3.287941e-09
max(abs((vPA - vAz2a))) # 1.465251e-10, intercept/slope better
max(abs((vPA - vAz1b))) # 4.374869e-13
max(abs((vPA - vAz2b))) # 3.330669e-16
})