Skip to content

Commit

Permalink
version 0.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Quentin Lajaunie authored and cran-robot committed May 2, 2023
0 parents commit 6869e9e
Show file tree
Hide file tree
Showing 17 changed files with 701 additions and 0 deletions.
21 changes: 21 additions & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Package: matrisk
Title: Macroeconomic-at-Risk
Version: 0.1.0
Authors@R: c(person("Quentin", "Lajaunie", role = c("aut", "cre"),
email = "quentin_lajaunie@hotmail.fr"),
person("Guillaume", "Flament", role = "aut", email="g.f.flament@gmail.com"),
person("Christophe", "Hurlin", role = "aut", email="christophe.hurlin@univ-orleans.fr"))
Description: The Macroeconomics-at-Risk (MaR) approach is based on a two-step semi-parametric estimation procedure that allows to forecast the full conditional distribution of an economic variable at a given horizon, as a function of a set of factors. These density forecasts are then be used to produce coherent forecasts for any downside risk measure, e.g., value-at-risk, expected shortfall, downside entropy. Initially introduced by Adrian et al. (2019) <doi:10.1257/aer.20161923> to reveal the vulnerability of economic growth to financial conditions, the MaR approach is currently extensively used by international financial institutions to provide Value-at-Risk (VaR) type forecasts for GDP growth (Growth-at-Risk) or inflation (Inflation-at-Risk). This package provides methods for estimating these models. Datasets for the US and the Eurozone are available to allow testing of the Adrian et al (2019) model. This package constitutes a useful toolbox (data and functions) for private practitioners, scholars as well as policymakers.
Depends: R (>= 2.10)
License: GPL-3
Encoding: UTF-8
RoxygenNote: 7.2.3
Imports: stats, quantreg, sn, dfoptim, plot3D
NeedsCompilation: no
Packaged: 2023-04-28 21:12:07 UTC; quentin.lajaunie_ver
Author: Quentin Lajaunie [aut, cre],
Guillaume Flament [aut],
Christophe Hurlin [aut]
Maintainer: Quentin Lajaunie <quentin_lajaunie@hotmail.fr>
Repository: CRAN
Date/Publication: 2023-05-02 08:30:05 UTC
16 changes: 16 additions & 0 deletions MD5
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
26edb2e9c67240f5c22fd629e160f8db *DESCRIPTION
e86405f5b4e333e036a337944f725f42 *NAMESPACE
883c5fa87da0bbde1bdfb5c65435571f *R/f_ES.R
a5c9081472fb94c0bf3f4c694a43f138 *R/f_VaR.R
bf04ec05bd4fc5081ad6e00d28117e0b *R/f_compile_quantile.R
3d485bca81db756b0e963773a6146456 *R/f_distrib.R
04dfb2a745c8bde8c5f8966fc4e336c5 *R/f_distrib_histo.R
3cb0267d447116bd94bb5454f8b397d6 *data/data_US.rda
9e4e519e3f447485c39812a85669c5f8 *data/data_euro.rda
028bb6a2238009d44186fdd32ebf2bee *man/data_US.Rd
f813dfe675ab76d5b1c379e2414da101 *man/data_euro.Rd
6ad037852dbea9e4b7e27387e184ee88 *man/f_ES.Rd
e26caf27752f6ee5ec94c990fca49247 *man/f_VaR.Rd
c750a7730d2a35262bb24be258c73c9d *man/f_compile_quantile.Rd
6179939a88ac1fd64ed72e248f834620 *man/f_distrib.Rd
9df5ed4934b96dfa8763dce35aa250c8 *man/f_distrib_histo.Rd
15 changes: 15 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Generated by roxygen2: do not edit by hand

export(f_ES)
export(f_VaR)
export(f_compile_quantile)
export(f_distrib)
export(f_distrib_histo)
import(plot3D)
importFrom(dfoptim,nmkb)
importFrom(quantreg,rq)
importFrom(sn,dst)
importFrom(sn,qst)
importFrom(stats,dnorm)
importFrom(stats,predict)
importFrom(stats,qnorm)
37 changes: 37 additions & 0 deletions R/f_ES.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#' Expected Shortfall
#'
#' @param alpha Numeric argument for Expected-Shortfall, between 0 and 1
#' @param dist String for the type of distribution (gaussian or skew-t)
#' @param params Numeric vector containing parameters of the distribution
#' @param accuracy Scalar value which regulates the accuracy of the ES (default value 1e-05)
#'
#' @description
#' The function allows to calculate Expected-shortfall for a given distribution. It takes as parameters alpha (risk level), a distribution and the parameters associated with this distribution. For example, for a normal distribution, the user must enter the mean and the standard deviation. Currently, the function can calculate the Expected-shortfall for the normal distribution and for the skew-t distribution (Azzalini and Capitianio, 2003)
#'
#' @references Azzalini, Adelchi, and Antonella Capitanio. "Distributions generated by perturbation of symmetry with emphasis on a multivariate skew t‐distribution." Journal of the Royal Statistical Society: Series B (Statistical Methodology) 65.2 (2003): 367-389.
#' @references Azzalini, Adelchi, and Maintainer Adelchi Azzalini. "Package ‘sn’." The skew-normal and skew-t distributions (2015): 1-3.
#'
#' @return Numeric value for the expected-shortfall given the distribution and the alpha risk
#' @export
#'
#' @examples
#' f_ES(0.95, "gaussian", params=c(0,1))
#' f_ES(0.95, "gaussian", params=c(0,1), accuracy=1e-05)
#' f_ES(0.95, "gaussian", params=c(0,1), accuracy=1e-04)
#'
f_ES <- function(alpha, dist, params, accuracy=1e-05){
ES <- 0
if (alpha > 1-1e-04){
stop("expected shortfall is computable for any 'alpha' less than 0.9999")
}else{
}
x <- seq(alpha, 1-1e-04, by=accuracy)
if(dist=="gaussian"){
ES <- sapply(x, f_VaR, dist="gaussian", params=params,simplify=TRUE)
}else if(dist=="skew-t"){
ES <- sapply(x, f_VaR, dist="skew-t", params=params,simplify=TRUE)
}else{
}
mean(ES)
return(mean(ES))
}
35 changes: 35 additions & 0 deletions R/f_VaR.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#' Value-at-Risk
#'
#' @param alpha Numeric argument for Expected-Shortfall, between 0 and 1
#' @param dist String for the type of distribution (gaussian or skew-t)
#' @param params Numeric vector containing parameters of the distribution
#'
#' @description
#' The function allows to calculate Value-at-Risk for a given distribution. It takes as parameters alpha (risk level), a distribution and the parameters associated with this distribution. For example, for a normal distribution, the user must enter the mean and the standard deviation. Currently, the function can calculate the Value-at-Risk for the normal distribution and for the skew-t distribution (Azzalini and Capitianio, 2003)
#'
#' @references Azzalini, Adelchi, and Antonella Capitanio. "Distributions generated by perturbation of symmetry with emphasis on a multivariate skew t‐distribution." Journal of the Royal Statistical Society: Series B (Statistical Methodology) 65.2 (2003): 367-389.
#' @references Azzalini, Adelchi, and Maintainer Adelchi Azzalini. "Package ‘sn’." The skew-normal and skew-t distributions (2015): 1-3.
#'
#' @return Numeric value for the Value-at-Risk given the distribution and the alpha risk
#' @export
#'
#' @examples
#' f_VaR(0.95, "gaussian", params=c(0,1))
#'
f_VaR <- function(alpha, dist, params){
# error management and match function
if(dist=="gaussian"){
if (length(params)!=2){
stop("'params' must contain 2 values")
}else{
}
results<-qnorm(1 - alpha,params[1],params[2])
}else if(dist=="skew-t"){
if (length(params)!=4){
stop("'params' must contain 4 values")
}else{
}
results<- qst(1 - alpha,xi=params[1],omega=params[2],alpha=params[3], nu=params[4],tol = 1e-04)
}
return(results)
}
56 changes: 56 additions & 0 deletions R/f_compile_quantile.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#' Estimation of quantiles
#'
#' @param qt_trgt Numeric vector, dim k, of k quantiles for different qt-estimations
#' @param v_dep Numeric vector of the dependent variable
#' @param v_expl Numeric vector of the (k) explanatory variable(s)
#' @param t_trgt Numeric time target (optional)
#'
#' @return Numeric matrix with the predicted values based on each quantile regression, at time fixed in input
#' @importFrom stats predict
#' @importFrom quantreg rq
#' @export
#' @description
#' Predicted values based on each quantile regression (Koenker and Basset, 1978), at time=t_trgt, for each quantile in qt_trgt.
#'
#' @references Koenker, Roger, and Gilbert Bassett Jr. "Regression quantiles." Econometrica: journal of the Econometric Society (1978): 33-50.
#'
#' @examples
#' # Import data
#' data("data_euro")
#'
#' #' # Data process
#' PIB_euro_forward_4 = data_euro["GDP"][c(5:length(data_euro["GDP"][,1])),]
#' FCI_euro_lag_4 = data_euro["FCI"][c(1:(length(data_euro["GDP"][,1]) - 4)),]
#' CISS_euro_lag_4 = data_euro["CISS"][c(1:(length(data_euro["GDP"][,1]) - 4)),]
#'
#' quantile_target <- as.vector(c(0.10,0.25,0.75,0.90))
#' results_quantile_reg <- f_compile_quantile(qt_trgt=quantile_target,
#' v_dep=PIB_euro_forward_4,
#' v_expl=cbind(FCI_euro_lag_4, CISS_euro_lag_4),
#' t_trgt = 30)
#'
f_compile_quantile <- function(qt_trgt, v_dep, v_expl, t_trgt){

# number of quantile regressions (for k quantile regressions)
nb_qt <- length(qt_trgt)

# initialization of matrix results
results_qt <- matrix(data=0, ncol=2, nrow=nb_qt)

# loop on each quantile regression
for (ct_qt in 1:nb_qt){

reg_qt <- rq(v_dep ~ cbind(v_expl), tau=qt_trgt[ct_qt]) # quantile regression
pred_qt <- predict(reg_qt, newdata=as.data.frame(v_expl)) # prediction

# store the value that corresponds to t_trgt, time target
if(missing(t_trgt)){
results_qt[ct_qt,2] <- pred_qt[length(pred_qt)]
}else{
results_qt[ct_qt,2] <- pred_qt[t_trgt]
}

}
results_qt[,1] <- qt_trgt
return(results_qt)
}
126 changes: 126 additions & 0 deletions R/f_distrib.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#' Distribution
#'
#' @param type_function String argument : "gaussian" for normal distribution or "skew-t" for t-student distribution
#' @param compile_qt Numeric matrix containing different quantiles and associated values
#' @param starting_values Numeric vector with initial values for optimization
#'
#' @return a data.frame with the parameters of the distribution
#' @importFrom dfoptim nmkb
#' @importFrom stats qnorm
#' @importFrom sn qst
#' @description
#' This function is used to estimate the parameters of the distribution (mean and standard deviation for Gaussian, xi, omega, alpha, and nu for skew-t) based on the quantile regression results (Koenker and Basset, 1978). See Adrian et al. (2019) and Adrian et al. (2022) for more details on the estimation steps.
#'
#' @references Adrian, Tobias, Nina Boyarchenko, and Domenico Giannone. "Vulnerable growth." American Economic Review 109.4 (2019): 1263-89.
#' @references Adrian, Tobias, et al. "The term structure of growth-at-risk. " American Economic Journal: Macroeconomics 14.3 (2022): 283-323.
#' @references Koenker, Roger, and Gilbert Bassett Jr. "Regression quantiles." Econometrica: journal of the Econometric Society (1978): 33-50.
#'
#' @export
#'
#' @examples
#' # Import data
#' data("data_euro")
#'
#' # Data process
#' PIB_euro_forward_4 = data_euro["GDP"][c(5:length(data_euro["GDP"][,1])),]
#' FCI_euro_lag_4 = data_euro["FCI"][c(1:(length(data_euro["GDP"][,1]) - 4)),]
#' CISS_euro_lag_4 = data_euro["CISS"][c(1:(length(data_euro["GDP"][,1]) - 4)),]
#'
#' # for a gaussian
#' quantile_target <- as.vector(c(0.25,0.75))
#' results_quantile_reg <- f_compile_quantile(qt_trgt=quantile_target,
#' v_dep=PIB_euro_forward_4,
#' v_expl=cbind(FCI_euro_lag_4, CISS_euro_lag_4),
#' t_trgt = 30)
#'
#' results_g <- f_distrib(type_function="gaussian",
#' compile_qt=results_quantile_reg,
#' starting_values=c(0, 1))
#'
#' # for a skew-t
#' quantile_target <- as.vector(c(0.10,0.25,0.75,0.90))
#' results_quantile_reg <- f_compile_quantile(qt_trgt=quantile_target,
#' v_dep=PIB_euro_forward_4,
#' v_expl=cbind(FCI_euro_lag_4, CISS_euro_lag_4),
#' t_trgt = 30)
#'
#' results_s <- f_distrib(type_function="skew-t",
#' compile_qt=results_quantile_reg,
#' starting_values=c(0, 1, -0.5, 1.3))
#'
f_distrib <- function(type_function, compile_qt, starting_values){

# for a gaussian function
if(type_function=="gaussian"){
# error management
if (length(starting_values)!=2 && is.matrix(compile_qt)==FALSE){
stop("for a gaussian function, 'starting_values' has to be of dimension 2 and 'compile_qt' has to be a matrix")
}else if(length(starting_values)!=2){
if(nrow(compile_qt)<2){
stop("for a gaussian function, 'starting_values' has to be of dimension 2 and 'compile_qt' has to be a matrix with a minimum of 2 rows")
}else{
stop("for a gaussian function, 'starting_values' has to be of dimension 2")
}
}else if(is.matrix(compile_qt)==FALSE){
stop("'compile_qt' has to be a matrix")
}else if(nrow(compile_qt)<2){
error_results <- TRUE
stop("'compile_qt' has to be a matrix with a minimum of 2 rows")
}else{
# objective function
f_objective <- function(X, par){
# initialization
sum <- 0

# Loop on each elements of X
for (compteur in 1:nrow(X)){
sum <- sum + (qnorm(X[compteur,1], mean=par[1], sd=par[2]) - X[compteur,2])^2
}
return(sum)
}
# optimization
param <-nmkb(par=starting_values, fn=f_objective,
lower=c(-Inf,0),
upper=c(+Inf, +Inf), X=compile_qt)
}

results <- data.frame("mean"=param$par[1], "sd"=param$par[2])
return(results)

# for a skew-t function
}else if(type_function=="skew-t"){
# error management
if (length(starting_values)!=4 && is.matrix(compile_qt)==FALSE){
stop("for a skew-t function, 'starting_values' has to be of dimension 4 and 'compile_qt' has to be a matrix")
}else if(length(starting_values)!=4){
if(nrow(compile_qt)<4){
stop("for a skew-t function, 'starting_values' has to be of dimension 4 and 'compile_qt' has to be a matrix with a minimum of 4 rows")
}else{
stop("for a skew-t function, 'starting_values' has to be of dimension 4")
}
}else if(is.matrix(compile_qt)==FALSE){
stop("'compile_qt' has to be a matrix")
}else if(nrow(compile_qt)<4){
stop("'compile_qt' has to be a matrix with a minimum of 4 rows")
}else{
# objective function
f_objective <- function(X, par){
# initialization
sum <- 0
# Loop on each elements of X
for (compteur in 1:nrow(X)){
sum <- sum + (qst(X[compteur,1], xi=par[1], omega=par[2], alpha=par[3], nu=par[4], tol=1e-08, method=0) - X[compteur,2])^2
}
return(sum)
}
# optimization
param <-nmkb(par=starting_values, fn=f_objective,
lower=c(-Inf,10e-6, -1, 10e-6),
upper=c(+Inf, +Inf, 1, +Inf), X=compile_qt)
results <- data.frame("xi"=param$par[1], "omega"=param$par[2], "alpha"=param$par[3], "nu"=param$par[4])
return(results)
}
}else{
}

}

0 comments on commit 6869e9e

Please sign in to comment.