summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillaume Horel <guillaume.horel@gmail.com>2017-12-18 13:10:26 -0500
committerGuillaume Horel <guillaume.horel@gmail.com>2017-12-18 13:10:26 -0500
commit72549cc50059c32291a33c8933ee4a767438df61 (patch)
tree6dbb14f231d461625bee9e6c873f6a280fe29960
parentf76f4068da836f1e7baee1fc5965354b8666096f (diff)
downloadlossdistrib-72549cc50059c32291a33c8933ee4a767438df61.tar.gz
use Roxygen more
-rw-r--r--DESCRIPTION4
-rw-r--r--NAMESPACE36
-rw-r--r--R/distrib.R63
3 files changed, 84 insertions, 19 deletions
diff --git a/DESCRIPTION b/DESCRIPTION
index c19cdcd..f4eb62a 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -6,6 +6,8 @@ Date: 2014-10-03
Author: Guillaume Horel
Maintainer: Guillaume Horel <guillaume.horel@serenitascapital.com>
Description: Utility functions for generating the loss and recovery
- distributions of a portfolio of obligations
+ distributions of a portfolio of obligations.
License: GPL-3
Suggests: testthat
+RoxygenNote: 6.0.1
+Imports: distr
diff --git a/NAMESPACE b/NAMESPACE
index 65b8827..8f0bb73 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -1,2 +1,34 @@
-exportPattern("^[[:alpha:]]+")
-useDynLib("lossdistrib", .registration=TRUE, .fixes = "C_")
+# Generated by roxygen2: do not edit by hand
+
+export(BCER)
+export(BClossdist)
+export(BClossdistC)
+export(GHquad)
+export(dist.transform)
+export(dqnorm)
+export(dshockprob)
+export(exp_trunc)
+export(fit.prob)
+export(fit.probC)
+export(lossdist.joint)
+export(lossdist.prepay.joint)
+export(lossdistC)
+export(lossdistC.prepay.joint)
+export(lossdistC.prepay.jointZ)
+export(lossdistC.truncated)
+export(lossdistCZ)
+export(lossdistrib)
+export(lossdistrib.fft)
+export(lossdistrib2)
+export(lossdistrib2.truncated)
+export(lossrecovdist)
+export(lossrecovdist.joint.term)
+export(lossrecovdist.term)
+export(rec.trunc)
+export(recovdist)
+export(recovdistC)
+export(shockprob)
+export(shockseverity)
+export(stochasticrecov)
+export(stochasticrecovC)
+useDynLib(lossdistrib, .registration=TRUE, .fixes = "C_")
diff --git a/R/distrib.R b/R/distrib.R
index 59fba37..ae5e51f 100644
--- a/R/distrib.R
+++ b/R/distrib.R
@@ -9,7 +9,8 @@
## recovery with 0.1-1 support, so it's not clear that there is a big gain.
## - do the correlation adjustments when computing the deltas since it seems to be
## the market standard
-
+#' @useDynLib lossdistrib, .registration=TRUE, .fixes = "C_"
+NULL
#' Gauss-Hermite quadrature weights
#'
#' \code{GHquad} computes the quadrature weights for integrating against a
@@ -21,8 +22,8 @@
#' @return A list with two components:
#' \item{Z}{the list of nodes}
#' \item{w}{the corresponding weights}
-#'
-GHquad <- function(n){
+#' @export
+GHquad <- function(n) {
n <- as.integer(n)
Z <- double(n)
w <- double(n)
@@ -42,6 +43,7 @@ GHquad <- function(n){
#' algorithm of Andersen, Sidenius and Basu
#' @param p Numeric vector, the vector of success probabilities
#' @return A vector q such that \eqn{q_k=\Pr(S=k)}
+#' @export
lossdistrib <- function(p){
## basic recursive algorithm of Andersen, Sidenius and Basu
n <- length(p)
@@ -81,6 +83,7 @@ convolve <- function(dist1, dist2) {
#' compared to \eqn{O(n^2)} for the recursive algorithm.
#' @param p Numeric vector, the vector of success probabilities
#' @return A vector such that \eqn{q_k=\Pr(S=k)}
+#' @export
lossdistrib.fft <- function(p) {
## haven't tested when p is not a power of 2.
if(length(p) == 1){
@@ -109,7 +112,8 @@ lossdistrib.fft <- function(p) {
#' (instead of the loss distribution).
#' @return a Numeric vector of size \code{N} computing the loss (resp.
#' default) distribution if \code{defaultflag} is FALSE (resp. TRUE).
-lossdistrib2 <- function(p, w, S, N, defaultflag=FALSE){
+#' @export
+lossdistrib2 <- function(p, w, S, N, defaultflag = FALSE){
n <- length(p)
lu <- 1/(N-1)
q <- rep(0, N)
@@ -147,7 +151,8 @@ lossdistrib2 <- function(p, w, S, N, defaultflag=FALSE){
#' @param N Integer, number of ticks in the grid
#' @param cutoff Integer, where to stop computing the exact probabilities
#' @return a Numeric vector of size \code{N} computing the loss distribution
-lossdistrib2.truncated <- function(p, w, S, N, cutoff=N){
+#' @export
+lossdistrib2.truncated <- function(p, w, S, N, cutoff = N){
n <- length(p)
lu <- 1/(N-1)
q <- rep(0, cutoff)
@@ -188,6 +193,7 @@ lossdistrib2.truncated <- function(p, w, S, N, cutoff=N){
#' @param S Numeric, vector of severities
#' @param N Integer, number of ticks in the grid
#' @return a Numeric vector of size \code{N} computing the recovery distribution
+#' @export
recovdist <- function(dp, pp, w, S, N){
n <- length(dp)
q <- rep(0, N)
@@ -226,7 +232,8 @@ recovdist <- function(dp, pp, w, S, N){
#' @return q Matrix of joint loss, recovery probability distribution
#' colSums(q) is the recovery distribution marginal
#' rowSums(q) is the loss distribution marginal
-lossdist.joint <- function(p, w, S, N, defaultflag=FALSE){
+#' @export
+lossdist.joint <- function(p, w, S, N, defaultflag = FALSE){
n <- length(p)
lu <- 1/(N-1)
q <- matrix(0, N, N)
@@ -249,11 +256,12 @@ lossdist.joint <- function(p, w, S, N, defaultflag=FALSE){
qtemp[(i+2):N, (j+1):N] <- qtemp[(i+2):N, (j+1):N] + psplit[4] * q[1:(N-i-1), 1:(N-j)]
q <- qtemp + (1-p[k])*q
}
- q[length(q)] <- q[length(q)]+1-sum(q)
+ q[length(q)] <- q[length(q)] + 1 - sum(q)
return(q)
}
-lossdist.prepay.joint <- function(dp, pp, w, S, N, defaultflag=FALSE){
+#' @export
+lossdist.prepay.joint <- function(dp, pp, w, S, N, defaultflag = FALSE){
## recursive algorithm with first order correction
## to compute the joint probability distribition of the loss and recovery
## inputs:
@@ -314,6 +322,7 @@ lossdist.prepay.joint <- function(dp, pp, w, S, N, defaultflag=FALSE){
return(q)
}
+#' @export
lossdistC <- function(p, w, S, N, defaultflag=FALSE){
## C version of lossdistrib2, roughly 50 times faster
.C(C_lossdistrib, as.double(p), as.integer(length(p)),
@@ -321,6 +330,7 @@ lossdistC <- function(p, w, S, N, defaultflag=FALSE){
as.logical(defaultflag), q = double(N))$q
}
+#' @export
lossdistCZ <- function(p, w, S, N, defaultflag=FALSE, rho, Z){
##S is of size (length(p), length(Z))
stopifnot(length(rho) == length(p),
@@ -332,6 +342,7 @@ lossdistCZ <- function(p, w, S, N, defaultflag=FALSE, rho, Z){
as.double(Z), as.integer(length(Z)), q = matrix(0, N, length(Z)))$q
}
+#' @export
lossdistC.truncated <- function(p, w, S, N, T=N, defaultflag=FALSE){
## truncated version of lossdistrib
## q[i] is 0 for i>=T
@@ -340,13 +351,15 @@ lossdistC.truncated <- function(p, w, S, N, T=N, defaultflag=FALSE){
as.logical(defaultflag), q = double(N))$q
}
-exp.trunc <- function(p, w, S, N, K){
+#' @export
+exp_trunc <- function(p, w, S, N, K){
## computes E[(K-L)^+]
r <- 0
.C(C_exp_trunc, as.double(p), as.integer(length(p)),
as.double(w), as.double(S), as.integer(N), as.double(K), res = r)$res
}
+#' @export
rec.trunc <- function(p, w, S, N, K){
## computes E[(K-(1-R))^+] = E[(\tilde K- \bar R)]
## where \tilde K = K-sum_i w_i S_i and \bar R=\sum_i w_i R_i (1-X_i)
@@ -358,12 +371,14 @@ rec.trunc <- function(p, w, S, N, K){
}
}
+#' @export
recovdistC <- function(dp, pp, w, S, N){
## C version of recovdist
.C(C_recovdist, as.double(dp), as.double(pp), as.integer(length(dp)),
as.double(w), as.double(S), as.integer(N), q = double(N))$q
}
+#' @export
lossdistC.prepay.joint <- function(dp, pp, w, S, N, defaultflag=FALSE){
## C version of lossdist.prepay.joint
r <- .C(C_lossdistrib_joint, as.double(dp), as.double(pp), as.integer(length(dp)),
@@ -371,6 +386,7 @@ lossdistC.prepay.joint <- function(dp, pp, w, S, N, defaultflag=FALSE){
return(r)
}
+#' @export
lossdistC.prepay.jointZ <- function(dp, pp, w, S, N, defaultflag = FALSE, rho, Z, wZ){
## N is the size of the grid
## dp is of size n.credits
@@ -387,6 +403,7 @@ lossdistC.prepay.jointZ <- function(dp, pp, w, S, N, defaultflag = FALSE, rho, Z
return(r$output)
}
+#' @export
lossrecovdist <- function(defaultprob, prepayprob, w, S, N, defaultflag=FALSE, useC=TRUE){
lossdistrib2 <- if(useC) lossdistC
recovdist <- if(useC) recovdistC
@@ -400,6 +417,7 @@ lossrecovdist <- function(defaultprob, prepayprob, w, S, N, defaultflag=FALSE, u
return(list(L=L, R=R))
}
+#' @export
lossrecovdist.term <- function(defaultprob, prepayprob, w, S, N, defaultflag=FALSE, useC=TRUE){
## computes the loss and recovery distribution over time
L <- array(0, dim=c(N, ncol(defaultprob)))
@@ -420,6 +438,7 @@ lossrecovdist.term <- function(defaultprob, prepayprob, w, S, N, defaultflag=FAL
return(list(L=L, R=R))
}
+#' @export
lossrecovdist.joint.term <- function(defaultprob, prepayprob, w, S, N, defaultflag=FALSE, useC=TRUE){
## computes the joint loss and recovery distribution over time
Q <- array(0, dim=c(ncol(defaultprob), N, N))
@@ -437,7 +456,8 @@ lossrecovdist.joint.term <- function(defaultprob, prepayprob, w, S, N, defaultfl
return(Q)
}
-dist.transform <- function(dist.joint){
+#' @export
+dist.transform <- function(dist.joint) {
## compute the joint (D, R) distribution
## from the (L, R) distribution using D = L+R
distDR <- array(0, dim=dim(dist.joint))
@@ -459,7 +479,8 @@ dist.transform <- function(dist.joint){
return( distDR )
}
-shockprob <- function(p, rho, Z, log.p=F){
+#' @export
+shockprob <- function(p, rho, Z, log.p=F) {
## computes the shocked default probability as a function of the copula factor
## function is vectorized provided the below caveats:
## p and rho are vectors of same length n, Z is a scalar, returns vector of length n
@@ -478,7 +499,8 @@ shockprob <- function(p, rho, Z, log.p=F){
}
}
-shockseverity <- function(S, Stilde=1, Z, rho, p){
+#' @export
+shockseverity <- function(S, Stilde=1, Z, rho, p) {
## computes the severity as a function of the copula factor Z
result <- double(length(S))
result[p==0] <- 0
@@ -487,15 +509,18 @@ shockseverity <- function(S, Stilde=1, Z, rho, p){
return(result)
}
-dshockprob <- function(p,rho,Z){
+#' @export
+dshockprob <- function(p,rho,Z) {
dnorm((qnorm(p)-sqrt(rho)*Z)/sqrt(1-rho))*dqnorm(p)/sqrt(1-rho)
}
+#' @export
dqnorm <- function(x){
1/dnorm(qnorm(x))
}
-fit.prob <- function(Z, w, rho, p0){
+#' @export
+fit.prob <- function(Z, w, rho, p0) {
## if the weights are not perfectly gaussian, find the probability p such
## E_w(shockprob(p, rho, Z)) = p0
if(p0==0){
@@ -519,14 +544,16 @@ fit.prob <- function(Z, w, rho, p0){
return(p)
}
-fit.probC <- function(Z, w, rho, p0){
+#' @export
+fit.probC <- function(Z, w, rho, p0) {
stopifnot(length(Z)==length(w))
r <- .C(C_fitprob, as.double(Z), as.double(w), as.integer(length(Z)),
as.double(rho), as.double(p0), q = double(1))
return(r$q)
}
-stochasticrecov <- function(R, Rtilde, Z, w, rho, porig, pmod){
+#' @export
+stochasticrecov <- function(R, Rtilde, Z, w, rho, porig, pmod) {
## if porig == 0 (probably matured asset) then return orginal recovery
## it shouldn't matter anyway since we never default that asset
if(porig == 0){
@@ -537,6 +564,7 @@ stochasticrecov <- function(R, Rtilde, Z, w, rho, porig, pmod){
}
}
+#' @export
stochasticrecovC <- function(R, Rtilde, Z, w, rho, porig, pmod){
r <- .C(C_stochasticrecov, as.double(R), as.double(Rtilde), as.double(Z),
as.double(w), as.integer(length(Z)), as.double(rho), as.double(porig),
@@ -544,6 +572,7 @@ stochasticrecovC <- function(R, Rtilde, Z, w, rho, porig, pmod){
return(r$q)
}
+#' @export
BClossdist <- function(defaultprob, issuerweights, recov, rho, Z, w,
N=length(recov)+1, defaultflag=FALSE, n.int=500){
@@ -575,6 +604,7 @@ BClossdist <- function(defaultprob, issuerweights, recov, rho, Z, w,
list(L=L, R=R)
}
+#' @export
BClossdistC <- function(defaultprob, issuerweights, recov, rho, Z, w,
N=length(issuerweights)+1, defaultflag=FALSE){
if(is.null(dim(defaultprob))){
@@ -593,6 +623,7 @@ BClossdistC <- function(defaultprob, issuerweights, recov, rho, Z, w,
return(list(L=r$L,R=r$R))
}
+#' @export
BCER <- function(defaultprob, issuerweights, recov, K, rho, Z, w,
N=length(issuerweights)+1, defaultflag=FALSE){
stopifnot(length(Z)==length(w),