diff --git a/R/InsuranceParameters.R b/R/InsuranceParameters.R index 2dd20cf46dbfae0bec451dacc8e5885108896621..b812c52ce9710ca91007d3250d7283a06c5fe9f2 100644 --- a/R/InsuranceParameters.R +++ b/R/InsuranceParameters.R @@ -260,6 +260,10 @@ InsuranceContract.Values = list( #' that returns a vector of coefficients for each year to #' interpolate the reserves available at the given \code{contractDates} #' for the desirec \code{balanceDates}}} +#' reserves.} +#' \item{\code{$unearnedPremiumsMethod}}{How to calculate the unearned +#' premiums (considering the balance sheet date and the premium +#' frequency). A function with signature \code{unearnedPremiumsMethod(params, dates)}} #' \item{\code{$surrenderValueCalculation}}{A function describing the surrender #' value calculation.} #' \item{\code{$premiumFrequencyOrder}}{Order of the approximation for @@ -399,6 +403,7 @@ InsuranceContract.ParameterDefaults = list( i = 0.00, # guaranteed interest rate balanceSheetDate = as.Date("1900-12-31"), # Balance sheet date (for the calculation of the balance sheet reserves, year is irrelevant) balanceSheetMethod = "30/360", + unearnedPremiumsMethod = NULL, # Function to calculate the factors for unearned premiums surrenderValueCalculation = NULL, # By default no surrender penalties premiumFrequencyOrder = 0, # Order of the approximation for payments within the year (unless an extra frequency loading is used => then leave this at 0) diff --git a/R/InsuranceTarif.R b/R/InsuranceTarif.R index 7f3a26b5c7b8696a749ae2071b67955125ba44d6..c24d067d154cddc061e59a9cb7596297db97d73a 100644 --- a/R/InsuranceTarif.R +++ b/R/InsuranceTarif.R @@ -1070,9 +1070,10 @@ InsuranceTarif = R6Class( #' @description Calculate the (linear) interpolation factors for the balance #' sheet reserve (Dec. 31) between the yearly contract clowing dates #' @details Not to be called directly, but implicitly by the [InsuranceContract] object. + #' @param method The method for the balance sheet interpolation (30/360, act/act, act/360, act/365 or a function) #' @param years how many years to calculate (for some usances, the factor #' is different in leap years!) - getBalanceSheetReserveFactor = function(params, years = 1) { + getBalanceSheetReserveFactor = function(method, params, years = 1) { balanceDate = params$ActuarialBases$balanceSheetDate year(balanceDate) = year(params$ContractData$contractClosing); if (balanceDate < params$ContractData$contractClosing) { @@ -1082,15 +1083,15 @@ InsuranceTarif = R6Class( contractDates = params$ContractData$contractClosing + years(1:years); balanceDates = balanceDate + years(1:years - 1); - if (is.function(params$ActuarialBases$balanceSheetMethod)) { - baf = params$ActuarialBases$balanceSheetMethod(params = params, contractDates = contractDates, balanceDates = balanceDates) - } else if (params$ActuarialBases$balanceSheetMethod == "30/360") { + if (is.function(method)) { + baf = method(params = params, contractDates = contractDates, balanceDates = balanceDates) + } else if (method == "30/360") { baf = ((month(balanceDates + days(1)) - month(contractDates) - 1) %% 12 + 1) / 12 - } else if (params$ActuarialBases$balanceSheetMethod == "act/act") { + } else if (method == "act/act") { baf = as.numeric((balanceDates + days(1)) - contractDates, units = "days" ) / as.numeric(balanceDates - (balanceDates - years(1)), units = "days") - } else if (params$ActuarialBases$balanceSheetMethod == "act/360") { + } else if (method == "act/360") { baf = pmin(as.numeric((balanceDates + days(1)) - contractDates, units = "days" ) / 360, 1) - } else if (params$ActuarialBases$balanceSheetMethod == "act/365") { + } else if (method == "act/365") { baf = pmin(as.numeric((balanceDates + days(1)) - contractDates, units = "days" ) / 365, 1) } data.frame(date = balanceDates, time = baf + (1:years) - 1, baf = baf) @@ -1104,7 +1105,7 @@ InsuranceTarif = R6Class( reserves = values$reserves; years = length(reserves[,"Zillmer"]); # Balance sheet reserves: - factors = self$getBalanceSheetReserveFactor(params, years = years); + factors = self$getBalanceSheetReserveFactor(method = params$ActuarialBases$balanceSheetMethod, params = params, years = years); baf = factors$baf factors$baf = NULL resZ_BS = (1 - baf) * reserves[,"Zillmer"] + baf * c(reserves[-1, "Zillmer"], 0); @@ -1112,12 +1113,16 @@ InsuranceTarif = R6Class( res_BS = resZ_BS + resGamma_BS; # Premium transfer / unearned premium: - bm = month(params$ContractData$contractClosing) - freq = params$ContractData$premiumFrequency + fact = valueOrFunction(params$ActuarialBases$unearnedPremiumsMethod, params = params, dates = factors$date) + if (is.null(fact) || is.na(fact)) { + freq = params$ContractData$premiumFrequency + bm = month(params$ContractData$contractClosing) + + fact = (month(factors$date) - bm + 12 + 1) %% (12/freq) * (freq/12) + } # TODO: We have no vector of actual written premiums (implicit assumption # seems to be that the premium stays constant!). Once we have such a vector, # rewrite the following code - fact = (bm - 1) %% (12/freq) / 12 * freq unearnedPremiums = fact * values$cashFlows$premiums_advance * values$premiums[["written_beforetax"]] # TODO # If advance profit participation is granted, unearned premiums still apply to the whole gross premium without PP and partner rebate! ppScheme = params$ProfitParticipation$profitParticipationScheme;