diff options
Diffstat (limited to 'R/thetas-durations.R')
| -rw-r--r-- | R/thetas-durations.R | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/R/thetas-durations.R b/R/thetas-durations.R new file mode 100644 index 00000000..02001187 --- /dev/null +++ b/R/thetas-durations.R @@ -0,0 +1,162 @@ +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){ + arraystring1 <- paste0("Array[''", paste(tenors, collapse = "'', ''"), "'']::tenor[]") + arraystring2 <- paste0('"', paste(tenors, collapse='" float, "'), '" float') + sqlstr <- paste("select * from crosstab('select date, tenor, closeprice from index_quotes", + "where index=''%s''and series=%s") + if(onlymissing){ + sqlstr <- paste(sqlstr, "and duration is Null") + } + sqlstr <- paste(sqlstr, "order by date, tenor', 'select unnest(%s)')", + "AS ct(date date, %s)") + stmt <- sprintf(sqlstr, index, series, arraystring1, arraystring2) + df <- dbGetQuery(serenitasdb, stmt) + return( df ) +} + +get.indexmaturity <- function(index, series){ + sqlstr <- paste("select maturity, coupon/cast(10000 as float)as running, tenor", + "from index_maturity where index='%s'", + "and series=%s order by maturity") + stmt <- sprintf(sqlstr, index, series) + df <- dbGetQuery(serenitasdb, stmt) + 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){ + 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)*0.05 + r[i] <- quotes[i]-upfront+0.05 + } + } + return( r ) +} + +convertNA <- function(x){ + if(is.na(x)){ + return( "Null" ) + }else{ + return( x ) + } +} + + +index <- 'HY' +tenors <- c("3yr", "5yr", "7yr") +recov <- 0.3 +sqlstr.duration <- paste("UPDATE index_quotes set duration=%s where date='%s' and index='%s'", + "and series=%s and tenor='%s'") +sqlstr.theta <- paste("UPDATE index_quotes set theta=%s where date='%s' and index='%s'", + "and series=%s and tenor='%s'") + +for(series in c(16, 17, 18, 19, 20, 21, 22, 23)){ + indexquotes <- get.indexquotes(index, series) + 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]) + df.thetas <- data.frame(date=indexquotes$date, r[,4:6]) + 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])){ + stmt <- sprintf(sqlstr.duration, df.durations[i,tenor], + df.durations[i,"date"], index, series, tenor) + dbSendQuery(serenitasdb, stmt) + } + if(!is.na(df.thetas[i,tenor])){ + stmt <- sprintf(sqlstr.theta, df.thetas[i,tenor], + df.thetas[i,"date"], index, series, tenor) + dbSendQuery(serenitasdb, stmt) + } + } + } +} + +## ## 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")) |
