library(ggplot2) library(lubridate) library(doParallel) if(.Platform$OS.type == "unix"){ root.dir <- "/home/share/CorpCDOs" }else{ root.dir <- "//WDSENTINEL/share/CorpCDOs" } hostname <- system("hostname", intern=TRUE) if(hostname=="debian"){ registerDoParallel(4) }else{ registerDoParallel(8) } source(file.path(root.dir, "code", "R", "serenitasdb.R")) source(file.path(root.dir, "code", "R", "cds_functions_generic.R")) source(file.path(root.dir, "code", "R", "yieldcurve.R")) get.indexquotes <- function(index, series, tenors=c("3yr", "5yr", "7yr"), onlymissing=TRUE){ query1 <- sprintf(paste("select date, tenor, closeprice from index_quotes", "where index=%s and series=%s"), sqlQuote(index), series) if(onlymissing){ query1 <- paste(query1, "and duration is Null") } query1 <- paste(query1, "order by date, tenor") query2 <- sprintf("select unnest(%s::tenor[])",sqlQuote(sqlArray(tenors))) arraystring2 <- paste(lapply(tenors, function(s)sprintf("\"%s\" float", s)), collapse=",") stmt <- paste0("SELECT * from crosstab($1, $2) AS ct(date date, ", arraystring2, ")") df <- dbGetQuery(serenitasdb, stmt, params=list(query1, query2)) return( df ) } get.indexmaturity <- function(index, series){ sqlstr <- paste("select maturity, coupon/cast(10000 as float)as running, tenor", "from index_maturity where index=$1", "and series=$2 order by maturity") df <- dbGetQuery(serenitasdb, sqlstr, params=list(index, series)) df$maturity <- as.Date(df$maturity) return( df ) } fastduration <- function(sc, cs, tradedate, maturities){ r <- rep(NA, length(maturities)) if(is.null(sc)){ return( r ) } startdate <- tradedate+1 acc <- cdsAccrued(tradedate, 1) for(i in seq_along(maturities)){ if(startdate>maturities[i]){ r[i] <- NA }else{ r[i] <- couponleg(cs[cs$unadj.dates<=maturities[i],], sc, startdate, accruedondefault=TRUE)-acc } } return( r ) } fasttheta <- function(sc, cs, recov, tradedate, maturities, quotes, fixedrate=0.05){ r <- rep(NA, length(maturities)) if(is.null(sc)){ return(r) } startdate <- tradedate+1 acc <- cdsAccrued(tradedate, 1) newmaturities <- maturities+years(-1) for(i in seq_along(newmaturities)){ ## never extrapolate, and do not attempt to compute theta if within 1 year if(startdate>newmaturities[i] || is.na(quotes[i])){ next }else{ newcs <- cs[cs$unadj.dates<=newmaturities[i],] upfront <- defaultleg(newcs, sc, recov, startdate) - (couponleg(newcs, sc, startdate, accruedondefault=TRUE)-acc)*fixedrate r[i] <- quotes[i]-upfront+fixedrate } } return( r ) } index <- 'HY' tenors <- c("3yr", "5yr", "7yr") recov <- 0.3 sqlstr.duration <- paste("UPDATE index_quotes set duration=$1 where date=$2 and index=$3", "and series=$4 and tenor=$5") sqlstr.theta <- paste("UPDATE index_quotes set theta=$1 where date=$2 and index=$3", "and series=$4 and tenor=$5") for(series in c(16, 17, 18, 19, 20, 21, 22, 23, 24)){ indexquotes <- get.indexquotes(index, series) indexquotes <- indexquotes[!(is.na(indexquotes[,"3yr"]) & is.na(indexquotes[,"5yr"]) & is.na(indexquotes[,"7yr"])),] if(nrow(indexquotes)==0){ next } maturities <- get.indexmaturity(index, series) maturities <- maturities[maturities$tenor %in% tenors,] indexquotes <- indexquotes[indexquotes$date<=maturities$maturity[3],] durations <- matrix(0, nrow(indexquotes), length(tenors)) thetas <- matrix(0, nrow(indexquotes), length(tenors)) maturity <- maturities[nrow(maturities), "maturity"] durandthetas <- foreach(i = 1:nrow(indexquotes), .combine='rbind') %dopar% { tradedate <- indexquotes[i, "date"] exportYC(tradedate) cs <- couponSchedule(IMMDate(tradedate, noadj=TRUE), maturity,"Q", "FIXED", 1, 0, tradedate, IMMDate(tradedate, "prev")) quotes <- data.frame(upfront=(100-as.numeric(indexquotes[i,-1]))/100, maturities) sc <- cdshazardrate(quotes, recov, tradedate, cs) c(fastduration(sc, cs, tradedate, maturities$maturity), fasttheta(sc, cs, recov, tradedate, maturities$maturity, quotes$upfront)) } r <- c() for(i in 1:nrow(indexquotes)){ tradedate <- indexquotes[i, "date"] exportYC(tradedate) cs <- couponSchedule(IMMDate(tradedate, noadj=TRUE), maturity,"Q", "FIXED", 1, 0, tradedate, IMMDate(tradedate, "prev")) quotes <- data.frame(upfront=(100-as.numeric(indexquotes[i,-1]))/100, maturities) sc <- cdshazardrate(quotes, recov, tradedate, cs) r <- rbind(r, c(fastduration(sc, cs, tradedate, maturities$maturity), fasttheta(sc, cs, recov, tradedate, maturities$maturity, quotes$upfront))) } df.durations <- data.frame(date=indexquotes$date, r[,1:3, drop=F]) df.thetas <- data.frame(date=indexquotes$date, r[,4:6, drop=F]) colnames(df.durations) <- c("date", tenors) colnames(df.thetas) <- c("date", tenors) for(i in 1:nrow(df.durations)){ for(tenor in tenors){ if(!is.na(df.durations[i, tenor])){ r <- dbSendQuery(serenitasdb, sqlstr.duration, params = list(df.durations[i, tenor], df.durations[i,"date"], index, series, tenor)) if(dbHasCompleted(r)){ dbClearResult(r) } } if(!is.na(df.thetas[i,tenor])){ r <- dbSendQuery(serenitasdb, sqlstr.theta, params = list(df.thetas[i, tenor], df.thetas[i, "date"], index, series, tenor)) if(dbHasCompleted(r)){ dbClearResult(r) } } } } } ## ## nice plot, now I'm just showing off ## ggplot(df.durations, aes(x=date))+geom_line(aes(y=`3yr`, colour="3yr"))+ ## geom_line(aes(y=`5yr`, colour="5yr"))+ ## geom_line(aes(y=`7yr`, colour="7yr"))+ylab("duration")+labs(colour="tenor") ## ggsave(filename=paste0("HY", series, " durations.png")) ## ## plot thetas ## ggplot(df.thetas, aes(x=date))+geom_line(aes(y=`3yr`, colour="3yr"))+ ## geom_line(aes(y=`5yr`, colour="5yr"))+ ## geom_line(aes(y=`7yr`, colour="7yr"))+ylab("theta")+labs(colour="tenor") ## ggsave(filename=paste0("HY", series, " thetas.png"))