R/cross_currency_date_convention.R

setClass(
    Class          = "CrossCurrencyDateConvention",
    contains       = "DateConvention",
    representation = representation(
        calendar2 = "Calendar",
        spotLag   = "integer"
    )
)

setMethod(
    f          = "SetIsHoliday",
    signature  = "CrossCurrencyDateConvention",
    definition = function(object){
        calendar1  <- object@calendar
        calendar2  <- object@calendar2
        IsHoliday1 <- SetIsHoliday(calendar1)
        IsHoliday2 <- SetIsHoliday(calendar2)
        IsHoliday  <- function(date) IsHoliday1(date) | IsHoliday2(date)
        if (is(calendar1, "UsdCalendar") || is(calendar2, "UsdCalendar")) {
            IsHoliday
        } else {
            IsUsHoliday <- SetIsHoliday(UsdCalendar())
            function(date) IsUsHoliday(date) | IsHoliday(date)
        }
    }
)

setMethod(
    f          = "SetEndOfMonth",
    signature  = "CrossCurrencyDateConvention",
    definition = function(object) {
        calendar1   <- object@calendar
        calendar2   <- object@calendar2
        EndOfMonth1 <- SetEndOfMonth(calendar1)
        EndOfMonth2 <- SetEndOfMonth(calendar2)
        EndOfMonth  <- function(date) pmin(EndOfMonth1(date), EndOfMonth2(date))
        if (is(calendar1, "UsdCalendar") || is(calendar2, "UsdCalendar")) {
            EndOfMonth
        } else {
            UsEndOfMonth <- SetEndOfMonth(UsdCalendar())
            function(date) pmin(UsEndOfMonth(date, EndOfMonth(date)))
        }
    }
)

setMethod(
    f          = "SetTenorConverter",
    signature  = signature(convention = "CrossCurrencyDateConvention",
                           valueDate  = "Date"),
    definition = function(convention, valueDate) {
        ConvertNonSpotTenorToDate <- callNextMethod(convention)
        spotDate                  <- SpotDate(convention, valueDate)
        IsHoliday                 <- SetIsHoliday(convention)
        
        function(tenor) {
            datNums          <- integer(length(tenor))
            isSpotTenor      <- substring(tenor, 1, 1) == "S"
            notSpotTenor     <- !isSpotTenor
            
            if (any(isSpotTenor)) {
                spotTenor   <- tenor[spotTenor] 
                spotDateNum <- numeric(length(spotDateNum))
                
                for (targetTenor in c("SN", "SW")) {
                    
                    isTargetTenor <- spotTenor == targetTenor
                    addTime       <- switch(targetTenor,
                                            "SN" = lubridate::days(),
                                            "SW" = lubridate::weeks())
                    
                    targetDate    <- spotDate %m+% addTime
                    
                    while (IsHoliday(targetDate)) {
                        targetDate %m+% lubridate::days()
                    }
                    
                    spotDateNum[isTargetTenor] <- as.integer(targetDate)
                }
                
                datNums[isSpotTenor] <- spotDateNum
            }
            
            if (any(notSpotTenor)) {
                datNums[notSpotTenor] <- ConvertNonSpotTenorToDate(tenor[notSpotTenor])
            }
            
            AsDate(datNums)
        }
    }
)

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

setMethod(
    f          = "SpotDate",
    signature  = signature(convention = "CrossCurrencyDateConvention", 
                           valueDate  = "Date"),
    definition = function(convention, valueDate) {
        spotLag       <- convention@spotLag
        spotDate      <- valueDate
        isBusinessDay <- SetIsBusinessDay(convn)
        
        while (spotLag > 0) {
            spotDate <- spotDate %m+% lubridate::days()
            if (isBusinessDay(spotDate)) {
                spotLag <- spotLag - 1
            }
        } 
        
        spotDate
    }
)
gfunk0704/StochasticVolatility documentation built on Feb. 8, 2020, 10:04 a.m.