aboutsummaryrefslogtreecommitdiffstats
path: root/calibrate_tranches.R
diff options
context:
space:
mode:
Diffstat (limited to 'calibrate_tranches.R')
-rw-r--r--calibrate_tranches.R87
1 files changed, 67 insertions, 20 deletions
diff --git a/calibrate_tranches.R b/calibrate_tranches.R
index 18e2621f..c1f44a58 100644
--- a/calibrate_tranches.R
+++ b/calibrate_tranches.R
@@ -57,39 +57,45 @@ for(i in 1:nrow(nondefaulted)){
SC@curve <- cdshazardrate(quotes, nondefaulted$recovery[i]/100)
hy17portfolio <- c(hy17portfolio, SC)
}
+
issuerweights <- rep(1/length(hy17portfolio), length(hy17portfolio))
-hy17$indexref <- 1.025
+hy17$indexref <- 1.02
hy17portfolio.tweaked <- tweakcurves(hy17portfolio, hy17)
SurvProb <- SPmatrix(hy17portfolio.tweaked, hy17)
## load common parameters
K <- c(0, 0.15, 0.25, 0.35, 1)
Kmodified <- adjust.attachments(K, hy17$loss, hy17$factor)
-tranche.upf <- c(46.6875, 92.625, 105.375, 114.562)
+tranche.upf <- c(44.875, 91.75, 104.8125, 114.3125)
tranche.running <- c(0.05, 0.05, 0.05, 0.05)
-lu <- 0.01
+Ngrid <- 2*nrow(nondefaulted)+1
recov <- sapply(hy17portfolio.tweaked, attr, "recovery")
cs <- couponSchedule(nextIMMDate(today()), hy17$maturity,"Q", "FIXED", 0.05, 0)
## calibrate the tranches using base correlation
rhovec <- c()
f <- function(rho, ...){
- temp <- BClossdistC(SurvProb, issuerweights, recov, rho, lu, 100)
- return( abs(tranche.upf[i-1]-1/(Kmodified[i]-Kmodified[i-1])*
- (tranche.bp(temp$L, temp$R, cs, 0, Kmodified[i])*Kmodified[i]-
- tranche.bp(oldtemp$L, oldtemp$R, cs, 0, Kmodified[i-1])*Kmodified[i-1])) )
+ temp <- BClossdistC(SurvProb, issuerweights, recov, rho, Ngrid)
+ bp <- 100*(1+1/(Kmodified[i]-Kmodified[i-1]) *
+ (tranche.pv(temp$L, temp$R, cs, 0, Kmodified[i], Ngrid) -
+ tranche.pv(oldtemp$L, oldtemp$R, cs, 0, Kmodified[i-1], Ngrid)))
+ return( abs(tranche.upf[i-1]-bp))
}
for(i in 2:length(Kmodified)){
rho <- optimize(f, interval=c(0,1),
SurvProb, issuerweights, recov, lu, tranche.upf, Kmodified, cs, oldtemp)$minimum
- oldtemp <- BClossdistC(SurvProb, issuerweights, recov, rho, lu)
+ oldtemp <- BClossdistC(SurvProb, issuerweights, recov, rho, Ngrid)
rhovec <- c(rhovec, rho)
}
+deltas <- c()
+for(i in 2:5){
+ deltas <- c(deltas, BCtranche.delta(hy17portfolio.tweaked, hy17, 0.05, K[i-1], K[i], rhovec[i-1], rhovec[i], Ngrid))
+}
-#calibrate by modifying the factor distribution
+##calibrate by modifying the factor distribution
bottomup <- 1:3
topdown <- 2:4
n.int <- 100
@@ -104,15 +110,15 @@ p <- defaultprob
rho <- 0.45
clusterExport(cl, list("shockprob", "issuerweights", "rho", "Z", "lossrecovdist.term",
- "lossrecovdist", "lossdistribC", "lu",
- "tranche.bpvec", "tranche.bp", "tranche.pl", "tranche.cl",
+ "lossrecovdist", "lossdistribC", "Ngrid",
+ "tranche.pvvec", "tranche.pv", "tranche.pl", "tranche.cl",
"trancheloss", "trancherecov", "pos", "Kmodified", "cs"))
-
+## TODO: investigate if this is the right thing w.r.t recovery
parf <- function(i){
pshocked <- apply(p, 2, shockprob, rho=rho, Z=Z[i])
S <- 1 - Rstoch[i,,]
- dist <- lossrecovdist.term(pshocked, 0, issuerweights, S, lu)
- return( tranche.bpvec(Kmodified, dist$L, dist$R, cs))
+ dist <- lossrecovdist.term(pshocked, 0, issuerweights, S, Ngrid)
+ return( tranche.pvvec(Kmodified, dist$L, dist$R, cs))
}
for(l in 1:100){
@@ -122,10 +128,12 @@ for(l in 1:100){
Rstoch[,i,t] <- stochasticrecov(recov[i], 0, Z, w.mod, rho, defaultprob[i,t], p[i,t])
}
}
+
clusterExport(cl, list("Rstoch", "p"))
result <- parSapply(cl, 1:n.int, parf)
## solve the optimization problem
- program <- KLfit(result[topdown,], w, tranche.upf[topdown])
+ program <- KLfit(100*(result[bottomup,]+1), w, tranche.upf[bottomup])
+
err <- 0
for(i in 1:n.credit){
@@ -133,15 +141,54 @@ for(l in 1:100){
err <- err + abs(crossprod(shockprob(p[i,j], rho, Z), program$weight) - defaultprob[i,j])
}
}
+ errvec <- c(errvec, err)
## update the new probabilities
- for(i in 1:n.credit){
- for(j in 1:ncol(p)){
- p[i,j] <- fit.prob(Z, program$weight, rho, defaultprob[i,j])
- }
- }
+ p <- MFupdate.prob(Z, program.weight, rho, defaultprob)
errvec <- c(errvec, err)
w.mod <- program$weight
cat(err,"\n")
}
+clusterExport(cl, list("shockprob", "issuerweights", "rho", "Z", "lossrecovdist.term",
+ "lossrecovdist", "lossdistribC", "Ngrid",
+ "tranche.pvvec", "tranche.pv", "tranche.pl", "tranche.cl",
+ "trancheloss", "trancherecov", "pos", "Kmodified", "cs"))
+
+MFtranche.pv <- function(cl, cs, w, rho, defaultprob, p, issuerweights,
+ Ngrid=length(issuerweights)+1, Kmodified, n.int=100){
+ ## computes the tranches pv using the modified factor distribution
+ ## p is the modified probability so that
+ n.credit <- length(issuerweights)
+ Rstoch <- array(0, dim=c(n.int, n.credit, ncol(defaultprob)))
+ for(t in 1:ncol(defaultprob)){
+ for(i in 1:n.credit){
+ Rstoch[,i,t] <- stochasticrecov(recov[i], 0, Z, w, rho, defaultprob[i,t], p[i,t])
+ }
+ }
+ parf <- function(i){
+ pshocked <- apply(p, 2, shockprob, rho=rho, Z=Z[i])
+ S <- 1 - Rstoch[i,,]
+ dist <- lossrecovdist.term(pshocked, 0, issuerweights, S, Ngrid)
+ return( tranche.pvvec(Kmodified, dist$L, dist$R, cs))
+ }
+ clusterExport(cl, list("Rstoch", "p"))
+ result <- parSapply(cl, 1:n.int, parf)
+ return( 100*(1+result%*%w.mod) )
+}
+
+## computes deltas
+newportf <- hy17portfolio.tweaked
+eps <- 1e-4
+for(i in 1:length(newportf)){
+ newportf[[i]]@curve@hazardrates <- hy17portfolio.tweaked[[i]]@curve@hazardrates * (1 + eps)
+}
+SurvProb2 <- SPmatrix(newportf, hy17)
+p2 <- MFupdate.prob(Z, w.mod, rho, 1-SurvProb2)
+dPVtranches <- MFtranche.pv(cl, cs, w.mod, rho, 1-SurvProb2, p2, issuerweights) - MFtranche.pv(cl, cs, w.mod, rho, defaultprob, p, issuerweights)
+dPVindex <- indexpv(newportf, hy17)-indexpv(hy17portfolio.tweaked, hy17)
+MFdeltas <- dPVtranches/dPVindex
+
+#global deltas
+PVtranches <- MFtranche.pv(cl, cs, w.mod, rho, defaultprob, p, issuerweights)
+PVindex <-