From 07dea12d46f9d473a47aad5be27b7ab28fbba5d2 Mon Sep 17 00:00:00 2001 From: Reinhold Kainhofer <reinhold@kainhofer.com> Date: Sun, 3 Jan 2021 02:00:13 +0100 Subject: [PATCH] Add parameter useUnearnedPremiums to switch between unearned premiums and inclusion of full (single) premium in balance sheet reserve Single-premium contract typically do not use unearned premiums, but add the whole single-premium to the balance sheet reserve immediately. The parameter useUnearnedPremiums switches this behaviour. By default, single-premium contracts will not use unearned premiums (and include the full premium in the balance sheet reserve), while contracts with regulare premiums will use unearned premiums by default (and not include the premium paid at time t in the balance sheet reserve at time t). Closes #69 --- R/InsuranceParameters.R | 20 +++++++++-- R/InsuranceTarif.R | 39 +++++++++++++--------- R/exportInsuranceContract_xlsx.R | 2 ++ inst/Beispiele/Example_Endowment.R | 3 +- man/InsuranceContract.ParameterDefaults.Rd | 13 ++++++++ 5 files changed, 58 insertions(+), 19 deletions(-) diff --git a/R/InsuranceParameters.R b/R/InsuranceParameters.R index 3f0b087..1670c51 100644 --- a/R/InsuranceParameters.R +++ b/R/InsuranceParameters.R @@ -374,6 +374,19 @@ InsuranceContract.Values = list( #' included in the Zillmer premium calculation} #' \item{\code{$alphaRefundLinear}}{Whether the refund of alpha-costs on #' surrender is linear in t or follows the NPV of an annuity} +#' \item{\code{$useUnearnedPremiums}}{Whether unearned premiums should be +#' reported in the balance sheet reserves. Otherwise, a premium +#' paid at the beginning of the period is added to the reserve at +#' that time for balance-sheet purposes. +#' +#' For regular premiums, the default is TRUE, i.e. the balance-sheet +#' reserve at time $t$ does not include the premium paid at time +#' $t$, but unearned premiums are included in the balance sheet +#' reserves. For single-premium contracts, there are no "unearned" +#' premiums, but the initial single premium is added to the reserve +#' immediately for balance-sheet purposes. In particular, the +#' balance sheet reserve at time $t=0$ is not 0, but the +#' premium paid. In turn, no unearned premiums are applied.} #' } #' #' ## Elements of sublist \code{InsuranceContract.ParameterDefault$ProfitParticipation} @@ -490,9 +503,10 @@ InsuranceContract.ParameterDefaults = list( premiumFrequencyLoading = list("1" = 0.0, "2" = 0.0, "4" = 0.0, "12" = 0.0), # TODO: Properly implement this as a function alphaRefundPeriod = 5 # How long acquisition costs should be refunded in case of surrender ), - Features = list( # Special cases for the calculations + Features = list( # Special cases for the calculations betaGammaInZillmer = FALSE, # Whether beta and gamma-costs should be included in the Zillmer premium calculation - alphaRefundLinear = TRUE # Whether the refund of alpha-costs on surrender is linear in t or follows the NPV of an annuity + alphaRefundLinear = TRUE, # Whether the refund of alpha-costs on surrender is linear in t or follows the NPV of an annuity + useUnearnedPremiums = isRegularPremiumContract # Whether unearned premiums should be calculated in the balance sheet reserves. Otherwise, a premium paid at the beginning of the period is added to the reserve for balance-sheet purposes. ), ProfitParticipation = list( @@ -510,7 +524,7 @@ InsuranceContract.ParameterDefaults = list( terminalBonusRate = NULL, terminalBonusFundRate = NULL, - profitParticipationScheme = NULL, # Gewinnbeteiligungssystem (object of class Profit Participation) + profitParticipationScheme = NULL, # Gewinnbeteiligungssystem (object of class Profit Participation) profitComponents = c(), # Potential values: "interest", "risk", "expense", "sum", "terminal", "TBF" profitClass = NULL, profitRates = NULL, # General, company-wide profit rates, key columns are year and profitClass diff --git a/R/InsuranceTarif.R b/R/InsuranceTarif.R index 12c485c..ba54351 100644 --- a/R/InsuranceTarif.R +++ b/R/InsuranceTarif.R @@ -1118,32 +1118,41 @@ InsuranceTarif = R6Class( 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); - resGamma_BS = (1 - baf) * reserves[,"gamma"] + baf * c(reserves[-1, "gamma"], 0); + + useUnearnedPremiums = valueOrFunction(params$Features$useUnearnedPremiums, params = params, values = values) + resN_BS = (1 - baf) * (reserves[,"net"] + if (!useUnearnedPremiums) values$premiumComposition[,"net"] else 0) + baf * c(reserves[-1, "net"], 0) + resZ_BS = (1 - baf) * (reserves[,"Zillmer"] + if (!useUnearnedPremiums) values$premiumComposition[,"Zillmer"] else 0) + baf * c(reserves[-1, "Zillmer"], 0) + resGamma_BS = (1 - baf) * (reserves[,"gamma"] + if (!useUnearnedPremiums) values$premiumComposition[,"gamma"] else 0) + baf * c(reserves[-1, "gamma"], 0) res_BS = resZ_BS + resGamma_BS; # Premium transfer / unearned premium: - 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) + if (useUnearnedPremiums) { + 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 - 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; - if (!is.null(ppScheme)) { + 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 + 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; + if (!is.null(ppScheme)) { partnerRebate = valueOrFunction(params$Loadings$partnerRebate, params = params, values = values); advanceProfitParticipation = ppScheme$getAdvanceProfitParticipationAfterUnitCosts(params = params, values = values); unearnedPremiums = unearnedPremiums / (1 - partnerRebate - advanceProfitParticipation); + } + } else { + # If reserves contain single-premium, no unearned premiums are shown in the balance sheet! + unearnedPremiums = 0 } # Collect all reserves to one large matrix res = cbind(factors, + "net" = pmax(resN_BS,0), "Zillmer" = pmax(resZ_BS,0), "gamma" = pmax(resGamma_BS,0), "Balance Sheet Reserve" = pmax(res_BS,0), diff --git a/R/exportInsuranceContract_xlsx.R b/R/exportInsuranceContract_xlsx.R index 2a338f5..9c639fa 100644 --- a/R/exportInsuranceContract_xlsx.R +++ b/R/exportInsuranceContract_xlsx.R @@ -271,6 +271,8 @@ getContractBlockPremiums = function(contract) { values } +#' Convert the multi-dimensional costs array to a data.frame for output to a file +#' #' @description Convert the cost values array to a tx15 matrix #' @details Not to be called directly, but implicitly by the [InsuranceContract] object. #' Convert the array containing cost values like cashflows, present diff --git a/inst/Beispiele/Example_Endowment.R b/inst/Beispiele/Example_Endowment.R index e70b820..74d9aed 100644 --- a/inst/Beispiele/Example_Endowment.R +++ b/inst/Beispiele/Example_Endowment.R @@ -1,4 +1,5 @@ library(LifeInsuranceContracts) +library(MortalityTables) ################################################################### # # DEFINITION TARIF #### @@ -42,7 +43,7 @@ Tarif.Bsp = InsuranceTarif$new( type = "endowment", tarif = "BSP", desc = "Gemischte Versicherung (Standardtarif)", - #premiumPeriod = 1, + premiumPeriod = 1, #alphaRefundLinear = FALSE, mortalityTable = mort.AT.census.2011.unisex, diff --git a/man/InsuranceContract.ParameterDefaults.Rd b/man/InsuranceContract.ParameterDefaults.Rd index a16e49b..aee0e1f 100644 --- a/man/InsuranceContract.ParameterDefaults.Rd +++ b/man/InsuranceContract.ParameterDefaults.Rd @@ -212,6 +212,19 @@ payment frequencies of more than once a year. Format is included in the Zillmer premium calculation} \item{\code{$alphaRefundLinear}}{Whether the refund of alpha-costs on surrender is linear in t or follows the NPV of an annuity} +\item{\code{$useUnearnedPremiums}}{Whether unearned premiums should be +reported in the balance sheet reserves. Otherwise, a premium +paid at the beginning of the period is added to the reserve at +that time for balance-sheet purposes.\preformatted{ For regular premiums, the default is TRUE, i.e. the balance-sheet + reserve at time $t$ does not include the premium paid at time + $t$, but unearned premiums are included in the balance sheet + reserves. For single-premium contracts, there are no "unearned" + premiums, but the initial single premium is added to the reserve + immediately for balance-sheet purposes. In particular, the + balance sheet reserve at time $t=0$ is not 0, but the + premium paid. In turn, no unearned premiums are applied.\} +} + } } -- GitLab