aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--R/build_portfolios.R220
-rw-r--r--R/build_scenarios.R348
-rw-r--r--R/db.R34
-rw-r--r--R/interpweights.R250
-rw-r--r--R/intex_deal_functions.R880
-rw-r--r--R/latestprices.R44
-rw-r--r--R/loadcashflows.R38
-rw-r--r--R/parse_intex.R18
-rw-r--r--R/tranches_RV_BC.R218
-rw-r--r--R/yieldcurve.R196
10 files changed, 1073 insertions, 1173 deletions
diff --git a/R/build_portfolios.R b/R/build_portfolios.R
index d5ffda3d..00d65321 100644
--- a/R/build_portfolios.R
+++ b/R/build_portfolios.R
@@ -1,110 +1,110 @@
-library("RQuantLib")
-library("yaml")
-
-args <- commandArgs(trailingOnly=TRUE)
-
-if(.Platform$OS.type == "unix"){
- root.dir <- "/home/share/CorpCDOs"
-}else{
- root.dir <- "//WDSENTINEL/share/CorpCDOs"
-}
-code.dir <- if(Sys.getenv("CODE_DIR")=="") root.dir else Sys.getenv("CODE_DIR")
-
-source(file.path(code.dir, "code", "R", "intex_deal_functions.R"), chdir=TRUE)
-source(file.path(code.dir, "code", "R", "yieldcurve.R"))
-source(file.path(code.dir, "code", "R", "serenitasdb.R"), chdir=TRUE)
-source(file.path(code.dir, "code", "R", "creditIndex.R"))
-
-if(interactive()) {
- ## enter the parameters here
- workdate <- as.Date("2016-02-17")
- dealnames <- c("cent15")
- reinvflags <- c(TRUE)
-} else {
- if(length(args) >=2){
- argslist <- strsplit(args[-1], ",")
- dealnames <- unlist(lapply(argslist, function(x)x[1]))
- reinvflags <- as.logical(unlist(lapply(argslist, function(x)x[2])))
- }else{
- data <- read.table(file.path(root.dir, "scripts", "deals_to_price.txt"),
- colClasses=c("character", "logical"))
- dealnames <- data$V1
- reinvflags <- data$V2
- }
- workdate <- if(length(args) >=1) as.Date(args[1]) else Sys.Date()
-}
-
-calibration.date <- addBusDay(workdate, -1)
-exportYC(calibration.date)
-index <- creditIndex("hy27")
-index <- set.index.desc(index, calibration.date)
-global.params <- yaml.load_file(file.path(root.dir, "code", "etc", "params.yml"))
-
-cusipdata <- cusip.data(workdate)
-cashspread.discount <- 0
-currdealnames <- dbGetQuery(etdb, "select dealname from et_deal_model_numbers where updatedate=$1", list(workdate))
-## build portfolio data
-for(i in seq_along(dealnames)){
- deal.name <- dealnames[i]
- global.params$reinvflag <- reinvflags[i]
- if(is.na(deal.name)){
- next
- }
- deal.data <- getdealdata(deal.name, calibration.date)
- if(is.na(deal.data$reinv_end_date)){
- global.params$reinvflag <- FALSE
- }
- if(deal.data$"Curr Collat Bal" < 1 ||is.na(deal.data$maturity)||
- deal.data$maturity <= Sys.Date()+90){
- next
- }
- deal.portfolio <- buildSC.portfolio(deal.name, deal.data, cusipdata, global.params, workdate)
- ##deal.portfolio$SC <- tweakportfolio(deal.portfolio$SC, -cashspread.discount, multiplicative=FALSE)
- mv <- crossprod(deal.portfolio$notional, deal.portfolio$price)/100
- nullcurves <- unlist(lapply(deal.portfolio$SC, is.null))
- deal.portfolio$SC <- deal.portfolio$SC[!nullcurves]
- deal.portfolio$notional <- deal.portfolio$notional[!nullcurves]
- A <- SPmatrix2(deal.portfolio$SC, deal.data, freq="Quarterly", workdate)
- S <- 1 - sapply(deal.portfolio$SC, attr, "recov")
- deal.weights <- deal.portfolio$notional/sum(deal.portfolio$notional)
- deal.spread5y <- portfoliospread(deal.portfolio, index$maturity, workdate)
- deal.spreadatmaturity <- portfoliospread(deal.portfolio, ,workdate)
- save.dir <- file.path(root.dir, "Scenarios", paste("Portfolios", workdate, sep="_"))
- if(!file.exists(save.dir)){
- dir.create(save.dir)
- }
- save(deal.portfolio, A, S, deal.weights, deal.spread5y,
- deal.spreadatmaturity, deal.data, file=file.path(save.dir, paste0(deal.name, ".RData")))
- cat(deal.name, "... done\n")
- if(deal.name %in% currdealnames$dealname){
- sqlstring <- paste0("UPDATE et_deal_model_numbers SET dealspread5y = $1,",
- "dealspread = $2, cdopercentage = $3, stalepercentage= $4, ",
- "marketvalue = $5",
- "WHERE dealname= $6 and updatedate = $7")
- r <- dbSendQuery(etdb, sqlstring,params = list(deal.spread5y,
- deal.spreadatmaturity,
- deal.portfolio$cdopercentage,
- deal.portfolio$stale,
- mv,
- deal.name,
- workdate))
- if(dbHasCompleted(r)){
- dbClearResult(r)
- }
- }else{
- sqlstring <- paste0("INSERT INTO et_deal_model_numbers",
- "(dealname, cdopercentage, stalepercentage,",
- "dealspread5y, marketvalue, updatedate, dealspread) ",
- "VALUES($1, $2, $3, $4, $5, $6, $7)")
- r <- dbSendQuery(etdb, sqlstring, params = list(deal.name,
- deal.portfolio$cdopercentage,
- deal.portfolio$stale,
- deal.spread5y, mv,
- workdate,
- deal.spreadatmaturity))
- if(dbHasCompleted(r)){
- dbClearResult(r)
- }
- currdealnames <- c(currdealnames, deal.name)
- }
-}
+library("RQuantLib")
+library("yaml")
+
+args <- commandArgs(trailingOnly=TRUE)
+
+if(.Platform$OS.type == "unix"){
+ root.dir <- "/home/share/CorpCDOs"
+}else{
+ root.dir <- "//WDSENTINEL/share/CorpCDOs"
+}
+code.dir <- if(Sys.getenv("CODE_DIR")=="") root.dir else Sys.getenv("CODE_DIR")
+
+source(file.path(code.dir, "code", "R", "intex_deal_functions.R"), chdir=TRUE)
+source(file.path(code.dir, "code", "R", "yieldcurve.R"))
+source(file.path(code.dir, "code", "R", "serenitasdb.R"), chdir=TRUE)
+source(file.path(code.dir, "code", "R", "creditIndex.R"))
+
+if(interactive()) {
+ ## enter the parameters here
+ workdate <- as.Date("2016-02-17")
+ dealnames <- c("cent15")
+ reinvflags <- c(TRUE)
+} else {
+ if(length(args) >=2){
+ argslist <- strsplit(args[-1], ",")
+ dealnames <- unlist(lapply(argslist, function(x)x[1]))
+ reinvflags <- as.logical(unlist(lapply(argslist, function(x)x[2])))
+ }else{
+ data <- read.table(file.path(root.dir, "scripts", "deals_to_price.txt"),
+ colClasses=c("character", "logical"))
+ dealnames <- data$V1
+ reinvflags <- data$V2
+ }
+ workdate <- if(length(args) >=1) as.Date(args[1]) else Sys.Date()
+}
+
+calibration.date <- addBusDay(workdate, -1)
+exportYC(calibration.date)
+index <- creditIndex("hy27")
+index <- set.index.desc(index, calibration.date)
+global.params <- yaml.load_file(file.path(root.dir, "code", "etc", "params.yml"))
+
+cusipdata <- cusip.data(workdate)
+cashspread.discount <- 0
+currdealnames <- dbGetQuery(etdb, "select dealname from et_deal_model_numbers where updatedate=$1", list(workdate))
+## build portfolio data
+for(i in seq_along(dealnames)){
+ deal.name <- dealnames[i]
+ global.params$reinvflag <- reinvflags[i]
+ if(is.na(deal.name)){
+ next
+ }
+ deal.data <- getdealdata(deal.name, calibration.date)
+ if(is.na(deal.data$reinv_end_date)){
+ global.params$reinvflag <- FALSE
+ }
+ if(deal.data$"Curr Collat Bal" < 1 ||is.na(deal.data$maturity)||
+ deal.data$maturity <= Sys.Date()+90){
+ next
+ }
+ deal.portfolio <- buildSC.portfolio(deal.name, deal.data, cusipdata, global.params, workdate)
+ ##deal.portfolio$SC <- tweakportfolio(deal.portfolio$SC, -cashspread.discount, multiplicative=FALSE)
+ mv <- crossprod(deal.portfolio$notional, deal.portfolio$price)/100
+ nullcurves <- unlist(lapply(deal.portfolio$SC, is.null))
+ deal.portfolio$SC <- deal.portfolio$SC[!nullcurves]
+ deal.portfolio$notional <- deal.portfolio$notional[!nullcurves]
+ A <- SPmatrix2(deal.portfolio$SC, deal.data, freq="Quarterly", workdate)
+ S <- 1 - sapply(deal.portfolio$SC, attr, "recov")
+ deal.weights <- deal.portfolio$notional/sum(deal.portfolio$notional)
+ deal.spread5y <- portfoliospread(deal.portfolio, index$maturity, workdate)
+ deal.spreadatmaturity <- portfoliospread(deal.portfolio, ,workdate)
+ save.dir <- file.path(root.dir, "Scenarios", paste("Portfolios", workdate, sep="_"))
+ if(!file.exists(save.dir)){
+ dir.create(save.dir)
+ }
+ save(deal.portfolio, A, S, deal.weights, deal.spread5y,
+ deal.spreadatmaturity, deal.data, file=file.path(save.dir, paste0(deal.name, ".RData")))
+ cat(deal.name, "... done\n")
+ if(deal.name %in% currdealnames$dealname){
+ sqlstring <- paste0("UPDATE et_deal_model_numbers SET dealspread5y = $1,",
+ "dealspread = $2, cdopercentage = $3, stalepercentage= $4, ",
+ "marketvalue = $5",
+ "WHERE dealname= $6 and updatedate = $7")
+ r <- dbSendQuery(etdb, sqlstring,params = list(deal.spread5y,
+ deal.spreadatmaturity,
+ deal.portfolio$cdopercentage,
+ deal.portfolio$stale,
+ mv,
+ deal.name,
+ workdate))
+ if(dbHasCompleted(r)){
+ dbClearResult(r)
+ }
+ }else{
+ sqlstring <- paste0("INSERT INTO et_deal_model_numbers",
+ "(dealname, cdopercentage, stalepercentage,",
+ "dealspread5y, marketvalue, updatedate, dealspread) ",
+ "VALUES($1, $2, $3, $4, $5, $6, $7)")
+ r <- dbSendQuery(etdb, sqlstring, params = list(deal.name,
+ deal.portfolio$cdopercentage,
+ deal.portfolio$stale,
+ deal.spread5y, mv,
+ workdate,
+ deal.spreadatmaturity))
+ if(dbHasCompleted(r)){
+ dbClearResult(r)
+ }
+ currdealnames <- c(currdealnames, deal.name)
+ }
+}
diff --git a/R/build_scenarios.R b/R/build_scenarios.R
index a2c0c190..f5255836 100644
--- a/R/build_scenarios.R
+++ b/R/build_scenarios.R
@@ -1,174 +1,174 @@
-library(doParallel)
-library(yaml)
-
-hostname <- system("hostname", intern=TRUE)
-if(hostname=="debian"){
- registerDoParallel(8)
-}else{
- registerDoParallel(4)
-}
-
-args <- commandArgs(trailingOnly=TRUE)
-
-if(.Platform$OS.type == "unix"){
- root.dir <- "/home/share/CorpCDOs"
-}else{
- root.dir <- "//WDSENTINEL/share/CorpCDOs"
-}
-
-code.dir <- if(Sys.getenv("CODE_DIR")=="") root.dir else Sys.getenv("CODE_DIR")
-source(file.path(code.dir, "code", "R", "intex_deal_functions.R"), chdir=TRUE)
-source(file.path(code.dir, "code", "R", "yieldcurve.R"))
-source(file.path(code.dir, "code", "R", "serenitasdb.R"), chdir=TRUE)
-source(file.path(code.dir, "code", "R", "tranche_functions.R"))
-
-if(interactive()) {
- tradedate <- as.Date("2016-02-25")
- dealnames <- c("beto", "ozlmf5")
- reinvflags <- c(TRUE, TRUE)
-}else{
- tradedate <- as.Date(args[1])
- if(length(args) >=2){
- argslist <- strsplit(args[-1], ",")
- dealnames <- unlist(lapply(argslist, function(x)x[1]))
- reinvflags <- as.logical(unlist(lapply(argslist, function(x)x[2])))
- }
-}
-
-calibration.date <- addBusDay(tradedate, -1)
-settledate <- addBusDay(tradedate, 3)
-calibration <- read.table(file.path(root.dir, "Scenarios", "Calibration",
- paste0("calibration-", calibration.date,".csv")), sep=",", header=T)
-Z <- calibration$Z
-w <- calibration$w
-exportYC(calibration.date)
-
-Ngrid <- 201
-support <- seq(0, 1, length = Ngrid)
-n.scenarios <- 100
-recov.adj <- 1
-params <- yaml.load_file(file.path(root.dir, "code", "etc", "params.yml"))
-
-for(j in seq_along(dealnames)){
- load(file.path(root.dir, "Scenarios", paste("Portfolios", tradedate, sep="_"),
- paste(dealnames[j], "RData", sep=".")))
- if(is.na(deal.data$reinv_end_date)){
- reinvflags[j] <- FALSE
- }
- dp <- A$DP
- pp <- A$PP
- dpmod <- MFupdate.prob(Z, w, deal.portfolio$beta, dp)
- ppmod <- MFupdate.prob(-Z, w, deal.portfolio$beta, pp)
- dist.joint <- MFlossdist.prepay.joint(w, Z, deal.portfolio$beta, dp, dpmod, pp, ppmod,
- deal.weights, 1-S, Ngrid)
- dist.joint <- pmax(dist.joint, 0)
- distDR <- dist.transform(dist.joint)
- ## compute E(R|D)
- R <- matrix(0, Ngrid, dim(distDR)[1])
- for(t in 1:dim(distDR)[1]){
- R[,t] <- sweep(distDR[t,,], 1, rowSums(distDR[t,,]), "/") %*% support
- R[1,t] <- 0
- if(t >= 2){
- R[,t] <- pmax(R[,t], R[,t-1])
- }
- }
-
- ## compute scenariosd
- scenariosd <- matrix(0, n.scenarios, dim(distDR)[1])
- scenariosr <- matrix(0, n.scenarios, dim(distDR)[1])
- percentiles <- seq(0, 1, 1/n.scenarios)
- for(t in 1:dim(distDR)[1]){
- D <- rowSums(distDR[t,,])
- Dfun <- splinefun(c(0, cumsum(D)), c(0, support), "hyman")
- Rfun <- approxfun(support, R[,t], rule=2)
- for(i in 1:n.scenarios){
- ## this is roughtly E(D|D is in ith percentile)
- ## using trapezoidal approximation
- if(i==1){
- scenariosd[i,t] <- 0.5* Dfun(0.01)
- }else{
- scenariosd[i,t] <- 0.5 * (Dfun((i-1)*0.01)+Dfun(i*0.01))
- }
- if(t>=2 && scenariosd[i,t] < scenariosd[i,t-1]){
- scenariosd[i,t] <- scenariosd[i,t-1]
- }
- scenariosr[i,t] <- Rfun(scenariosd[i,t])
- if(t>=2 && scenariosr[i,t] < scenariosr[i,t-1]){
- scenariosr[i,t] <- scenariosr[i,t-1]
- }
- }
- }
-
- ## we need to adjust the recovery because intex has some embedded amortization assumptions
- ## that we can't turn off (multiply by recov.adj)
- intexrecov <- matrix(0, n.scenarios, dim(distDR)[1])
- for(i in 1:dim(distDR)[1]){
- if(i==1){
- intexrecov[,i] <- recov.adj * (scenariosr[,i]/scenariosd[,1])
- }else{
- intexrecov[,i] <- recov.adj * (scenariosr[,i]-scenariosr[,i-1])/(scenariosd[,i]-scenariosd[,i-1])
- }
- }
- deal.dates <- getdealschedule(deal.data, "Quarterly")
- deal.dates <- deal.dates[deal.dates>=settledate]
- cdr <- cdrfromscenarios(scenariosd, deal.dates, tradedate)
- ## linear approximation for monthly scenarios
- deal.data <- getdealdata(dealnames[j], tradedate)
- deal.datesmonthly <- getdealschedule(deal.data, "Monthly")
- deal.datesmonthly <- deal.datesmonthly[deal.datesmonthly>=settledate]
-
- cdrmonthly <- matrix(0, n.scenarios, length(deal.datesmonthly))
- recoverymonthly <- matrix(0, n.scenarios, length(deal.datesmonthly))
- scenariosrmonthly <- matrix(0, n.scenarios, length(deal.datesmonthly))
- scenariosdmonthly <- matrix(0, n.scenarios, length(deal.datesmonthly))
- for(i in 1:n.scenarios){
- cdrmonthly[i,] <- approx(deal.dates, cdr[i,], deal.datesmonthly, rule=2)$y
- recoverymonthly[i,] <- approx(deal.dates, intexrecov[i,], deal.datesmonthly, rule=2)$y
- scenariosrmonthly[i,] <- approx(deal.dates, scenariosr[i,], deal.datesmonthly, rule=2)$y
- scenariosdmonthly[i,] <- approx(deal.dates, scenariosd[i,], deal.datesmonthly, rule=2)$y
- }
- recoverymonthly <- pmin(recoverymonthly,1)
- recoverymonthly[!is.finite(recoverymonthly)] <- 100
-
- if(!is.na(deal.data$reinv_end_date) && deal.data$reinv_end_date <= tradedate){
- ## we cap rolling maturity at the current weighted average maturity of the portfolio
- rollingmaturity <- (crossprod(sapply(deal.portfolio$SC, creditcurve.maturity),
- deal.portfolio$notional)/sum(deal.portfolio$notional)
- - as.numeric(tradedate))
- }else{
- rollingmaturity <- params$rollingmaturity
- }
-
- ## compute reinvestment price
- cdrmonthly.dt <- data.table(date=deal.datesmonthly, t(cdrmonthly), key="date")
- recoverymonthly.dt <- data.table(date=deal.datesmonthly, t(recoverymonthly), key="date")
- if(reinvflags[j]){
- reinvprices <- compute.reinvprices(dealnames[j], cdrmonthly.dt, recoverymonthly.dt,
- params, rollingmaturity, tradedate)
- }else{
- reinvprices <- list()
- }
-
- save.dir <- file.path(root.dir, "Scenarios", paste("Intex curves", tradedate, sep="_"), "csv")
- if(!file.exists(save.dir)){
- dir.create(save.dir, recursive = T)
- }
-
- write.table(cdrmonthly,
- file= file.path(save.dir, paste0(dealnames[j],"-cdr.csv")),
- row.names=F, col.names=F, sep=",")
- write.table(100 * recoverymonthly,
- file=file.path(save.dir, paste0(dealnames[j],"-recovery.csv")),
- row.names=F, col.names=F, sep=",", na="NaN")
- write.table(reinvprices, file = file.path(save.dir, paste0(dealnames[j], "-reinvprices.csv")),
- row.names=F, col.names=T, sep=",")
-
- configfile <- file.path(save.dir, paste0(dealnames[j], ".config"))
- config <- list(rollingmat = as.integer(rollingmaturity/365*12),
- reinvflag = reinvflags[j])
- cat(as.yaml(config), file = configfile)
- save(scenariosd, scenariosr, dist.joint, file=file.path(save.dir, paste0(dealnames[j], ".RData")),
- compress="xz")
-
- cat("generated scenarios for:", dealnames[j], "\n")
-}
+library(doParallel)
+library(yaml)
+
+hostname <- system("hostname", intern=TRUE)
+if(hostname=="debian"){
+ registerDoParallel(8)
+}else{
+ registerDoParallel(4)
+}
+
+args <- commandArgs(trailingOnly=TRUE)
+
+if(.Platform$OS.type == "unix"){
+ root.dir <- "/home/share/CorpCDOs"
+}else{
+ root.dir <- "//WDSENTINEL/share/CorpCDOs"
+}
+
+code.dir <- if(Sys.getenv("CODE_DIR")=="") root.dir else Sys.getenv("CODE_DIR")
+source(file.path(code.dir, "code", "R", "intex_deal_functions.R"), chdir=TRUE)
+source(file.path(code.dir, "code", "R", "yieldcurve.R"))
+source(file.path(code.dir, "code", "R", "serenitasdb.R"), chdir=TRUE)
+source(file.path(code.dir, "code", "R", "tranche_functions.R"))
+
+if(interactive()) {
+ tradedate <- as.Date("2016-02-25")
+ dealnames <- c("beto", "ozlmf5")
+ reinvflags <- c(TRUE, TRUE)
+}else{
+ tradedate <- as.Date(args[1])
+ if(length(args) >=2){
+ argslist <- strsplit(args[-1], ",")
+ dealnames <- unlist(lapply(argslist, function(x)x[1]))
+ reinvflags <- as.logical(unlist(lapply(argslist, function(x)x[2])))
+ }
+}
+
+calibration.date <- addBusDay(tradedate, -1)
+settledate <- addBusDay(tradedate, 3)
+calibration <- read.table(file.path(root.dir, "Scenarios", "Calibration",
+ paste0("calibration-", calibration.date,".csv")), sep=",", header=T)
+Z <- calibration$Z
+w <- calibration$w
+exportYC(calibration.date)
+
+Ngrid <- 201
+support <- seq(0, 1, length = Ngrid)
+n.scenarios <- 100
+recov.adj <- 1
+params <- yaml.load_file(file.path(root.dir, "code", "etc", "params.yml"))
+
+for(j in seq_along(dealnames)){
+ load(file.path(root.dir, "Scenarios", paste("Portfolios", tradedate, sep="_"),
+ paste(dealnames[j], "RData", sep=".")))
+ if(is.na(deal.data$reinv_end_date)){
+ reinvflags[j] <- FALSE
+ }
+ dp <- A$DP
+ pp <- A$PP
+ dpmod <- MFupdate.prob(Z, w, deal.portfolio$beta, dp)
+ ppmod <- MFupdate.prob(-Z, w, deal.portfolio$beta, pp)
+ dist.joint <- MFlossdist.prepay.joint(w, Z, deal.portfolio$beta, dp, dpmod, pp, ppmod,
+ deal.weights, 1-S, Ngrid)
+ dist.joint <- pmax(dist.joint, 0)
+ distDR <- dist.transform(dist.joint)
+ ## compute E(R|D)
+ R <- matrix(0, Ngrid, dim(distDR)[1])
+ for(t in 1:dim(distDR)[1]){
+ R[,t] <- sweep(distDR[t,,], 1, rowSums(distDR[t,,]), "/") %*% support
+ R[1,t] <- 0
+ if(t >= 2){
+ R[,t] <- pmax(R[,t], R[,t-1])
+ }
+ }
+
+ ## compute scenariosd
+ scenariosd <- matrix(0, n.scenarios, dim(distDR)[1])
+ scenariosr <- matrix(0, n.scenarios, dim(distDR)[1])
+ percentiles <- seq(0, 1, 1/n.scenarios)
+ for(t in 1:dim(distDR)[1]){
+ D <- rowSums(distDR[t,,])
+ Dfun <- splinefun(c(0, cumsum(D)), c(0, support), "hyman")
+ Rfun <- approxfun(support, R[,t], rule=2)
+ for(i in 1:n.scenarios){
+ ## this is roughtly E(D|D is in ith percentile)
+ ## using trapezoidal approximation
+ if(i==1){
+ scenariosd[i,t] <- 0.5* Dfun(0.01)
+ }else{
+ scenariosd[i,t] <- 0.5 * (Dfun((i-1)*0.01)+Dfun(i*0.01))
+ }
+ if(t>=2 && scenariosd[i,t] < scenariosd[i,t-1]){
+ scenariosd[i,t] <- scenariosd[i,t-1]
+ }
+ scenariosr[i,t] <- Rfun(scenariosd[i,t])
+ if(t>=2 && scenariosr[i,t] < scenariosr[i,t-1]){
+ scenariosr[i,t] <- scenariosr[i,t-1]
+ }
+ }
+ }
+
+ ## we need to adjust the recovery because intex has some embedded amortization assumptions
+ ## that we can't turn off (multiply by recov.adj)
+ intexrecov <- matrix(0, n.scenarios, dim(distDR)[1])
+ for(i in 1:dim(distDR)[1]){
+ if(i==1){
+ intexrecov[,i] <- recov.adj * (scenariosr[,i]/scenariosd[,1])
+ }else{
+ intexrecov[,i] <- recov.adj * (scenariosr[,i]-scenariosr[,i-1])/(scenariosd[,i]-scenariosd[,i-1])
+ }
+ }
+ deal.dates <- getdealschedule(deal.data, "Quarterly")
+ deal.dates <- deal.dates[deal.dates>=settledate]
+ cdr <- cdrfromscenarios(scenariosd, deal.dates, tradedate)
+ ## linear approximation for monthly scenarios
+ deal.data <- getdealdata(dealnames[j], tradedate)
+ deal.datesmonthly <- getdealschedule(deal.data, "Monthly")
+ deal.datesmonthly <- deal.datesmonthly[deal.datesmonthly>=settledate]
+
+ cdrmonthly <- matrix(0, n.scenarios, length(deal.datesmonthly))
+ recoverymonthly <- matrix(0, n.scenarios, length(deal.datesmonthly))
+ scenariosrmonthly <- matrix(0, n.scenarios, length(deal.datesmonthly))
+ scenariosdmonthly <- matrix(0, n.scenarios, length(deal.datesmonthly))
+ for(i in 1:n.scenarios){
+ cdrmonthly[i,] <- approx(deal.dates, cdr[i,], deal.datesmonthly, rule=2)$y
+ recoverymonthly[i,] <- approx(deal.dates, intexrecov[i,], deal.datesmonthly, rule=2)$y
+ scenariosrmonthly[i,] <- approx(deal.dates, scenariosr[i,], deal.datesmonthly, rule=2)$y
+ scenariosdmonthly[i,] <- approx(deal.dates, scenariosd[i,], deal.datesmonthly, rule=2)$y
+ }
+ recoverymonthly <- pmin(recoverymonthly,1)
+ recoverymonthly[!is.finite(recoverymonthly)] <- 100
+
+ if(!is.na(deal.data$reinv_end_date) && deal.data$reinv_end_date <= tradedate){
+ ## we cap rolling maturity at the current weighted average maturity of the portfolio
+ rollingmaturity <- (crossprod(sapply(deal.portfolio$SC, creditcurve.maturity),
+ deal.portfolio$notional)/sum(deal.portfolio$notional)
+ - as.numeric(tradedate))
+ }else{
+ rollingmaturity <- params$rollingmaturity
+ }
+
+ ## compute reinvestment price
+ cdrmonthly.dt <- data.table(date=deal.datesmonthly, t(cdrmonthly), key="date")
+ recoverymonthly.dt <- data.table(date=deal.datesmonthly, t(recoverymonthly), key="date")
+ if(reinvflags[j]){
+ reinvprices <- compute.reinvprices(dealnames[j], cdrmonthly.dt, recoverymonthly.dt,
+ params, rollingmaturity, tradedate)
+ }else{
+ reinvprices <- list()
+ }
+
+ save.dir <- file.path(root.dir, "Scenarios", paste("Intex curves", tradedate, sep="_"), "csv")
+ if(!file.exists(save.dir)){
+ dir.create(save.dir, recursive = T)
+ }
+
+ write.table(cdrmonthly,
+ file= file.path(save.dir, paste0(dealnames[j],"-cdr.csv")),
+ row.names=F, col.names=F, sep=",")
+ write.table(100 * recoverymonthly,
+ file=file.path(save.dir, paste0(dealnames[j],"-recovery.csv")),
+ row.names=F, col.names=F, sep=",", na="NaN")
+ write.table(reinvprices, file = file.path(save.dir, paste0(dealnames[j], "-reinvprices.csv")),
+ row.names=F, col.names=T, sep=",")
+
+ configfile <- file.path(save.dir, paste0(dealnames[j], ".config"))
+ config <- list(rollingmat = as.integer(rollingmaturity/365*12),
+ reinvflag = reinvflags[j])
+ cat(as.yaml(config), file = configfile)
+ save(scenariosd, scenariosr, dist.joint, file=file.path(save.dir, paste0(dealnames[j], ".RData")),
+ compress="xz")
+
+ cat("generated scenarios for:", dealnames[j], "\n")
+}
diff --git a/R/db.R b/R/db.R
index d4c4161b..bdfba82f 100644
--- a/R/db.R
+++ b/R/db.R
@@ -1,17 +1,17 @@
-library(DBI)
-
-dbConn <- function(dbname){
- switch(dbname,
- ET = dbConnect(RPostgres::Postgres(),
- dbname="ET",
- user="et_user",
- host="debian"),
- serenitasdb = dbConnect(RPostgres::Postgres(),
- dbname="serenitasdb",
- user = "serenitas_user",
- host="debian"),
- dawndb = dbConnect(RPostgres::Postgres(),
- dbname="dawndb",
- user = "dawn_user",
- host="debian"))
-}
+library(DBI)
+
+dbConn <- function(dbname){
+ switch(dbname,
+ ET = dbConnect(RPostgres::Postgres(),
+ dbname="ET",
+ user="et_user",
+ host="debian"),
+ serenitasdb = dbConnect(RPostgres::Postgres(),
+ dbname="serenitasdb",
+ user = "serenitas_user",
+ host="debian"),
+ dawndb = dbConnect(RPostgres::Postgres(),
+ dbname="dawndb",
+ user = "dawn_user",
+ host="debian"))
+}
diff --git a/R/interpweights.R b/R/interpweights.R
index 57995c89..acf06c82 100644
--- a/R/interpweights.R
+++ b/R/interpweights.R
@@ -1,125 +1,125 @@
-interpweights <- function(w, v1, v2){
- #Given L=(w,v1), compute neww such that newL=(new,v2)=L in distribution
- cumw <- cumsum(w)
- neww <- splinefun(v1, cumw, method= "monoH.FC")(v2, deriv=1)
- #neww <- diff(newcumw)
- interpweights <- neww/sum(neww)
- return(interpweights)
-}
-
-interpvalues <- function(w, v, neww){
- ## Given a distribution D=(w,v), compute new values
- ## such that Dnew=(neww, newv) equals D in distribution
- cumw <- cumsum(w)
- cdf <- splinefun(v, cumw, method="hyman")
- eps <- 1e-3
- newv <- rep(0, length(neww))
- cumneww <- cumsum(neww)
- mid <- 0
- for(i in 1:length(neww)){
- iter <- 0
- ## do binary search
- hi <- cdf(1)
- lo <- mid
- if(hi < cumneww[i]){
- newv[i] <- hi
- next
- }
- if(cdf(lo) > cumneww[i]){
- newv[i] <- lo
- next
- }
- mid <- (lo+hi)/2
- iter <- 0
- while(abs(cdf(mid) - cumneww[i])>eps){
- if(cdf(mid) > cumneww[i]){
- hi <- mid
- }else{
- lo <- mid
- }
- mid <- (lo+hi)/2
- }
- newv[i] <- mid
- }
- return(newv)
-}
-
-interpvalues.distr <- function(w, v, neww){
- ## same as interpvalues, but using the distr
- ## package. need to check how good it is
- require(distr)
- D <- DiscreteDistribution(v, w)
- return( q(D)(cumsum(neww)) )
-}
-
-adjust_scenario <- function(scenario, epsilon){
- 1-(1-scenario)^(1/(1+epsilon))
-}
-
-adjust_weights <- function(weights, scenario, epsilon){
- interpweights(weights,scenario,adjust_scenario(scenario,epsilon))
-}
-
-obj <- function(epsilon, vecpv, prob, support, cte){
- newprob <- adjust_weights(prob, support, epsilon)
- return( 1 - crossprod(newprob, vecpv) - cte)
-}
-
-tweak <- function(min, max, vecpv, prob, support, cte){
- mid <- (min + max)/2
- objective <- obj(mid, vecpv, prob, support, cte)
- while( abs(objective) > 1e-6){
- if(objective > 0){
- min <- mid
- }else{
- max <- mid
- }
- mid <- (min+max)/2
- objective <- obj(mid, vecpv, prob, support, cte)
- }
- return( mid )
-}
-
-interpweightsadjust <- function(w, v1, v2, vecpv){
- interpweightsadjust <- interpweights(w, v1, v2)
- epsilon <- tweak(-0.5, 0.5, vecpv, interpweightsadjust, v2, 1)
- return( adjust_weights(interpweightsadjust, v2, epsilon) )
-}
-
-transformweightslike <- function(p1, v1, p2, v2, p, v){
- cump2 <- cumsum(p2)
- cump1 <- cumsum(p1)
- P1 <- splinefun(v1,cump1,method= "monoH.FC")
- dP1 <- function(x){P1(x,deriv=1)}
- pomme <- interpweights(p2,v2,v)
- pomme <- cumsum(pomme)
- r <- rep(0,length(pomme))
- for(i in 1:length(pomme)){
- r[i] <- inverse(P1,dP1,pomme[i])
- }
- return(r)
-}
-
-clipw <- function(x){
- write(x,file="clipboard",sep="\n")
-}
-
-clipr <- function(){
- scan(file="clipboard")
-}
-
-sclipr <- function(){
- scan(file="clipboard",what="character")
-}
-
-inverse <- function(f,Df,x, x0=x){
- #inverse a function by the newton's method.
- x1 <- x0-f(x0)/(Df(x0)-1)
- counter <- 0
- while(abs(x1-x0)>1e-6&&counter<500){
- x0 <- x1
- x1 <- x0-(f(x0)-x)/Df(x0)
- counter <- counter+1
- }
- return(x1)
-}
+interpweights <- function(w, v1, v2){
+ #Given L=(w,v1), compute neww such that newL=(new,v2)=L in distribution
+ cumw <- cumsum(w)
+ neww <- splinefun(v1, cumw, method= "monoH.FC")(v2, deriv=1)
+ #neww <- diff(newcumw)
+ interpweights <- neww/sum(neww)
+ return(interpweights)
+}
+
+interpvalues <- function(w, v, neww){
+ ## Given a distribution D=(w,v), compute new values
+ ## such that Dnew=(neww, newv) equals D in distribution
+ cumw <- cumsum(w)
+ cdf <- splinefun(v, cumw, method="hyman")
+ eps <- 1e-3
+ newv <- rep(0, length(neww))
+ cumneww <- cumsum(neww)
+ mid <- 0
+ for(i in 1:length(neww)){
+ iter <- 0
+ ## do binary search
+ hi <- cdf(1)
+ lo <- mid
+ if(hi < cumneww[i]){
+ newv[i] <- hi
+ next
+ }
+ if(cdf(lo) > cumneww[i]){
+ newv[i] <- lo
+ next
+ }
+ mid <- (lo+hi)/2
+ iter <- 0
+ while(abs(cdf(mid) - cumneww[i])>eps){
+ if(cdf(mid) > cumneww[i]){
+ hi <- mid
+ }else{
+ lo <- mid
+ }
+ mid <- (lo+hi)/2
+ }
+ newv[i] <- mid
+ }
+ return(newv)
+}
+
+interpvalues.distr <- function(w, v, neww){
+ ## same as interpvalues, but using the distr
+ ## package. need to check how good it is
+ require(distr)
+ D <- DiscreteDistribution(v, w)
+ return( q(D)(cumsum(neww)) )
+}
+
+adjust_scenario <- function(scenario, epsilon){
+ 1-(1-scenario)^(1/(1+epsilon))
+}
+
+adjust_weights <- function(weights, scenario, epsilon){
+ interpweights(weights,scenario,adjust_scenario(scenario,epsilon))
+}
+
+obj <- function(epsilon, vecpv, prob, support, cte){
+ newprob <- adjust_weights(prob, support, epsilon)
+ return( 1 - crossprod(newprob, vecpv) - cte)
+}
+
+tweak <- function(min, max, vecpv, prob, support, cte){
+ mid <- (min + max)/2
+ objective <- obj(mid, vecpv, prob, support, cte)
+ while( abs(objective) > 1e-6){
+ if(objective > 0){
+ min <- mid
+ }else{
+ max <- mid
+ }
+ mid <- (min+max)/2
+ objective <- obj(mid, vecpv, prob, support, cte)
+ }
+ return( mid )
+}
+
+interpweightsadjust <- function(w, v1, v2, vecpv){
+ interpweightsadjust <- interpweights(w, v1, v2)
+ epsilon <- tweak(-0.5, 0.5, vecpv, interpweightsadjust, v2, 1)
+ return( adjust_weights(interpweightsadjust, v2, epsilon) )
+}
+
+transformweightslike <- function(p1, v1, p2, v2, p, v){
+ cump2 <- cumsum(p2)
+ cump1 <- cumsum(p1)
+ P1 <- splinefun(v1,cump1,method= "monoH.FC")
+ dP1 <- function(x){P1(x,deriv=1)}
+ pomme <- interpweights(p2,v2,v)
+ pomme <- cumsum(pomme)
+ r <- rep(0,length(pomme))
+ for(i in 1:length(pomme)){
+ r[i] <- inverse(P1,dP1,pomme[i])
+ }
+ return(r)
+}
+
+clipw <- function(x){
+ write(x,file="clipboard",sep="\n")
+}
+
+clipr <- function(){
+ scan(file="clipboard")
+}
+
+sclipr <- function(){
+ scan(file="clipboard",what="character")
+}
+
+inverse <- function(f,Df,x, x0=x){
+ #inverse a function by the newton's method.
+ x1 <- x0-f(x0)/(Df(x0)-1)
+ counter <- 0
+ while(abs(x1-x0)>1e-6&&counter<500){
+ x0 <- x1
+ x1 <- x0-(f(x0)-x)/Df(x0)
+ counter <- counter+1
+ }
+ return(x1)
+}
diff --git a/R/intex_deal_functions.R b/R/intex_deal_functions.R
index 03282783..270fc07d 100644
--- a/R/intex_deal_functions.R
+++ b/R/intex_deal_functions.R
@@ -1,440 +1,440 @@
-library(RQuantLib)
-library(data.table)
-library(doParallel)
-library(lossdistrib)
-
-hostname <- system("hostname", intern=TRUE)
-if(hostname=="debian"){
- registerDoParallel(8)
-}else{
- registerDoParallel(4)
-}
-
-source("cds_functions_generic.R")
-source("db.R")
-etdb <- dbConn("ET")
-
-getdealdata <- function(dealname, workdate){
- sqlstring <- paste0("select marketvalue from et_deal_model_numbers where dealname=$1 and ",
- "updatedate in (select max(updatedate) from et_deal_model_numbers where ",
- "dealname = $2 and updatedate<=$3)")
- mv <- dbGetQuery(etdb, sqlstring,
- params = list(dealname, dealname, workdate))$marketvalue
-
- sqlstring <- paste0("select \"Curr Collat Bal\", reinv_end_date, ",
- "first_pay_date , maturity, \"Principal Bal\" , pay_day from ",
- "historical_clo_universe($1, $2)")
- dealdata <- dbGetQuery(etdb, sqlstring, params=list(dealname, workdate))
- if(!length(mv)){
- dealdata$mv <- NA
- }else{
- dealdata$mv <- mv
- }
- return(dealdata)
-}
-
-getcollateral <- function(dealname, date){
- if(missing(date)){
- collatdata <- dbGetQuery(etdb, "select * from et_aggdealinfo($1)",
- params=list(dealname))
- }else{
- collatdata <- dbGetQuery(etdb,
- "select * from et_aggdealinfo_historical($1, $2)",
- params=list(dealname, date))
- }
- return(collatdata)
-}
-
-listdealnames <- function(){
- sqlstring <- "select distinct dealname from clo_universe order by dealname"
- return( dbGetQuery(etdb, sqlstring))
-}
-
-cusip.data <- function(workdate = Sys.Date()){
- sqlstring <- "SELECT DISTINCT ON (cusip) cusip, maturity, coupon AS grosscoupon,
-spread, CASE WHEN floater_index like 'LIBOR%' THEN 'FLOAT' ELSE 'FIXED' END
-AS fixedorfloat, orig_moody FROM cusip_universe JOIN deal_indicative USING (dealname)
-WHERE updatedate<=$1 ORDER BY cusip, updatedate DESC"
- data <- dbGetQuery(etdb, sqlstring, workdate)
- data <- data.table(data)
- setkey(data, "cusip")
- return( data )
-}
-
-recovery <- function(collateral) {
- ## return assumed recovery based on assumptions from recovery.assumptions
- if(!is.na(collateral$secondlien) && collateral$secondlien){
- collateral$assettype <- "SecondLien"
- }
- recovery <- with(global.params,
- as.numeric(recovery.assumptions[collateral$assettype]))
- if( !is.na(collateral$covlite) && collateral$covlite) {
- recovery <- recovery - global.params$recovery.assumptions$Adj_Covlite
- }
- if( !is.na(collateral$iscdo) && collateral$iscdo ){
- recovery <- 0
- }
- ## price is too low need to lower the assumed recovery
- if(!is.na(collateral$price) && recovery > collateral$price/100 - 0.1){
- recovery <- max(collateral$price/100-0.2, 0)
- }
- return(recovery)
-}
-
-dealnamefromcusip <- function(cusips){
- ## wrapper around the sql function
- sqlstr <- sprintf("select * from dealname_from_cusip('%s')",
- paste(cusips, collapse="','"))
- r <- dbGetQuery(etdb, sqlstr)
- return( r$p_dealname )
-}
-
-cusipsfromdealnames <- function(dealnames){
- sqlstring <-
- sprintf("select unnest(\"Deal Cusip List\") from deal_indicative where dealname in ('%s')",
- paste(dealnames, collapse="','"))
- return( dbGetQuery(etdb, sqlstring)$unnest )
-}
-
-fithazardrate.fast <- function(collateral, eps=1e-6){
- lambda <- 0.05
- cs <- couponSchedule(collateral$nextpaydate, collateral$maturity,
- collateral$frequency, collateral$fixedorfloat,
- collateral$grosscoupon * 0.01, collateral$spread*0.01)
- R <- recovery(collateral)
- while(abs(bondprice(lambda, cs, R) * 100 - collateral$price) > eps){
- lambda <- lambda - (bondprice(lambda, cs, R) - 0.01*collateral$price)/dbondprice(lambda, cs, R)
- }
- return( lambda )
-}
-
-vanillabondprice <- function(h, collateral, prepay=TRUE) {
- R <- recovery(collateral)
- cs <- couponSchedule(collateral$nextpaydate, collateral$maturity,
- collateral$frequency, collateral$fixedorfloat,
- collateral$grosscoupon*0.01, collateral$spread*0.01)
- if(prepay){
- dpc <- new("defaultprepaycurve", dates=cs$dates, hazardrates=rep(h,length(cs$dates)),
- prepayrates=rep(k(h), length(cs$dates)))
- }else{
- dpc <- new("defaultprepaycurve", dates=cs$dates, hazardrates=rep(h,length(cs$dates)),
- prepayrates=numeric(0))
- }
- return( bondprice(cs, dpc, R) )
-}
-
-dvanillabondprice <- function(hazardrate, collateral) {
- R <- recovery(collateral)
- cs <- couponSchedule(collateral$nextpaydate, collateral$maturity,
- collateral$frequency, collateral$fixedorfloat,
- collateral$grosscoupon*0.01, collateral$spread*0.01)
- return( bondprice(hazardrate, cs, R) )
-}
-
-fithazardrate <- function(collateral){
- R <- recovery(collateral)
- cs <- couponSchedule(collateral$nextpaydate, collateral$maturity,
- collateral$frequency, collateral$fixedorfloat,
- collateral$grosscoupon*0.01, collateral$spread*0.01)
- f <- function(lambda){
- u <- bondprice(lambda, cs, R )
- return( (u * 100-collateral$price)^2 )
- }
- return( optimize(f, c(0,1), tol=1e-6)$minimum )
-}
-
-stackcurve <- function(SC, line.item, global.params, startdate){
- if(line.item$nextpaydate> line.item$maturity){
- SC@curve@hazardrates <- 0
- SC@curve@prepayrates <- 0
- SC@curve@dates <- line.item$maturity
- return( SC )
- }
- newdates <- seq(line.item$nextpaydate, line.item$maturity, by="3 months")
- if(newdates[length(newdates)]<line.item$maturity){
- newdates <- c(newdates, line.item$maturity)
- }
- newdates <- c(startdate, newdates[newdates>startdate])
- if(is.na(line.item$assettype) || line.item$assettype=="Loan"){
- hvec <- global.params$shape(yearFrac(today(), newdates[-1])) * global.params$defaultloanhazardrate
- kvec <- global.params$alpha * exp(-global.params$beta * hvec)
- }else if(line.item$assettype=="Bond" || line.item$assettype=="Credit Default Swap"
- || (!is.na(line.item$iscdo) && line.item$iscdo)){
- hvec <- global.params$shape(yearFrac(today(), newdates[-1])) * global.params$defaultbondhazardrate
- kvec <- rep(0, length(hvec))
- }
- SC@curve@hazardrates <- c(SC@curve@hazardrates, hvec)
- SC@curve@prepayrates <- c(SC@curve@prepayrates, kvec)
- SC@curve@dates <- c(SC@curve@dates, newdates[-1])
- return(SC)
-}
-
-buildSC.matured <- function(SC, line.item, reinvdate, dealmaturity, global.params, startdate){
- if(!is.na(reinvdate) && startdate<=reinvdate){ #reinvest
- line.item$maturity <- min(dealmaturity, startdate + global.params$rollingmaturity)
- SC <- stackcurve(SC, line.item, global.params, startdate)
- }else{ #no reinvestment
- SC@curve@dates <- startdate
- SC@curve@hazardrates <- 0
- SC@curve@prepayrates <- 0
- }
- return( SC )
-}
-
-buildSC <- function(line.item, reinvdate, dealmaturity, global.params, startdate){
- if(!is.na(line.item$iscdo) && line.item$iscdo && is.na(line.item$price)){
- ##we have prices for some cdos e.g. 210795PS3
- if(is.na(line.item$orig) || line.item$orig_moody == "NA" || length(line.item$orig_moody)==0){
- line.item$orig_moody <- "NR"
- }
- line.item$price <- as.numeric(global.params$cdoprices[gsub("\\d", "", line.item$orig_moody)])
- }
- ##build survival curve
- SC <- new("creditcurve", recovery=recovery(line.item), startdate=startdate,
- issuer=line.item$issuername)
- SC@curve <- new("defaultprepaycurve", dates=as.Date(character(0)))
- ## defaulted asset
- if(!is.na(line.item$defaultedflag) && line.item$defaultedflag){
- if(is.na(line.item$price)){
- line.item$currentbalance <- line.item$currentbalance * recovery(line.item)
- }else{
- line.item$currentbalance <- line.item$currentbalance * line.item$price/100
- }
- line.item$price <- 100
- SC@recovery <- 0.7
- SC@startdate <- startdate + global.params$defaultedlag
- if(global.params$reinvflag){#we reinvest recovery assets
- line.item$maturity <- min(dealmaturity, SC@startdate + global.params$rollingmaturity)
- line.item$nextpaydate <- SC@startdate
- ## automatic reinvest
- SC<- stackcurve(SC, line.item, global.params, SC@startdate)
- }else{
- SC <- NULL
- }
-
- }else if(line.item$maturity <= startdate){#matured asset
- SC <- buildSC.matured(SC, line.item, reinvdate, dealmaturity, global.params, startdate)
- if(is.na(line.item$price))line.item$price <- 100
- }else if(is.na(line.item$price)){ #missing price
- SC <- stackcurve(SC, line.item, global.params, SC@startdate)
- cs <- couponSchedule(line.item$nextpaydate, line.item$maturity,
- line.item$frequency, line.item$fixedorfloat,
- line.item$grosscoupon*0.01, line.item$spread*0.01, startdate)
- line.item$price <- bondpv(cs, SC@curve, recovery(line.item), startdate) * 100
- }else{ #normal case
- if(!is.na(line.item$assettype) && line.item$assettype=="Bond"){ #no prepay rate
- alpha <- 0
- }else{
- alpha <- global.params$alpha
- }
- try <- bondhazardrate.shaped(line.item, global.params$shape,
- recovery(line.item), alpha, global.params$beta, startdate)
- if(is.null(try)){
- SC <- stackcurve(SC, line.item, global.params, SC@startdate)
- }else{
- SC@curve <- try
- }
- }
- if(!is.na(reinvdate) && !is.null(SC) && creditcurve.maturity(SC) <= reinvdate){
- ## if reinvdate is missing, assume no reinvestment
- ## otherwise reinvest
- newstartdate <- line.item$maturity
- line.item$maturity <- min(dealmaturity, newstartdate + global.params$rollingmaturity)
- SC <- stackcurve(SC, line.item, global.params, newstartdate)
- }
- if(is.na(line.item$price)){
- ## TODO
- }
- beta <- if(!is.na(line.item$iscdo) && line.item$iscdo) 1 else global.params$defaultcorr
- return( list(SC=SC, notional=line.item$currentbalance, price = line.item$price, beta = beta) )
-}
-
-buildSC.portfolio <- function(dealname, dealdata, cusipdata, global.params, startdate = Sys.Date()) {
- collatdata <- data.table(getcollateral(dealname, startdate))
- setkey(collatdata, "cusip")
- ## replace the cdo fields by bloomberg data
- collatdata[cusipdata,
- `:=`(maturity=i.maturity, fixedorfloat=i.fixedorfloat,
- spread=i.spread, grosscoupon=i.grosscoupon, orig_moody=i.orig_moody, iscdo=TRUE),
- allow.cartesian=TRUE]
-
- portfolio <- foreach(line.item = iter(collatdata, by='row')) %:% {
- when( !is.na(line.item$maturity) && line.item$currentbalance > 1
- && !is.na(line.item$assettype) && line.item$assettype!="Equity") } %dopar% {
- buildSC(line.item, dealdata$reinv_end_date, dealdata$maturity, global.params, startdate)
- }
- ## non-parallel version for debugging
- ## portfolio <- c()
- ## for(i in 1:nrow(collatdata)){
- ## line.item <- collatdata[i,]
- ## if(is.na(line.item$maturity) || line.item$currentbalance <= 1){
- ## next
- ## }
- ## portfolio <- c(portfolio, buildSC(line.item, dealdata$reinv_end_date, dealdata$maturity, global.params, startdate))
- ## }
- missingpricenotional <- sum(collatdata[is.na(price) & maturity>startdate &
- (is.na(iscdo)|!iscdo), currentbalance])
- cdonotional <- sum(collatdata[!is.na(iscdo)&(iscdo==TRUE),currentbalance])
- collatbalance <- sum(collatdata[,currentbalance])
- return( list(notional=vapply(portfolio, function(x)x$notional, numeric(1)),
- beta = vapply(portfolio, function(x)x$beta, numeric(1)),
- price = vapply(portfolio, function(x)x$price, numeric(1)),
- SC = lapply(portfolio, function(x)x$SC),
- stale = missingpricenotional/collatbalance,
- cdopercentage = cdonotional/collatbalance,
- collatbalance = collatbalance
- ) )
-}
-
-cdrfromscenarios <- function(scenarios, dates, tradedate){
- ## compute the forward cdr rates to pass to intex
- ## so that we match the default curves in scenarios
- cdr <- matrix(0, nrow(scenarios), ncol(scenarios))
- for(i in 1:nrow(scenarios)){
- cdr[i,] <- 100*(1-exp(diff(c(0, log(1-scenarios[i,])))))/diff(c(0, yearFrac(tradedate, dates)))
- }
- return( cdr )
-}
-
-recoveryfromscenarios <- function(scenariosd, scenariosr){
- ## compute the forward recovery rate based on the term
- ## structure of recovery scenarios
- ## we run into trouble for very stressed scenarios
- ## this code should cap the scenarios at 0 if this happens
- intexrecov <- matrix(0, n.scenarios, ncol(scenariosr))
- scenariosr <- scenariosr
- for(i in 1:n.scenarios){
- current <- 1
- intexrecov[i,1] <- scenariosr[i,1]
- for(t in 2:ncol(scenariosr)){
- w <- scenariosd[i,current]/scenariosd[i,t]
- ## if(scenariosr[i,t]-w*scenariosr[i,current]>=0){
- ## intexrecov[i,t] <- (scenariosr[i,t]-w*scenariosr[i,current])/(1-w)
- ## current <- current+1
- ## }else{
- ## intexrecov[i,t] <- 0
- ## }
- intexrecov[i,t] <- (scenariosr[i,t]-w*scenariosr[i,current])/(1-w)
- current <- current + 1
- }
- }
- return(intexrecov)
-}
-
-recoveryfromscenarios.fast <- function(scenariosr, scenariosd){
- r <- rbind(scenariosr[,1]/scenariosd[,1],
- apply(scenariosr, 1, diff)/apply(scenariosd, 1, diff))
- return( t(r) )
-}
-
-severityfromscenarios <- function(scenariosd, scenariosr){
- ## compute the forward recovery rate based on the term
- ## structure of recovery scenarios
- ## we run into trouble for very stressed scenarios
- ## this code should cap the scenarios at 0 if this happens
- intexseverity <- matrix(0, n.scenarios, ncol(scenariosr))
- for(i in 1:n.scenarios){
- current <- 1
- intexseverity[i,1] <- 1-scenariosr[i,1]
- for(t in 2:ncol(scenariosr)){
- w <- scenariosd[i,current]/scenariosd[i,t]
- intexseverity[i,t] <- 1 - (scenariosr[i,t]-w*scenariosr[i,current])/(1-w)
- current <- current+1
- }
- }
- return(intexseverity)
-}
-
-get.reinvassets <- function(dealname, tradedate){
- r <- list()
- sqlstr <- "select * from et_historicaldealinfo($1, $2) where ReinvFlag Is true"
- data <- dbGetQuery(etdb, sqlstr, params=list(dealname, tradedate))
- if(nrow(data)>0){
- for(i in 1:nrow(data)){
- r[[data$issuername[i]]] <- list(coupontype=data$fixedorfloat[i], liborfloor=data$liborfloor[i])
- }
- }
- return( r )
-}
-
-getpayday <- function(dealdata, tradedate){
- ## try to compute the previous pay date of a deal
- ## it relies on thwo things to be accurate: the pay_day
- ## as well as the first_pay_date (that's how we get the month)
- m <- as.numeric(format(dealdata$first_pay_date, "%m"))
- m <- m %%3+9
- y <- as.numeric(format(tradedate, "%Y"))
- y <- y - 1
- payday <- as.Date(sprintf("%s-%s-%s", y, m, dealdata$pay_day))
- i <- 1
- cal <- Calendar$new("UnitedStates")
- nextdate <- cal$advance(dates=payday, period = "3m", bdc = "Unadjusted")
- while(nextdate < tradedate){
- payday <- nextdate
- i <- i+1
- nextdate <- cal$advance(payday, 3*i, 2, bdc = "Unadjusted")
- }
- return(payday)
-}
-
-getdealschedule <- function(dealdata, freq = c("Monthly", "Quarterly"), tradedate=Sys.Date(),
- bdc = c("Unadjusted", "Following", "ModifiedFollowing")) {
- payday <- getpayday(dealdata, tradedate)
- freq <- match.arg(freq)
- bdc <- match.arg(bdc)
- params <- list(effectiveDate = getpayday(dealdata, tradedate),
- maturityDate = dealdata$maturity,
- period = freq,
- businessDayConvention = bdc,
- terminationDateConvention = "Unadjusted",
- dateGeneration = "Forward")
- return( Schedule(params) )
-}
-
-intexportfolio.forwardprice <- function(cdrmonthly, recoverymonthly, startdate, maturity,
- coupontype, margin, liborfloor){
- if(missing(liborfloor)||is.na(liborfloor)){
- currentcoupon <- margin
- }else{
- currentcoupon <- margin + liborfloor
- }
- forwardcs <- data.table(couponSchedule(nextpaydate=startdate+45, maturity,
- frequency="Q", coupontype, margin,
- currentcoupon, tradedate=startdate), key="dates")
- notionals <- cdrmonthly[date>=startdate, lapply(.SD,function(x)cumprod(1-x/100*1/12)),
- .SDcols=paste0("V",1:100)]
- recovery <- as.matrix(recoverymonthly[date>=startdate, .SD, .SDcols=paste0("V",1:100)])*
- -apply(rbind(1,as.matrix(notionals)), 2, diff)
- if(nrow(recovery)==1){
- recovery <- recovery*last(forwardcs[,df])
- }else{
- recovery <- data.table(dates=cdrmonthly[date>=startdate,date],apply(recovery, 2, cumsum),key="dates")
- recovery <- recovery[forwardcs, roll=TRUE]
- df <- recovery[,df]
- recovery <- t(df)%*%as.matrix(recovery[,lapply(.SD,function(x)diff(c(0,x))),.SDcols=paste0("V",1:100)])
- }
- notionals <- data.table(dates=cdrmonthly[date>=startdate,date], notionals, key="dates")
- outstanding <- notionals[forwardcs, roll=TRUE]
- mat.outstanding <- as.matrix(outstanding[,.SD,.SDcols=paste0("V",1:100)])
- po <- mat.outstanding[nrow(mat.outstanding),]*last(outstanding)[,df]
- io <- outstanding[, df*coupons]%*%mat.outstanding
- mean(recovery+po+io)
-}
-
-compute.reinvprices <- function(dealname, cdrmonthly, recoverymonthly, params, rollingmaturity, tradedate){
- reinvassets <- get.reinvassets(dealname, tradedate)
- reinvprices <- list()
- if(length(reinvassets)>0){
- maturity <- cdrmonthly$date[nrow(cdrmonthly)]
- for(assetname in names(reinvassets)){
- asset <- reinvassets[[assetname]]
- coupon <- if(asset$coupontype=="FLOAT") params$reinvfloat else params$reinvfixed
- reinvprices[[assetname]] <- foreach(date = iter(cdrmonthly$date), .combine=c) %dopar% {
- 100 * intexportfolio.forwardprice(cdrmonthly.dt, recoverymonthly.dt, date,
- min(date+rollingmaturity, maturity),
- asset$coupontype, coupon, asset$liborfloor/100)
- }
- }
- }
- return(reinvprices)
-}
+library(RQuantLib)
+library(data.table)
+library(doParallel)
+library(lossdistrib)
+
+hostname <- system("hostname", intern=TRUE)
+if(hostname=="debian"){
+ registerDoParallel(8)
+}else{
+ registerDoParallel(4)
+}
+
+source("cds_functions_generic.R")
+source("db.R")
+etdb <- dbConn("ET")
+
+getdealdata <- function(dealname, workdate){
+ sqlstring <- paste0("select marketvalue from et_deal_model_numbers where dealname=$1 and ",
+ "updatedate in (select max(updatedate) from et_deal_model_numbers where ",
+ "dealname = $2 and updatedate<=$3)")
+ mv <- dbGetQuery(etdb, sqlstring,
+ params = list(dealname, dealname, workdate))$marketvalue
+
+ sqlstring <- paste0("select \"Curr Collat Bal\", reinv_end_date, ",
+ "first_pay_date , maturity, \"Principal Bal\" , pay_day from ",
+ "historical_clo_universe($1, $2)")
+ dealdata <- dbGetQuery(etdb, sqlstring, params=list(dealname, workdate))
+ if(!length(mv)){
+ dealdata$mv <- NA
+ }else{
+ dealdata$mv <- mv
+ }
+ return(dealdata)
+}
+
+getcollateral <- function(dealname, date){
+ if(missing(date)){
+ collatdata <- dbGetQuery(etdb, "select * from et_aggdealinfo($1)",
+ params=list(dealname))
+ }else{
+ collatdata <- dbGetQuery(etdb,
+ "select * from et_aggdealinfo_historical($1, $2)",
+ params=list(dealname, date))
+ }
+ return(collatdata)
+}
+
+listdealnames <- function(){
+ sqlstring <- "select distinct dealname from clo_universe order by dealname"
+ return( dbGetQuery(etdb, sqlstring))
+}
+
+cusip.data <- function(workdate = Sys.Date()){
+ sqlstring <- "SELECT DISTINCT ON (cusip) cusip, maturity, coupon AS grosscoupon,
+spread, CASE WHEN floater_index like 'LIBOR%' THEN 'FLOAT' ELSE 'FIXED' END
+AS fixedorfloat, orig_moody FROM cusip_universe JOIN deal_indicative USING (dealname)
+WHERE updatedate<=$1 ORDER BY cusip, updatedate DESC"
+ data <- dbGetQuery(etdb, sqlstring, workdate)
+ data <- data.table(data)
+ setkey(data, "cusip")
+ return( data )
+}
+
+recovery <- function(collateral) {
+ ## return assumed recovery based on assumptions from recovery.assumptions
+ if(!is.na(collateral$secondlien) && collateral$secondlien){
+ collateral$assettype <- "SecondLien"
+ }
+ recovery <- with(global.params,
+ as.numeric(recovery.assumptions[collateral$assettype]))
+ if( !is.na(collateral$covlite) && collateral$covlite) {
+ recovery <- recovery - global.params$recovery.assumptions$Adj_Covlite
+ }
+ if( !is.na(collateral$iscdo) && collateral$iscdo ){
+ recovery <- 0
+ }
+ ## price is too low need to lower the assumed recovery
+ if(!is.na(collateral$price) && recovery > collateral$price/100 - 0.1){
+ recovery <- max(collateral$price/100-0.2, 0)
+ }
+ return(recovery)
+}
+
+dealnamefromcusip <- function(cusips){
+ ## wrapper around the sql function
+ sqlstr <- sprintf("select * from dealname_from_cusip('%s')",
+ paste(cusips, collapse="','"))
+ r <- dbGetQuery(etdb, sqlstr)
+ return( r$p_dealname )
+}
+
+cusipsfromdealnames <- function(dealnames){
+ sqlstring <-
+ sprintf("select unnest(\"Deal Cusip List\") from deal_indicative where dealname in ('%s')",
+ paste(dealnames, collapse="','"))
+ return( dbGetQuery(etdb, sqlstring)$unnest )
+}
+
+fithazardrate.fast <- function(collateral, eps=1e-6){
+ lambda <- 0.05
+ cs <- couponSchedule(collateral$nextpaydate, collateral$maturity,
+ collateral$frequency, collateral$fixedorfloat,
+ collateral$grosscoupon * 0.01, collateral$spread*0.01)
+ R <- recovery(collateral)
+ while(abs(bondprice(lambda, cs, R) * 100 - collateral$price) > eps){
+ lambda <- lambda - (bondprice(lambda, cs, R) - 0.01*collateral$price)/dbondprice(lambda, cs, R)
+ }
+ return( lambda )
+}
+
+vanillabondprice <- function(h, collateral, prepay=TRUE) {
+ R <- recovery(collateral)
+ cs <- couponSchedule(collateral$nextpaydate, collateral$maturity,
+ collateral$frequency, collateral$fixedorfloat,
+ collateral$grosscoupon*0.01, collateral$spread*0.01)
+ if(prepay){
+ dpc <- new("defaultprepaycurve", dates=cs$dates, hazardrates=rep(h,length(cs$dates)),
+ prepayrates=rep(k(h), length(cs$dates)))
+ }else{
+ dpc <- new("defaultprepaycurve", dates=cs$dates, hazardrates=rep(h,length(cs$dates)),
+ prepayrates=numeric(0))
+ }
+ return( bondprice(cs, dpc, R) )
+}
+
+dvanillabondprice <- function(hazardrate, collateral) {
+ R <- recovery(collateral)
+ cs <- couponSchedule(collateral$nextpaydate, collateral$maturity,
+ collateral$frequency, collateral$fixedorfloat,
+ collateral$grosscoupon*0.01, collateral$spread*0.01)
+ return( bondprice(hazardrate, cs, R) )
+}
+
+fithazardrate <- function(collateral){
+ R <- recovery(collateral)
+ cs <- couponSchedule(collateral$nextpaydate, collateral$maturity,
+ collateral$frequency, collateral$fixedorfloat,
+ collateral$grosscoupon*0.01, collateral$spread*0.01)
+ f <- function(lambda){
+ u <- bondprice(lambda, cs, R )
+ return( (u * 100-collateral$price)^2 )
+ }
+ return( optimize(f, c(0,1), tol=1e-6)$minimum )
+}
+
+stackcurve <- function(SC, line.item, global.params, startdate){
+ if(line.item$nextpaydate> line.item$maturity){
+ SC@curve@hazardrates <- 0
+ SC@curve@prepayrates <- 0
+ SC@curve@dates <- line.item$maturity
+ return( SC )
+ }
+ newdates <- seq(line.item$nextpaydate, line.item$maturity, by="3 months")
+ if(newdates[length(newdates)]<line.item$maturity){
+ newdates <- c(newdates, line.item$maturity)
+ }
+ newdates <- c(startdate, newdates[newdates>startdate])
+ if(is.na(line.item$assettype) || line.item$assettype=="Loan"){
+ hvec <- global.params$shape(yearFrac(today(), newdates[-1])) * global.params$defaultloanhazardrate
+ kvec <- global.params$alpha * exp(-global.params$beta * hvec)
+ }else if(line.item$assettype=="Bond" || line.item$assettype=="Credit Default Swap"
+ || (!is.na(line.item$iscdo) && line.item$iscdo)){
+ hvec <- global.params$shape(yearFrac(today(), newdates[-1])) * global.params$defaultbondhazardrate
+ kvec <- rep(0, length(hvec))
+ }
+ SC@curve@hazardrates <- c(SC@curve@hazardrates, hvec)
+ SC@curve@prepayrates <- c(SC@curve@prepayrates, kvec)
+ SC@curve@dates <- c(SC@curve@dates, newdates[-1])
+ return(SC)
+}
+
+buildSC.matured <- function(SC, line.item, reinvdate, dealmaturity, global.params, startdate){
+ if(!is.na(reinvdate) && startdate<=reinvdate){ #reinvest
+ line.item$maturity <- min(dealmaturity, startdate + global.params$rollingmaturity)
+ SC <- stackcurve(SC, line.item, global.params, startdate)
+ }else{ #no reinvestment
+ SC@curve@dates <- startdate
+ SC@curve@hazardrates <- 0
+ SC@curve@prepayrates <- 0
+ }
+ return( SC )
+}
+
+buildSC <- function(line.item, reinvdate, dealmaturity, global.params, startdate){
+ if(!is.na(line.item$iscdo) && line.item$iscdo && is.na(line.item$price)){
+ ##we have prices for some cdos e.g. 210795PS3
+ if(is.na(line.item$orig) || line.item$orig_moody == "NA" || length(line.item$orig_moody)==0){
+ line.item$orig_moody <- "NR"
+ }
+ line.item$price <- as.numeric(global.params$cdoprices[gsub("\\d", "", line.item$orig_moody)])
+ }
+ ##build survival curve
+ SC <- new("creditcurve", recovery=recovery(line.item), startdate=startdate,
+ issuer=line.item$issuername)
+ SC@curve <- new("defaultprepaycurve", dates=as.Date(character(0)))
+ ## defaulted asset
+ if(!is.na(line.item$defaultedflag) && line.item$defaultedflag){
+ if(is.na(line.item$price)){
+ line.item$currentbalance <- line.item$currentbalance * recovery(line.item)
+ }else{
+ line.item$currentbalance <- line.item$currentbalance * line.item$price/100
+ }
+ line.item$price <- 100
+ SC@recovery <- 0.7
+ SC@startdate <- startdate + global.params$defaultedlag
+ if(global.params$reinvflag){#we reinvest recovery assets
+ line.item$maturity <- min(dealmaturity, SC@startdate + global.params$rollingmaturity)
+ line.item$nextpaydate <- SC@startdate
+ ## automatic reinvest
+ SC<- stackcurve(SC, line.item, global.params, SC@startdate)
+ }else{
+ SC <- NULL
+ }
+
+ }else if(line.item$maturity <= startdate){#matured asset
+ SC <- buildSC.matured(SC, line.item, reinvdate, dealmaturity, global.params, startdate)
+ if(is.na(line.item$price))line.item$price <- 100
+ }else if(is.na(line.item$price)){ #missing price
+ SC <- stackcurve(SC, line.item, global.params, SC@startdate)
+ cs <- couponSchedule(line.item$nextpaydate, line.item$maturity,
+ line.item$frequency, line.item$fixedorfloat,
+ line.item$grosscoupon*0.01, line.item$spread*0.01, startdate)
+ line.item$price <- bondpv(cs, SC@curve, recovery(line.item), startdate) * 100
+ }else{ #normal case
+ if(!is.na(line.item$assettype) && line.item$assettype=="Bond"){ #no prepay rate
+ alpha <- 0
+ }else{
+ alpha <- global.params$alpha
+ }
+ try <- bondhazardrate.shaped(line.item, global.params$shape,
+ recovery(line.item), alpha, global.params$beta, startdate)
+ if(is.null(try)){
+ SC <- stackcurve(SC, line.item, global.params, SC@startdate)
+ }else{
+ SC@curve <- try
+ }
+ }
+ if(!is.na(reinvdate) && !is.null(SC) && creditcurve.maturity(SC) <= reinvdate){
+ ## if reinvdate is missing, assume no reinvestment
+ ## otherwise reinvest
+ newstartdate <- line.item$maturity
+ line.item$maturity <- min(dealmaturity, newstartdate + global.params$rollingmaturity)
+ SC <- stackcurve(SC, line.item, global.params, newstartdate)
+ }
+ if(is.na(line.item$price)){
+ ## TODO
+ }
+ beta <- if(!is.na(line.item$iscdo) && line.item$iscdo) 1 else global.params$defaultcorr
+ return( list(SC=SC, notional=line.item$currentbalance, price = line.item$price, beta = beta) )
+}
+
+buildSC.portfolio <- function(dealname, dealdata, cusipdata, global.params, startdate = Sys.Date()) {
+ collatdata <- data.table(getcollateral(dealname, startdate))
+ setkey(collatdata, "cusip")
+ ## replace the cdo fields by bloomberg data
+ collatdata[cusipdata,
+ `:=`(maturity=i.maturity, fixedorfloat=i.fixedorfloat,
+ spread=i.spread, grosscoupon=i.grosscoupon, orig_moody=i.orig_moody, iscdo=TRUE),
+ allow.cartesian=TRUE]
+
+ portfolio <- foreach(line.item = iter(collatdata, by='row')) %:% {
+ when( !is.na(line.item$maturity) && line.item$currentbalance > 1
+ && !is.na(line.item$assettype) && line.item$assettype!="Equity") } %dopar% {
+ buildSC(line.item, dealdata$reinv_end_date, dealdata$maturity, global.params, startdate)
+ }
+ ## non-parallel version for debugging
+ ## portfolio <- c()
+ ## for(i in 1:nrow(collatdata)){
+ ## line.item <- collatdata[i,]
+ ## if(is.na(line.item$maturity) || line.item$currentbalance <= 1){
+ ## next
+ ## }
+ ## portfolio <- c(portfolio, buildSC(line.item, dealdata$reinv_end_date, dealdata$maturity, global.params, startdate))
+ ## }
+ missingpricenotional <- sum(collatdata[is.na(price) & maturity>startdate &
+ (is.na(iscdo)|!iscdo), currentbalance])
+ cdonotional <- sum(collatdata[!is.na(iscdo)&(iscdo==TRUE),currentbalance])
+ collatbalance <- sum(collatdata[,currentbalance])
+ return( list(notional=vapply(portfolio, function(x)x$notional, numeric(1)),
+ beta = vapply(portfolio, function(x)x$beta, numeric(1)),
+ price = vapply(portfolio, function(x)x$price, numeric(1)),
+ SC = lapply(portfolio, function(x)x$SC),
+ stale = missingpricenotional/collatbalance,
+ cdopercentage = cdonotional/collatbalance,
+ collatbalance = collatbalance
+ ) )
+}
+
+cdrfromscenarios <- function(scenarios, dates, tradedate){
+ ## compute the forward cdr rates to pass to intex
+ ## so that we match the default curves in scenarios
+ cdr <- matrix(0, nrow(scenarios), ncol(scenarios))
+ for(i in 1:nrow(scenarios)){
+ cdr[i,] <- 100*(1-exp(diff(c(0, log(1-scenarios[i,])))))/diff(c(0, yearFrac(tradedate, dates)))
+ }
+ return( cdr )
+}
+
+recoveryfromscenarios <- function(scenariosd, scenariosr){
+ ## compute the forward recovery rate based on the term
+ ## structure of recovery scenarios
+ ## we run into trouble for very stressed scenarios
+ ## this code should cap the scenarios at 0 if this happens
+ intexrecov <- matrix(0, n.scenarios, ncol(scenariosr))
+ scenariosr <- scenariosr
+ for(i in 1:n.scenarios){
+ current <- 1
+ intexrecov[i,1] <- scenariosr[i,1]
+ for(t in 2:ncol(scenariosr)){
+ w <- scenariosd[i,current]/scenariosd[i,t]
+ ## if(scenariosr[i,t]-w*scenariosr[i,current]>=0){
+ ## intexrecov[i,t] <- (scenariosr[i,t]-w*scenariosr[i,current])/(1-w)
+ ## current <- current+1
+ ## }else{
+ ## intexrecov[i,t] <- 0
+ ## }
+ intexrecov[i,t] <- (scenariosr[i,t]-w*scenariosr[i,current])/(1-w)
+ current <- current + 1
+ }
+ }
+ return(intexrecov)
+}
+
+recoveryfromscenarios.fast <- function(scenariosr, scenariosd){
+ r <- rbind(scenariosr[,1]/scenariosd[,1],
+ apply(scenariosr, 1, diff)/apply(scenariosd, 1, diff))
+ return( t(r) )
+}
+
+severityfromscenarios <- function(scenariosd, scenariosr){
+ ## compute the forward recovery rate based on the term
+ ## structure of recovery scenarios
+ ## we run into trouble for very stressed scenarios
+ ## this code should cap the scenarios at 0 if this happens
+ intexseverity <- matrix(0, n.scenarios, ncol(scenariosr))
+ for(i in 1:n.scenarios){
+ current <- 1
+ intexseverity[i,1] <- 1-scenariosr[i,1]
+ for(t in 2:ncol(scenariosr)){
+ w <- scenariosd[i,current]/scenariosd[i,t]
+ intexseverity[i,t] <- 1 - (scenariosr[i,t]-w*scenariosr[i,current])/(1-w)
+ current <- current+1
+ }
+ }
+ return(intexseverity)
+}
+
+get.reinvassets <- function(dealname, tradedate){
+ r <- list()
+ sqlstr <- "select * from et_historicaldealinfo($1, $2) where ReinvFlag Is true"
+ data <- dbGetQuery(etdb, sqlstr, params=list(dealname, tradedate))
+ if(nrow(data)>0){
+ for(i in 1:nrow(data)){
+ r[[data$issuername[i]]] <- list(coupontype=data$fixedorfloat[i], liborfloor=data$liborfloor[i])
+ }
+ }
+ return( r )
+}
+
+getpayday <- function(dealdata, tradedate){
+ ## try to compute the previous pay date of a deal
+ ## it relies on thwo things to be accurate: the pay_day
+ ## as well as the first_pay_date (that's how we get the month)
+ m <- as.numeric(format(dealdata$first_pay_date, "%m"))
+ m <- m %%3+9
+ y <- as.numeric(format(tradedate, "%Y"))
+ y <- y - 1
+ payday <- as.Date(sprintf("%s-%s-%s", y, m, dealdata$pay_day))
+ i <- 1
+ cal <- Calendar$new("UnitedStates")
+ nextdate <- cal$advance(dates=payday, period = "3m", bdc = "Unadjusted")
+ while(nextdate < tradedate){
+ payday <- nextdate
+ i <- i+1
+ nextdate <- cal$advance(payday, 3*i, 2, bdc = "Unadjusted")
+ }
+ return(payday)
+}
+
+getdealschedule <- function(dealdata, freq = c("Monthly", "Quarterly"), tradedate=Sys.Date(),
+ bdc = c("Unadjusted", "Following", "ModifiedFollowing")) {
+ payday <- getpayday(dealdata, tradedate)
+ freq <- match.arg(freq)
+ bdc <- match.arg(bdc)
+ params <- list(effectiveDate = getpayday(dealdata, tradedate),
+ maturityDate = dealdata$maturity,
+ period = freq,
+ businessDayConvention = bdc,
+ terminationDateConvention = "Unadjusted",
+ dateGeneration = "Forward")
+ return( Schedule(params) )
+}
+
+intexportfolio.forwardprice <- function(cdrmonthly, recoverymonthly, startdate, maturity,
+ coupontype, margin, liborfloor){
+ if(missing(liborfloor)||is.na(liborfloor)){
+ currentcoupon <- margin
+ }else{
+ currentcoupon <- margin + liborfloor
+ }
+ forwardcs <- data.table(couponSchedule(nextpaydate=startdate+45, maturity,
+ frequency="Q", coupontype, margin,
+ currentcoupon, tradedate=startdate), key="dates")
+ notionals <- cdrmonthly[date>=startdate, lapply(.SD,function(x)cumprod(1-x/100*1/12)),
+ .SDcols=paste0("V",1:100)]
+ recovery <- as.matrix(recoverymonthly[date>=startdate, .SD, .SDcols=paste0("V",1:100)])*
+ -apply(rbind(1,as.matrix(notionals)), 2, diff)
+ if(nrow(recovery)==1){
+ recovery <- recovery*last(forwardcs[,df])
+ }else{
+ recovery <- data.table(dates=cdrmonthly[date>=startdate,date],apply(recovery, 2, cumsum),key="dates")
+ recovery <- recovery[forwardcs, roll=TRUE]
+ df <- recovery[,df]
+ recovery <- t(df)%*%as.matrix(recovery[,lapply(.SD,function(x)diff(c(0,x))),.SDcols=paste0("V",1:100)])
+ }
+ notionals <- data.table(dates=cdrmonthly[date>=startdate,date], notionals, key="dates")
+ outstanding <- notionals[forwardcs, roll=TRUE]
+ mat.outstanding <- as.matrix(outstanding[,.SD,.SDcols=paste0("V",1:100)])
+ po <- mat.outstanding[nrow(mat.outstanding),]*last(outstanding)[,df]
+ io <- outstanding[, df*coupons]%*%mat.outstanding
+ mean(recovery+po+io)
+}
+
+compute.reinvprices <- function(dealname, cdrmonthly, recoverymonthly, params, rollingmaturity, tradedate){
+ reinvassets <- get.reinvassets(dealname, tradedate)
+ reinvprices <- list()
+ if(length(reinvassets)>0){
+ maturity <- cdrmonthly$date[nrow(cdrmonthly)]
+ for(assetname in names(reinvassets)){
+ asset <- reinvassets[[assetname]]
+ coupon <- if(asset$coupontype=="FLOAT") params$reinvfloat else params$reinvfixed
+ reinvprices[[assetname]] <- foreach(date = iter(cdrmonthly$date), .combine=c) %dopar% {
+ 100 * intexportfolio.forwardprice(cdrmonthly.dt, recoverymonthly.dt, date,
+ min(date+rollingmaturity, maturity),
+ asset$coupontype, coupon, asset$liborfloor/100)
+ }
+ }
+ }
+ return(reinvprices)
+}
diff --git a/R/latestprices.R b/R/latestprices.R
deleted file mode 100644
index 6394e695..00000000
--- a/R/latestprices.R
+++ /dev/null
@@ -1,44 +0,0 @@
-library(RODBC)
-conn <- odbcConnect("MLP-PROD")
-deltas.hist <- sqlQuery(conn,"select * from ET_CusipDeltasHist where IndexType='LCDX' and ReinvSpreadScenario='MID'")
-deltas.live <- sqlQuery(conn,"select * from ET_CusipDeltas where IndexType='LCDX' and ReinvSpreadScenario='MID'")
-deltas <- rbind(deltas.live,deltas.hist)
-deltas$PriceDate <- as.Date(deltas$PriceDate,format="%m/%d/%Y")
-deltas <- deltas[order(deltas$PriceDate,decreasing=T),]
-cusiplist <- unique(deltas$Cusip)
-deltas <- deltas[match(cusiplist,deltas$Cusip),]
-
-walduration <- sqlQuery(conn,"select * from ET_CusipSumProduct_WALDuration")
-prices_lcdx <- sqlQuery(conn,"select * from ET_CusipSumProduct_AWPrice where IndexType='LCDX'")
-prices_t1 <- sqlQuery(conn,"select * from ET_CusipSumProduct_AWPrice where IndexType='T1'")
-prices_t2 <- sqlQuery(conn,"select * from ET_CusipSumProduct_AWPrice where IndexType='T2'")
-prices_hy <- sqlQuery(conn,"select * from ET_CusipSumProduct_AWPrice where IndexType='HY' and IndexSeries='10' and IndexTenor='7y'")
-odbcClose(conn)
-selectlatest <- function(data){
- data$PriceDate <- as.Date(data$PriceDate,format="%m/%d/%Y")
- data <- data[order(data$PriceDate,data$UpdateDate,decreasing=T),]
- data_mid <- data[data$ReinvSpreadScenario=="MID",]
- data_mid <- data_mid[match(unique(data_mid$Cusip),data_mid$Cusip,),]
- data_high <- data[data$ReinvSpreadScenario=="HIGH",]
- data_high <- data_high[match(unique(data_high$Cusip),data_high$Cusip,),]
- data_low <- data[data$ReinvSpreadScenario=="LOW",]
- data_low <- data_low[match(unique(data_low$Cusip),data_low$Cusip,),]
- data_noreinv <- data[data$ReinvSpreadScenario=="NOREINV",]
- data_noreinv <- data_noreinv[match(unique(data_noreinv$Cusip),data_noreinv$Cusip,),]
- data <- rbind(data_mid,data_noreinv,data_low,data_high)
- data[order(data$Cusip),]
-}
-
-prices_t1 <- selectlatest(prices_t1)
-prices_t2 <- selectlatest(prices_t2)
-prices_hy <- selectlatest(prices_hy)
-prices_lcdx <- selectlatest(prices_lcdx)
-walduration <- selectlatest(walduration)
-prices_lcdx <- prices_lcdx[prices_lcdx$Cusip%in%prices_t1$Cusip,]
-prices_hy <- prices_hy[prices_hy$Cusip%in%prices_t1$Cusip,]
-deltas <- deltas[deltas$Cusip%in%prices_t1$Cusip,]
-walduration <- walduration[walduration$Cusip%in%prices_t1$Cusip,]
-deltas <- deltas[pmatch(prices_t1$Cusip,deltas$Cusip,dup=T),]
-data <- cbind(prices_lcdx[,c("Cusip","ReinvSpreadScenario","AWJuniorWgts_Price","AWSeniorWgts_Price")],prices_t1[,"AWJuniorWgts_Price"],prices_t2[,"AWJuniorWgts_Price"],prices_hy[,c("AWJuniorWgts_Price","AWSeniorWgts_Price")],walduration[,c("AW_WAL","AW_Duration","PriceDate")],deltas[,c("FullTranche","Tranche1","Tranche2","Tranche3","Tranche4")])
-colnames(data)<-c("Cusip","ReinvScen","LCDX12 5y Jr","LCDX12 5y Sr","T1","T2","HY10 7y Jr","HY10 7y Sr","Wal","Duration","Price Date","LCDX index","LCDX 0-8","LCDX 8-15","LCDX 15-30","LCDX 30-100")
-write.table(data,file="W:/CorpCDOs/latestprices_Prod.txt",row.names=F,col.names=T,sep=",")
diff --git a/R/loadcashflows.R b/R/loadcashflows.R
deleted file mode 100644
index 26ea12f1..00000000
--- a/R/loadcashflows.R
+++ /dev/null
@@ -1,38 +0,0 @@
-cusips <- c("000743AA2","00083VAE1","009368AD3","00936BAA2","00936XAA4","03761KAG3","03761LAE6","039549AC4","30605LAA7","82626RAA0","92849RAA0")
-cfdir <- "T:/Analytics/Runs/20100608"
-test <- read.table(paste(cusip[1],"cashflow.txt",sep="_"),header=T)
-index_scen <- function(data,i){
- return( which(data$"Scenario"==paste("SCENARIO",i,sep="")) )
-}
-
-as.Date(as.character(test[index_scen(test,1),]$Date),format="%Y%m%d")
-
-library(zoo)
-today <- function(){
- as.Date(Sys.time())
-}
-df <- function(spreadcurve){
- df <- exp(-cumsum(as.numeric(diff(c(spreadcurve$curvedate,time(spreadcurve$curve)))/365)*spreadcurve$curve))
- list(curvedate=spreadcurve$curvedate,curve=zoo(df,time(spreadcurve$curve)))
-}
-test <- zoo(c(100,200,300),c(today+365*1:3))
-yc.usd <-list(curvedate=today(),curve=zoo(c(100,200,300),today()+365*1:3))
-
-addcurves <- function(curveA,curveB){
- if(curveA$curvedate==curveB$curvedate){
- curvemerged <- na.locf(na.locf(merge(curveA$curve,curveB$curve),na.rm=F,fromLast=T))
- return(list(curvedate=curveA$curvedate,curve=curvemerged[,1]+curvemerged[,2]))
- }else{
- return(0)
- }
-}
-multcurves <- function(curveA,curveB){
- if(curveA$curvedate==curveB$curvedate){
- curvemerged <- na.locf(na.locf(merge(curveA$curve,curveB$curve),na.rm=F,fromLast=T))
- return(list(curvedate=curveA$curvedate,curve=curvemerged[,1]*curvemerged[,2]))
- }else{
- return(0)
- }
-}
-spreadfrombondprice <- function(price,spread,maturity,yieldcurve){
-}
diff --git a/R/parse_intex.R b/R/parse_intex.R
deleted file mode 100644
index b9c52e07..00000000
--- a/R/parse_intex.R
+++ /dev/null
@@ -1,18 +0,0 @@
-root = "//WDSENTINEL/share/CorpCDOs"
-source(file.path(root, "R", "intex_deals_functions.R"))
-source(file.path(root, "R", "etdb.R"))
-dealnames <- c("limes", "stonln1")
-cusips <- cusipsfromdealnames(dealnames)
-
-deals.universe <- dbGetQuery(dbCon, "select distinct dealname from clo_universe order by dealname asc")$dealname
-cusips.universe <- cusipsfromdealnames(deals.universe)
-n.scenarios <- 100
-offset <- 2
-r <- data.frame()
-for(cusip in cusips){
- data <- read.table(paste(cusip, "-PY.txt", sep=""), sep="\t", header=T, nrow=3)
- price <- sum(as.numeric(sub("\\((.*)\\)", "-\\1", data[1,1:n.scenarios+offset])), na.rm=T)/n.scenarios
- wal <- sum(as.numeric(sub("\\((.*)\\)", "-\\1", data[2,1:n.scenarios+offset])), na.rm=T)/n.scenarios
- duration <- sum(as.numeric(sub("\\((.*)\\)", "-\\1", data[3,1:n.scenarios+offset])), na.rm=T)/n.scenarios
- r <- rbind(r, data.frame(cusip, price, wal, duration))
-}
diff --git a/R/tranches_RV_BC.R b/R/tranches_RV_BC.R
index b0ecae9e..29a922f7 100644
--- a/R/tranches_RV_BC.R
+++ b/R/tranches_RV_BC.R
@@ -1,109 +1,109 @@
-if(.Platform$OS.type == "unix"){
- root.dir <- "/home/share/CorpCDOs"
-}else{
- root.dir <- "//WDSENTINEL/share/CorpCDOs"
-}
-library(logging)
-basicConfig()
-removeHandler('basic.stdout')
-addHandler(writeToFile, file=file.path(root.dir, "logs", "tranches_RV_BC.log"))
-library(optparse)
-option_list <- list(
- make_option(c("-u", "--update"), action="store_true", default=FALSE,
- help="Update from the last run date [default %default]"),
- make_option(c("-c", "--config"), metavar="config_file",
- help="Runs the list of indices provided in CONFIG_FILE"),
- make_option(c("-i1", "--index1"), help="Reference index name"),
- make_option(c("-i2", "--index2"), help="Mapped index name"),
- make_option(c("-t1", "--tenor1"), default="5yr",
- help="Tenor of index1 [default %default]"),
- make_option(c("-t2", "--tenor2"), default="5yr",
- help="Tenor of index2 [default %default]"),
- make_option("--until", default=Sys.Date()-1, type="character",
- help="last day to run [default %default]"))
-
-args <- parse_args(OptionParser(option_list=option_list,
- description=
- "This script prices index2 using the skew from index1."))
-if(is.null(args$config)){
- if(is.null(args$index1) || is.null(args$index2)){
- stop("Please provide both index1 and index2")
- }
- runs <- list(mappings=list(c(args$index1, args$tenor1, args$index2, args$tenor2)))
-}else{
- library(yaml)
- runs <- yaml.load_file(file.path(root.dir, "code", "etc", args$config))
-}
-
-source(file.path(root.dir, "code", "R", "optimization.R"))
-source(file.path(root.dir, "code", "R", "calibration.R"), chdir=TRUE)
-source(file.path(root.dir, "code", "R", "serenitasdb.R"))
-source(file.path(root.dir, "code", "R", "creditIndex.R"))
-source(file.path(root.dir, "code", "R", "tranche_functions.R"))
-
-for(r in runs$mappings){
- index.name1 <- r[1]
- tenor1 <- r[2]
- index.name2 <- r[3]
- tenor2 <- r[4]
- filename <- file.path(root.dir,"Tranche_data","Runs",
- paste0(paste(index.name2, tenor2, "using", index.name1, tenor1),".csv"))
- if(!file.exists(filename)){
- args$update <- FALSE
- }
- if(args$update){
- runfile <- read.csv(filename)
- begin.date <- as.Date(runfile[nrow(runfile), 1])+1
- }else{
- begin.date <- switch(index.name1,
- hy23 = as.Date("2014-10-16"),
- hy21 = as.Date("2013-10-04"),
- hy19 = as.Date("2013-10-04"),
- ig21 = as.Date("2013-09-26"),
- ig23 = as.Date("2014-10-14"),
- ig25 = as.Date("2015-09-22"),
- ig27 = as.Date("2015-09-27"),
- hy25 = as.Date("2015-10-01"),
- hy27 = as.Date("2016-10-04"),
- xo24 = as.Date("2015-09-28"),
- eu24 = as.Date("2015-09-23"))
- }
- if(begin.date > as.Date(args$until)){
- next
- }
- alldates <- seq(begin.date, as.Date(as.character(args$until)), by="1 day")
- cal <- Calendar$new("UnitedStates/GovernmentBond")
- bus.dates <- alldates[cal$isBusinessDay(alldates)]
- addheaders <- TRUE
- for(j in seq_along(bus.dates)){
- tradedate <- bus.dates[j]
- index1 <- load.index(index.name1, tenor1, tradedate)
- index2 <- load.index(index.name2, tenor2, tradedate)
- if(any(c(is.null(index1), is.null(index2)))){
- loginfo(paste("skipping pair", index.name1, tenor1, index.name2, tenor2,
- "for date", as.character(tradedate)))
- next
- }
- accrued2 <- cdsAccrued(tradedate, index2$tranches$running)
- mappedpv <- list()
- for(method in c("ATM", "TLP", "PM")){
- index2$rho <- adjust.skew(index1, index2, method)
- if(tolower(substr(index2$name, 1, 2)) %in% c("ig", "xo", "eu")){
- mappedpv[[method]] <- BCtranche.pv(index2, protection=TRUE)$bp + accrued2
- }else{
- mappedpv[[method]] <- BCtranche.pv(index2)$bp - accrued2
- }
- }
- row <- c(as.character(tradedate), index2$tranches$upfront, unlist(mappedpv)*100)
- if(addheaders && !args$update){
- headers <- c("date", paste(index2$name, row.names(index2$tranches), "Quotes"),
- paste(index2$name, row.names(index2$tranches), "ATM PV"),
- paste(index2$name, row.names(index2$tranches), "TLP PV"),
- paste(index2$name, row.names(index2$tranches), "PM PV"))
- cat(paste(headers, collapse=","), "\n", file=filename)
- }
- addheaders <- FALSE
- cat(paste(row, collapse=","), sep="\n", file=filename, append=TRUE)
- }
-
-}
+if(.Platform$OS.type == "unix"){
+ root.dir <- "/home/share/CorpCDOs"
+}else{
+ root.dir <- "//WDSENTINEL/share/CorpCDOs"
+}
+library(logging)
+basicConfig()
+removeHandler('basic.stdout')
+addHandler(writeToFile, file=file.path(root.dir, "logs", "tranches_RV_BC.log"))
+library(optparse)
+option_list <- list(
+ make_option(c("-u", "--update"), action="store_true", default=FALSE,
+ help="Update from the last run date [default %default]"),
+ make_option(c("-c", "--config"), metavar="config_file",
+ help="Runs the list of indices provided in CONFIG_FILE"),
+ make_option(c("-i1", "--index1"), help="Reference index name"),
+ make_option(c("-i2", "--index2"), help="Mapped index name"),
+ make_option(c("-t1", "--tenor1"), default="5yr",
+ help="Tenor of index1 [default %default]"),
+ make_option(c("-t2", "--tenor2"), default="5yr",
+ help="Tenor of index2 [default %default]"),
+ make_option("--until", default=Sys.Date()-1, type="character",
+ help="last day to run [default %default]"))
+
+args <- parse_args(OptionParser(option_list=option_list,
+ description=
+ "This script prices index2 using the skew from index1."))
+if(is.null(args$config)){
+ if(is.null(args$index1) || is.null(args$index2)){
+ stop("Please provide both index1 and index2")
+ }
+ runs <- list(mappings=list(c(args$index1, args$tenor1, args$index2, args$tenor2)))
+}else{
+ library(yaml)
+ runs <- yaml.load_file(file.path(root.dir, "code", "etc", args$config))
+}
+
+source(file.path(root.dir, "code", "R", "optimization.R"))
+source(file.path(root.dir, "code", "R", "calibration.R"), chdir=TRUE)
+source(file.path(root.dir, "code", "R", "serenitasdb.R"))
+source(file.path(root.dir, "code", "R", "creditIndex.R"))
+source(file.path(root.dir, "code", "R", "tranche_functions.R"))
+
+for(r in runs$mappings){
+ index.name1 <- r[1]
+ tenor1 <- r[2]
+ index.name2 <- r[3]
+ tenor2 <- r[4]
+ filename <- file.path(root.dir,"Tranche_data","Runs",
+ paste0(paste(index.name2, tenor2, "using", index.name1, tenor1),".csv"))
+ if(!file.exists(filename)){
+ args$update <- FALSE
+ }
+ if(args$update){
+ runfile <- read.csv(filename)
+ begin.date <- as.Date(runfile[nrow(runfile), 1])+1
+ }else{
+ begin.date <- switch(index.name1,
+ hy23 = as.Date("2014-10-16"),
+ hy21 = as.Date("2013-10-04"),
+ hy19 = as.Date("2013-10-04"),
+ ig21 = as.Date("2013-09-26"),
+ ig23 = as.Date("2014-10-14"),
+ ig25 = as.Date("2015-09-22"),
+ ig27 = as.Date("2015-09-27"),
+ hy25 = as.Date("2015-10-01"),
+ hy27 = as.Date("2016-10-04"),
+ xo24 = as.Date("2015-09-28"),
+ eu24 = as.Date("2015-09-23"))
+ }
+ if(begin.date > as.Date(args$until)){
+ next
+ }
+ alldates <- seq(begin.date, as.Date(as.character(args$until)), by="1 day")
+ cal <- Calendar$new("UnitedStates/GovernmentBond")
+ bus.dates <- alldates[cal$isBusinessDay(alldates)]
+ addheaders <- TRUE
+ for(j in seq_along(bus.dates)){
+ tradedate <- bus.dates[j]
+ index1 <- load.index(index.name1, tenor1, tradedate)
+ index2 <- load.index(index.name2, tenor2, tradedate)
+ if(any(c(is.null(index1), is.null(index2)))){
+ loginfo(paste("skipping pair", index.name1, tenor1, index.name2, tenor2,
+ "for date", as.character(tradedate)))
+ next
+ }
+ accrued2 <- cdsAccrued(tradedate, index2$tranches$running)
+ mappedpv <- list()
+ for(method in c("ATM", "TLP", "PM")){
+ index2$rho <- adjust.skew(index1, index2, method)
+ if(tolower(substr(index2$name, 1, 2)) %in% c("ig", "xo", "eu")){
+ mappedpv[[method]] <- BCtranche.pv(index2, protection=TRUE)$bp + accrued2
+ }else{
+ mappedpv[[method]] <- BCtranche.pv(index2)$bp - accrued2
+ }
+ }
+ row <- c(as.character(tradedate), index2$tranches$upfront, unlist(mappedpv)*100)
+ if(addheaders && !args$update){
+ headers <- c("date", paste(index2$name, row.names(index2$tranches), "Quotes"),
+ paste(index2$name, row.names(index2$tranches), "ATM PV"),
+ paste(index2$name, row.names(index2$tranches), "TLP PV"),
+ paste(index2$name, row.names(index2$tranches), "PM PV"))
+ cat(paste(headers, collapse=","), "\n", file=filename)
+ }
+ addheaders <- FALSE
+ cat(paste(row, collapse=","), sep="\n", file=filename, append=TRUE)
+ }
+
+}
diff --git a/R/yieldcurve.R b/R/yieldcurve.R
index 75a84b30..fd6c5744 100644
--- a/R/yieldcurve.R
+++ b/R/yieldcurve.R
@@ -1,98 +1,98 @@
-require(RQuantLib)
-root.dir <- if(.Platform$OS.type == "unix"){
- "/home/share/CorpCDOs"
-}else{
- "//WDSENTINEL/share/CorpCDOs"
-}
-
-source(file.path(root.dir, "code", "R", "db.R"))
-
-getMarkitIRData <- function(date=Sys.Date(), currency=c("USD", "EUR")) {
- ## returns Markit rates from serenitasdb
- currency <- match.arg(currency)
- sqlstr <- sprintf("SELECT * FROM %s_rates WHERE effective_date = $1", currency)
- serenitasdb <- dbConn("serenitasdb")
- return( dbGetQuery(serenitasdb, sqlstr, params = list(date)) )
-}
-
-thirdwed <- function(x) {
- d <- x - as.POSIXlt(x)$mday + 1
- n <- (3-as.POSIXlt(d)$wday) %% 7 + 1
- d + 14 + n - 1
-}
-
-nextthirdwed <- function(x) {
- y <- thirdwed(x)
- thirdwed(y + 30 * (y < x))
-}
-
-buildMarkitYC <- function(MarkitData, currency=c("USD", "EUR"), futurequotes){
- currency <- match.arg(currency)
- deposits <- list()
- futures <- list()
- swaps <- list()
- if(missing(futurequotes)){
- for(k in names(MarkitData[2:7])) {
- v <- MarkitData[[k]]
- if(is.na(v)) {
- next
- }
- deposits[[paste0("d", tolower(k))]] <- v
- }
- }else{
- for(i in seq_along(futurequotes)){
- futures[[paste0("fut",i)]] <- futurequotes[i]
- }
- ## get last imm date
- lastimmdate <- nextthirdwed(advance(dates=tradeDate, n=21, timeUnit=2, bdc=4))
- lastfuturematurity <- advance(dates=lastimmdate, n=3, timeUnit=2, bdc=4)
- ## find out the 2 year swap rate maturity
- s2ymaturity <- advance(calendar="UnitedKingdom", dates=settleDate, 2, 3)
- if(s2ymaturity == lastfuturematurity){
- futures[["fut8"]] <- NULL
- }
- }
- for(k in names(MarkitData[8:length(MarkitData)])) {
- v <- MarkitData[[k]]
- if(is.na(v)) {
- next
- }
- swaps[[paste0("s", tolower(k))]] <- v
- }
- tsQuotes <- c(deposits, futures, swaps)
- return( tsQuotes )
-}
-
-exportYC <- function(tradedate=Sys.Date(), currency=c("USD", "EUR"), useFutures=FALSE){
- ## export the Yield Curve into the environment
- currency <- match.arg(currency)
- if(useFutures){
- futurefile <- file.path(data.dir, "Yield Curves",
- sprintf("futures-%s.csv", tradedate))
- if(file.exists(futurefile)){
- futurequotes <- read.csv(futurefile, header=F)
- }
- }
- MarkitData <- getMarkitIRData(tradedate, currency)
- setCalendarContext(calendar="WeekendsOnly", fixingDays=2,
- settleDate=tradedate)
- settings <- Settings$new()
- settings$EvaluationDate <- tradedate
- legparams <- switch(currency,
- USD = list(fixFreq="Semiannual",
- floatFreq="Quarterly",
- dayCounter="Thirty360"),
- EUR = list(fixFreq="Annual",
- floatFreq="Semiannual",
- dayCounter="Thirty360"))
- cal <- Calendar$new("WeekendsOnly")
- dc <- DayCounter$new("Actual365Fixed")
-
- if(exists("futurequotes")){
- tsQuotes <- buildMarkitYC(MarkitData, currency, futurequotes[,2])
- }else{
- tsQuotes <- buildMarkitYC(MarkitData, currency)
- }
- YC <<- YieldTermStructure$new("discount", "loglinear", 0L, cal,
- dc, tsQuotes, legparams)
-}
+require(RQuantLib)
+root.dir <- if(.Platform$OS.type == "unix"){
+ "/home/share/CorpCDOs"
+}else{
+ "//WDSENTINEL/share/CorpCDOs"
+}
+
+source(file.path(root.dir, "code", "R", "db.R"))
+
+getMarkitIRData <- function(date=Sys.Date(), currency=c("USD", "EUR")) {
+ ## returns Markit rates from serenitasdb
+ currency <- match.arg(currency)
+ sqlstr <- sprintf("SELECT * FROM %s_rates WHERE effective_date = $1", currency)
+ serenitasdb <- dbConn("serenitasdb")
+ return( dbGetQuery(serenitasdb, sqlstr, params = list(date)) )
+}
+
+thirdwed <- function(x) {
+ d <- x - as.POSIXlt(x)$mday + 1
+ n <- (3-as.POSIXlt(d)$wday) %% 7 + 1
+ d + 14 + n - 1
+}
+
+nextthirdwed <- function(x) {
+ y <- thirdwed(x)
+ thirdwed(y + 30 * (y < x))
+}
+
+buildMarkitYC <- function(MarkitData, currency=c("USD", "EUR"), futurequotes){
+ currency <- match.arg(currency)
+ deposits <- list()
+ futures <- list()
+ swaps <- list()
+ if(missing(futurequotes)){
+ for(k in names(MarkitData[2:7])) {
+ v <- MarkitData[[k]]
+ if(is.na(v)) {
+ next
+ }
+ deposits[[paste0("d", tolower(k))]] <- v
+ }
+ }else{
+ for(i in seq_along(futurequotes)){
+ futures[[paste0("fut",i)]] <- futurequotes[i]
+ }
+ ## get last imm date
+ lastimmdate <- nextthirdwed(advance(dates=tradeDate, n=21, timeUnit=2, bdc=4))
+ lastfuturematurity <- advance(dates=lastimmdate, n=3, timeUnit=2, bdc=4)
+ ## find out the 2 year swap rate maturity
+ s2ymaturity <- advance(calendar="UnitedKingdom", dates=settleDate, 2, 3)
+ if(s2ymaturity == lastfuturematurity){
+ futures[["fut8"]] <- NULL
+ }
+ }
+ for(k in names(MarkitData[8:length(MarkitData)])) {
+ v <- MarkitData[[k]]
+ if(is.na(v)) {
+ next
+ }
+ swaps[[paste0("s", tolower(k))]] <- v
+ }
+ tsQuotes <- c(deposits, futures, swaps)
+ return( tsQuotes )
+}
+
+exportYC <- function(tradedate=Sys.Date(), currency=c("USD", "EUR"), useFutures=FALSE){
+ ## export the Yield Curve into the environment
+ currency <- match.arg(currency)
+ if(useFutures){
+ futurefile <- file.path(data.dir, "Yield Curves",
+ sprintf("futures-%s.csv", tradedate))
+ if(file.exists(futurefile)){
+ futurequotes <- read.csv(futurefile, header=F)
+ }
+ }
+ MarkitData <- getMarkitIRData(tradedate, currency)
+ setCalendarContext(calendar="WeekendsOnly", fixingDays=2,
+ settleDate=tradedate)
+ settings <- Settings$new()
+ settings$EvaluationDate <- tradedate
+ legparams <- switch(currency,
+ USD = list(fixFreq="Semiannual",
+ floatFreq="Quarterly",
+ dayCounter="Thirty360"),
+ EUR = list(fixFreq="Annual",
+ floatFreq="Semiannual",
+ dayCounter="Thirty360"))
+ cal <- Calendar$new("WeekendsOnly")
+ dc <- DayCounter$new("Actual365Fixed")
+
+ if(exists("futurequotes")){
+ tsQuotes <- buildMarkitYC(MarkitData, currency, futurequotes[,2])
+ }else{
+ tsQuotes <- buildMarkitYC(MarkitData, currency)
+ }
+ YC <<- YieldTermStructure$new("discount", "loglinear", 0L, cal,
+ dc, tsQuotes, legparams)
+}