aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--R/calibrate_tranches_BC.R81
-rw-r--r--R/calibration.R66
-rw-r--r--R/cds_functions_generic.R14
-rw-r--r--R/script_calibrate_tranches.R97
4 files changed, 118 insertions, 140 deletions
diff --git a/R/calibrate_tranches_BC.R b/R/calibrate_tranches_BC.R
index b8e13f7d..cd0d85fc 100644
--- a/R/calibrate_tranches_BC.R
+++ b/R/calibrate_tranches_BC.R
@@ -8,11 +8,13 @@ source(file.path(root.dir, "code", "R", "cds_utils.R"))
source(file.path(root.dir, "code", "R", "cds_functions_generic.R"))
source(file.path(root.dir, "code", "R", "yieldcurve.R"))
source(file.path(root.dir, "code", "R", "optimization.R"))
-load.index("hy21")
+source(file.path(root.dir, "code", "R", "calibration.R"))
+load.index("hy21", "index_definitions_bt.yml")
library(lossdistrib)
n.int <- 250
attach(GHquad(n.int))
+Ngrid <- 201
alldates <- seq(as.Date("2014-01-01"), as.Date("2014-05-05"), by="1 day")
rhomat <- c()
@@ -23,74 +25,19 @@ for(i in seq_along(bus.dates)){
exportYC(tradedate)
## calibrate HY21
## calibrate the single names curves
- singlenames.data <- read.csv(file.path(root.dir, "Scenarios", "Calibration",
- paste0("hy21_singlenames_", tradedate, ".csv")))
- nondefaulted <- singlenames.data[!singlenames.data$ticker %in% hy21$defaulted,]
- bps <- 1e-4
-
- cdsdates <- as.Date(character(0))
- for(tenor in paste0(1:5, "y")){
- cdsdates <- c(cdsdates, cdsMaturity(tenor, date=tradedate))
- }
-
- hy21portfolio <- c()
- cs <- couponSchedule(IMMDate(tradedate), cdsdates[length(cdsdates)], "Q", "FIXED",
- 1, tradedate, IMMDate(tradedate, "prev"))
- for(i in 1:nrow(nondefaulted)){
- SC <- new("creditcurve",
- recovery=nondefaulted$recovery[i]/100,
- startdate=tradedate,
- issuer=as.character(nondefaulted$ticker[i]))
- quotes <- data.frame(maturity=cdsdates, upfront = as.numeric(nondefaulted[i,4:8])*0.01,
- running=rep(nondefaulted$running[i]*bps, 5))
- SC@curve <- cdshazardrate(quotes, nondefaulted$recovery[i]/100, tradedate, cs)
- hy21portfolio <- c(hy21portfolio, SC)
- }
- n.credit <- length(hy21portfolio)
- issuerweights <- rep(1/n.credit, n.credit)
- tranche.data <- read.csv(file.path(root.dir, "Scenarios", "Calibration",
- paste0("hy21_tranches_", tradedate, ".csv")), header=TRUE)
- hy21$indexref <- tranche.data$bidRefPrice[1]/100
-
- temp <- tweakcurves(hy21portfolio, hy21, tradedate)
- hy21portfolio.tweaked <- temp$portfolio
- cs <- couponSchedule(IMMDate(tradedate), hy21$maturity,"Q", "FIXED", 0.05, 0, tradedate,
- IMMDate(tradedate, "prev"))
- SurvProb <- SPmatrix(hy21portfolio.tweaked, length(cs$dates))
- ## load common parameters
- K <- c(0, 0.15, 0.25, 0.35, 1)
- Kmodified <- adjust.attachments(K, hy21$loss, hy21$factor)
- tranche.upf <- tranche.data$Mid
- tranche.running <- tranche.data$Coupon
-
- Ngrid <- 2 * nrow(nondefaulted) + 1
- recov <- sapply(hy21portfolio.tweaked, attr, "recovery")
-
- ##calibrate tranches using base correlation
- defaultprob <- 1 - SurvProb
-
- dK <- diff(Kmodified)
- acc <- cdsAccrued(tradedate, tranche.running)
-
- ##convert the quotes
- ## - we convert to protection terms x->1-x/100
- ## - we remove accrued x->x-acc
- ## - we weight it by the size of the tranche
- ## - we take the cumsum to convert to 0-5, 0-10, 0-15 quotes, etc...
- quotes <- cumsum(dK * (1-tranche.upf/100-acc))
+ set.singlenamesdata(hy21, tradedate)
+ set.tranchedata(hy21, tradedate)
## calibrate the tranches using base correlation
- rhovec <- c()
- f <- function(rho, ...){
- temp <- BClossdistC(defaultprob, issuerweights, recov, rho, Z, w, Ngrid)
- return(abs(tranche.pv(temp$L, temp$R, cs, 0, Kmodified[i]) + q))
+ f <- function(rho, index, N, i){
+ temp <- with(index,
+ BClossdistC(defaultprob, issuerweights, recov, rho, Z, w, N))
+ return(abs(tranche.pv(temp$L, temp$R, index$cs, 0, index$K[i+1]) + index$quotes[i]))
}
-
rhovec <- c()
- for(i in 2:length(Kmodified)){
+ for(i in 1:(length(hy21$K)-1)){
q <- quotes[i-1]
- rho <- optimize(f, interval=c(0,1),
- defaultprob, issuerweights, recov, Ngrid, Kmodified, cs, q)$minimum
+ rho <- optimize(f, interval=c(0,1), index=hy21, N=Ngrid, i=i)$minimum
rhovec <- c(rhovec, rho)
}
rhovec <- c(0, rhovec)
@@ -113,9 +60,9 @@ for(i in seq_along(bus.dates)){
## deltas <- dPVtranche/dPVindex
##use BCtranche.delta function
- deltas <- rep(0, length(K)-1)
- for(i in seq_along(K[-1])){
- deltas[i] <- BCtranche.delta(hy21portfolio.tweaked, hy21, 0.05, K[i], K[i+1], rhovec[i], rhovec[i+1], Z, w, Ngrid, tradedate)
+ deltas <- rep(0, length(hy21$K)-1)
+ for(i in seq_along(hy21$K[-1])){
+ deltas[i] <- BCtranche.delta(hy21, hy21$K[i], hy21$K[i+1], rhovec[i], rhovec[i+1], Z, w, Ngrid, tradedate)
}
deltasmat <- rbind(deltasmat, deltas)
rhomat <- rbind(rhomat, rhovec)
diff --git a/R/calibration.R b/R/calibration.R
new file mode 100644
index 00000000..96bf03f2
--- /dev/null
+++ b/R/calibration.R
@@ -0,0 +1,66 @@
+if(.Platform$OS.type == "unix"){
+ root.dir <- "/home/share/CorpCDOs"
+}else{
+ root.dir <- "//WDSENTINEL/share/CorpCDOs"
+}
+source(file.path(root.dir, "code", "R", "cds_utils.R"))
+source(file.path(root.dir, "code", "R", "cds_functions_generic.R"))
+
+buildSC <- function(quote, cs, cdsdates){
+ SC <- new("creditcurve",
+ recovery=quote$recovery/100,
+ startdate=tradedate,
+ issuer=as.character(quote$ticker))
+ quotes <- data.frame(maturity=cdsdates, upfront = as.numeric(quote[4:8]) * 0.01,
+ running=rep(quote$running*1e-4, 5))
+ SC@curve <- cdshazardrate(quotes, SC@recovery, tradedate, cs)
+ return( SC )
+}
+
+get.cdsSchedule <- function(tradedate){
+ cdsdates <- as.Date(character(0))
+ for(tenor in paste0(1:5, "y")){
+ cdsdates <- c(cdsdates, cdsMaturity(tenor, date=tradedate))
+ }
+ return( list(cs=couponSchedule(IMMDate(tradedate), cdsdates[length(cdsdates)], "Q", "FIXED",
+ 1, tradedate, IMMDate(tradedate, "prev")), cdsdates=cdsdates) )
+}
+
+set.singlenamesdata <- function(index, tradedate){
+ index.name <- deparse(substitute(index))
+ singlenames.data <- read.csv(file.path(root.dir, "Scenarios", "Calibration",
+ paste0(index.name, "_singlenames_", tradedate, ".csv")))
+ nondefaulted <- singlenames.data[!singlenames.data$ticker %in% index$defaulted,]
+ cds.cs <- get.cdsSchedule(tradedate)
+ index$portfolio <- c()
+ for(i in 1:nrow(nondefaulted)){
+ index$portfolio <- c(index$portfolio, buildSC(nondefaulted[i,], cds.cs$cs, cds.cs$cdsdates))
+ }
+ index$issuerweights <- rep(1/length(index$portfolio), length(index$portfolio))
+ index$recov <- sapply(index$portfolio, attr, "recovery")
+ assign(index.name, index, envir=parent.env(environment()))
+}
+
+set.tranchedata <- function(index, tradedate){
+ index.name <- deparse(substitute(index))
+ index$tranche.data <- read.csv(file.path(root.dir, "Scenarios", "Calibration",
+ paste0(index.name, "_tranches_", tradedate, ".csv")), header=TRUE)
+ index$indexref <- index$tranche.data$bidRefPrice[1]/100
+ index$cs <- couponSchedule(IMMDate(tradedate), index$maturity,"Q", "FIXED", 0.05, 0, tradedate,
+ IMMDate(tradedate, "prev"))
+ index$portfolio.tweaked <- tweakcurves(index, tradedate)$portfolio
+ index$defaultprob <- 1-SPmatrix(index$portfolio.tweaked, length(index$cs$dates))
+ K <- c(0, 0.15, 0.25, 0.35, 1)
+ index$K <- adjust.attachments(K, index$loss, index$factor)
+ index$tranche.upf <- index$tranche.data$Mid
+ index$tranche.running <- index$tranche.data$Coupon
+ ##convert the quotes
+ ## - we convert to protection terms x->1-x/100
+ ## - we remove accrued x->x-acc
+ ## - we weight it by the size of the tranche
+ ## - we take the cumsum to convert to 0-5, 0-10, 0-15 quotes, etc...
+ ## calibrate the tranches using base correlation
+ index$quotes <- cumsum(diff(index$K) *
+ (1-index$tranche.upf/100-cdsAccrued(tradedate, index$tranche.running)))
+ assign(index.name, index, envir=parent.env(environment()))
+}
diff --git a/R/cds_functions_generic.R b/R/cds_functions_generic.R
index 92fae5a7..26037343 100644
--- a/R/cds_functions_generic.R
+++ b/R/cds_functions_generic.R
@@ -547,10 +547,12 @@ indexpv <- function(index, epsilon=0, tradedate=Sys.Date(), clean=TRUE){
## computes the intrinsic price of a portfolio of cds
if(epsilon!=0){
portfolio <- tweakportfolio(index$portfolio, epsilon)
+ }else{
+ portfolio <- index$portfolio
}
startdate <- tradedate + 1
- cl.list <- unlist(lapply(index$portfolio, function(x){couponleg(index$cs, x@curve, startdate)}))
- pl.list <- unlist(lapply(index$portfolio, function(x){defaultleg(index$cs, x@curve, x@recovery, startdate)}))
+ cl.list <- unlist(lapply(portfolio, function(x){couponleg(index$cs, x@curve, startdate)}))
+ pl.list <- unlist(lapply(portfolio, function(x){defaultleg(index$cs, x@curve, x@recovery, startdate)}))
accrued <- cdsAccrued(tradedate, index$coupon)
r <- list(cl = mean(cl.list) - accrued, pl = mean(pl.list), bp = 1+mean(cl.list-pl.list))
if(clean){
@@ -608,15 +610,15 @@ portfolioduration <- function(portfolio, maturity){
return( crossprod(durations, portfolio$notional)/sum(portfolio$notional) )
}
-tweakcurves <- function(portfolio, index, tradedate=Sys.Date()){
+tweakcurves <- function(index, tradedate=Sys.Date()){
## computes the tweaking factor
epsilon <- 0
f <- function(epsilon, ...){
- abs(indexpv(portfolio, index, epsilon, tradedate)$bp - index$indexref)
+ abs(indexpv(index, epsilon, tradedate)$bp - index$indexref)
}
- epsilon <- optimize(f, c(-0.5, 0.5), portfolio, index, tol=1e-6)$minimum
+ epsilon <- optimize(f, c(-0.5, 0.5), index, tol=1e-6)$minimum
cat("tweak = ", epsilon, "\n")
- return( list(portfolio=tweakportfolio(portfolio, epsilon), epsilon=epsilon) )
+ return( list(portfolio=tweakportfolio(index$portfolio, epsilon), epsilon=epsilon) )
}
survivalProbability1 <- function(startdate, date, survival.curve) {
diff --git a/R/script_calibrate_tranches.R b/R/script_calibrate_tranches.R
index 14d346b1..12cb51f7 100644
--- a/R/script_calibrate_tranches.R
+++ b/R/script_calibrate_tranches.R
@@ -15,6 +15,7 @@ source(file.path(root.dir, "code", "R", "cds_utils.R"))
source(file.path(root.dir, "code", "R", "cds_functions_generic.R"))
source(file.path(root.dir, "code", "R", "yieldcurve.R"))
source(file.path(root.dir, "code", "R", "optimization.R"))
+source(file.path(root.dir, "code", "R", "calibration.R"))
load.index("hy21")
##figure out the tradedate
@@ -27,116 +28,79 @@ if(length(args) >= 1){
exportYC(tradedate)
## calibrate HY21
## calibrate the single names curves
-singlenames.data <- read.csv(file.path(root.dir, "Scenarios", "Calibration",
- paste0("hy21_singlenames_", tradedate, ".csv")))
-nondefaulted <- singlenames.data[!singlenames.data$ticker %in% hy21$defaulted,]
-bps <- 1e-4
-
-cdsdates <- as.Date(character(0))
-for(tenor in paste0(1:5, "y")){
- cdsdates <- c(cdsdates, cdsMaturity(tenor, date=tradedate))
-}
-
-hy21portfolio <- c()
-cs <- couponSchedule(IMMDate(tradedate), cdsdates[length(cdsdates)], "Q", "FIXED",
- 1, tradedate, IMMDate(tradedate, "prev"))
-for(i in 1:nrow(nondefaulted)){
- SC <- new("creditcurve",
- recovery=nondefaulted$recovery[i]/100,
- startdate=tradedate,
- issuer=as.character(nondefaulted$ticker[i]))
- quotes <- data.frame(maturity=cdsdates, upfront = as.numeric(nondefaulted[i,4:8]) /100,
- running=rep(nondefaulted$running[i] * bps, 5))
- SC@curve <- cdshazardrate(quotes, nondefaulted$recovery[i]/100, tradedate, cs)
- hy21portfolio <- c(hy21portfolio, SC)
-}
-
-issuerweights <- rep(1/length(hy21portfolio), length(hy21portfolio))
+set.singlenamesdata(hy21, tradedate)
+set.tranchedata(hy21, tradedate)
## load tranche data
-K <- c(0, 0.15, 0.25, 0.35, 1)
-Kmodified <- adjust.attachments(K, hy21$loss, hy21$factor)
-market.data <- read.csv(file.path(root.dir, "Scenarios", "Calibration",
- paste0("hy21_tranches_", tradedate, ".csv")))
-
-tranche.upf <- market.data$Mid
-tranche.running <- c(0.05, 0.05, 0.05, 0.05)
-# get the index ref
-hy21$indexref <- market.data$bidRefPrice[1]/100
-hy21portfolio.tweaked <- tweakcurves(hy21portfolio, hy21, tradedate)$portfolio
-cs <- couponSchedule(IMMDate(tradedate), hy21$maturity,"Q", "FIXED", 0.05, 0, tradedate, IMMDate(tradedate, "prev"))
-SurvProb <- SPmatrix(hy21portfolio.tweaked, length(cs$dates))
-
-Ngrid <- 2 * nrow(nondefaulted) + 1
-recov <- sapply(hy21portfolio.tweaked, attr, "recovery")
+n.credit <- length(hy21$portfolio)
+Ngrid <- 2 * n.credit + 1
acc <- cdsAccrued(tradedate, 0.05)
##calibrate by modifying the factor distribution
bottomup <- 1:3
topdown <- 2:4
n.int <- 500
-n.credit <- length(hy21portfolio)
+n.credit <- length(hy21$portfolio)
errvec <- c()
quadrature <- GHquad(n.int)
w <- quadrature$w
Z <- quadrature$Z
w.mod <- w
-defaultprob <- 1 - SurvProb
-p <- defaultprob
+p <- hy21$defaultprob
rho <- rep(0.45, n.credit)
-
result <- matrix(0, 4, n.int)
err <- Inf
while(err >0.01){
- Rstoch <- array(0, dim=c(n.credit, n.int, ncol(SurvProb)))
- for(t in 1:ncol(SurvProb)){
+ Rstoch <- array(0, dim=c(n.credit, n.int, ncol(hy21$defaultprob)))
+ for(t in 1:ncol(hy21$defaultprob)){
for(i in 1:n.credit){
- Rstoch[i,,t] <- stochasticrecovC(recov[i], 0, Z, w.mod, rho[i], defaultprob[i,t], p[i,t])
+ Rstoch[i,,t] <- stochasticrecovC(hy21$recov[i], 0, Z, w.mod, rho[i],
+ hy21$defaultprob[i,t], p[i,t])
}
}
- L <- array(0, dim=c(n.int, Ngrid, ncol(defaultprob)))
- R <- array(0, dim=c(n.int, Ngrid, ncol(defaultprob)))
- for(t in 1:ncol(defaultprob)){
+ L <- array(0, dim=c(n.int, Ngrid, ncol(hy21$defaultprob)))
+ R <- array(0, dim=c(n.int, Ngrid, ncol(hy21$defaultprob)))
+ for(t in 1:ncol(hy21$defaultprob)){
S <- 1 - Rstoch[,,t]
- L[,,t] <- t(lossdistCZ(p[,t], issuerweights, S, Ngrid, 0, rho, Z))
- R[,,t] <- t(lossdistCZ(p[,t], issuerweights, 1-S, Ngrid, 0, rho, Z))
+ L[,,t] <- t(lossdistCZ(p[,t], hy21$issuerweights, S, Ngrid, 0, rho, Z))
+ R[,,t] <- t(lossdistCZ(p[,t], hy21$issuerweights, 1-S, Ngrid, 0, rho, Z))
}
for(i in 1:n.int){
- result[,i] <- tranche.pvvec(Kmodified, L[i,,], R[i,,], cs) - acc
+ result[,i] <- tranche.pvvec(hy21$K, L[i,,], R[i,,], hy21$cs) - acc
}
## solve the optimization problem
- program <- KLfit(100*(result[bottomup,]+1), w, tranche.upf[bottomup])
+ program <- KLfit(100*(result[bottomup,]+1), w, hy21$tranche.upf[bottomup])
err <- 0
for(i in 1:n.credit){
for(j in 1:ncol(p)){
- err <- err + abs(crossprod(shockprob(p[i,j], rho[i], Z), program$weight) - defaultprob[i,j])
+ err <- err + abs(crossprod(shockprob(p[i,j], rho[i], Z), program$weight) - hy21$defaultprob[i,j])
}
}
errvec <- c(errvec, err)
## update the new probabilities
- p <- MFupdate.probC(Z, program$weight, rho, defaultprob)
+ p <- MFupdate.probC(Z, program$weight, rho, hy21$defaultprob)
errvec <- c(errvec, err)
w.mod <- program$weight
cat(err,"\n")
}
-Rstoch <- array(0, dim=c(n.credit, n.int, ncol(SurvProb)))
-for(t in 1:ncol(SurvProb)){
+Rstoch <- array(0, dim=c(n.credit, n.int, ncol(hy21$defaultprob)))
+for(t in 1:ncol(hy21$defaultprob)){
for(i in 1:n.credit){
- Rstoch[i,,t] <- stochasticrecovC(recov[i], 0, Z, w.mod, rho[i], defaultprob[i,t], p[i,t])
+ Rstoch[i,,t] <- stochasticrecovC(hy21$recov[i], 0, Z, w.mod, rho[i], hy21$defaultprob[i,t], p[i,t])
}
}
Lw <- matrix(0, Ngrid, n.int)
Rw <- matrix(0, Ngrid, n.int)
-L <- matrix(0, Ngrid, ncol(defaultprob))
-R <- matrix(0, Ngrid, ncol(defaultprob))
-for(t in 1:ncol(defaultprob)){
+L <- matrix(0, Ngrid, ncol(hy21$defaultprob))
+R <- matrix(0, Ngrid, ncol(hy21$defaultprob))
+for(t in 1:ncol(hy21$defaultprob)){
S <- 1 - Rstoch[,,t]
- Lw <- lossdistCZ(p[,t], issuerweights, S, Ngrid, 0, rho, Z)
- Rw <- lossdistCZ(p[,t], issuerweights, 1-S, Ngrid, 0, rho, Z)
+ Lw <- lossdistCZ(p[,t], hy21$issuerweights, S, Ngrid, 0, rho, Z)
+ Rw <- lossdistCZ(p[,t], hy21$issuerweights, 1-S, Ngrid, 0, rho, Z)
L[,t] <- Lw%*%w.mod
R[,t] <- Rw%*%w.mod
}
@@ -148,6 +112,5 @@ write.table(data.frame(Z=Z, w=w.mod),
paste0("calibration-", tradedate, ".csv")),
col.names=T, row.names=F, sep=",")
-save(singlenames.data, hy21, tranche.upf, dist,
- file = file.path(root.dir, "Scenarios", "Calibration",
- paste0("marketdata-", tradedate, ".RData")), compress="xz")
+save(hy21, dist, file = file.path(root.dir, "Scenarios", "Calibration",
+ paste0("marketdata-", tradedate, ".RData")), compress="xz")