R/date_convention.R

setClass(
    Class          = "DateConvention",
    representation = representation(
        calendar  = "Calendar"
    )
)

setGeneric(
    name = "SetTenorConvertor",
    def  = function(convention) {
        standardGeneric("SetTenorConvertor")
    } 
)

setMethod(
    f          = "SetEndOfMonth",
    signature  = "DateConvention",
    definition = function(object) SetEndOfMonth(object@calendar)
)

setMethod(
    f          = "SetIsHoliday",
    signature  = "DateConvention",
    definition = function(object) SetIsHoliday(object@calendar)
)

setGeneric(
    name = "SetTenorConverter",
    def  = function(convention, valueDate) {
        standardGeneric("SetTenorConverter")
    }
)

setMethod(
    f          = "SetTenorConverter",
    signature  = signature(convention = "DateConvention",
                           valueDate  = "Date"),
    definition = function(convention, valueDate) {
        IsHoliday  <- SetIsHoliday(convention)
        EndOfMonth <- SetEndOfMonth(convention)
        nightTenor <- c("ON", "TN")
        
        function(tenor) {
            for (nBusinessDays in 1:2) {
                isNightTenor <- tenor == nightTenor[nBusinessDays]
                
                if (any(isNightTenor)) {
                    expiryDate <- valueDate
                    remainDays <- nBusinessDays
                    nDays      <- 0
                    
                    while (remainDays > 0) {
                        expiryDate <- expiryDate %m+% lubridate::days()
                        nDays      <- nDays + 1
                        if (!IsHoliday(expiryDate)) {
                            remainDays - 1
                        }
                    }
                    
                    tenor[isNightTenor] <- paste0(nDays, "D")
                }
            }
            
            nChar   <- nchar(tenor)
            dateNum <- mapply(FUN  = function(num, unit) {
                                  AddTime <- switch(unit,
                                                    "D" = lubridate::days,
                                                    "W" = lubridate::weeks,
                                                    "M" = lubridate::months,
                                                    "Y" = lubridate::years)
                                  
                                  expiryDate <- valueDate %m+% AddTime(num)
                                  
                                  if (IsHoliday(expiryDate)) {
                                      if ((unit %in% c("D", "W")) ||
                                          (expiryDate < EndOfMonth9expiryDate)) {
                                          while (IsHoliday(expiryDate)) {
                                              expiryDate <- expiryDate %m+% lubridate::days()
                                          }
                                      } else {
                                          expiryDate <-  EndOfMonth(expiryDate)
                                      }
                                  }
                                  
                                  expiryDate
                              },
                              num  = as.integer(substring(tenor, 1, nChar - 1)), 
                              unit = substring(tenor, nChar, nChar))
            
            AsDate(dateNum)
        }
    } 
)

setMethod(
    f          = "SetTenorConverter",
    signature  = signature(convention = "DateConvention",
                           valueDate  = "missing"),
    definition = function(convention, valueDate) SetTenorConvertor(convention, ValueDate())
)
gfunk0704/StochasticVolatility documentation built on Feb. 8, 2020, 10:04 a.m.