From d7c88cdc1942f4ea34efa73d2e10b295a56594a7 Mon Sep 17 00:00:00 2001 From: Reinhold Kainhofer <reinhold@kainhofer.com> Date: Sat, 13 Nov 2021 10:28:23 +0100 Subject: [PATCH] Add unitcostsInGross Feature flag By default, the gross premium does not include unit costs, which are added after gross premium (but before taxes). Some companies include the unitcosts in the gross premium (which is refunded upon death -> correct calculation is essentaion). This flag allows a tarif to include the unit cost in the gross premium reather than adding later. Fixes Issue #73 (except for the documentation, which is covered by a different issue anyway) --- R/InsuranceParameters.R | 5 ++- R/InsuranceTarif.R | 41 +++++++++------------- man/InsuranceContract.ParameterDefaults.Rd | 2 ++ 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/R/InsuranceParameters.R b/R/InsuranceParameters.R index 06e5b13..56e99a0 100644 --- a/R/InsuranceParameters.R +++ b/R/InsuranceParameters.R @@ -446,6 +446,8 @@ InsuranceContract.Values = list( #' \item{\code{$surrenderIncludesCostsReserves}}{Whether (administration) #' cost reserves are paid out on surrender (i.e. included in the #' surrender value before surrender penalties are applied)} +#' \item{\code{$unitcostsInGross}}{Whether unit costs are included in the +#' gross premium calculation or added after gross premiums. (default: FALSE)} #' } #' #' ## Elements of sublist \code{InsuranceContract.ParameterDefault$ProfitParticipation} @@ -567,7 +569,8 @@ InsuranceContract.ParameterDefaults = list( 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 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. - surrenderIncludesCostsReserves = TRUE # Whether (administration) cost reserves are paid out on surrender (i.e. included in the surrender value before surrender penalties are applied) + surrenderIncludesCostsReserves = TRUE, # Whether (administration) cost reserves are paid out on surrender (i.e. included in the surrender value before surrender penalties are applied) + unitcostsInGross = FALSE ), ProfitParticipation = list( diff --git a/R/InsuranceTarif.R b/R/InsuranceTarif.R index 3a0b6d4..f63a054 100644 --- a/R/InsuranceTarif.R +++ b/R/InsuranceTarif.R @@ -903,35 +903,25 @@ InsuranceTarif = R6Class( # coefficients for the costs if (type == "gross") { - coeff[["SumInsured"]][["costs"]]["alpha", "SumInsured",] = 1; - coeff[["SumInsured"]][["costs"]]["beta", "SumInsured",] = 1; - coeff[["SumInsured"]][["costs"]]["gamma", "SumInsured",] = 1; + affected = c("alpha", "beta", "gamma") + if (params$Features$unitcostsInGross) { + affected = c(affected, "unitcosts") + } + coeff[["SumInsured"]][["costs"]][affected, "SumInsured", ] = 1; # TODO: How to handle beta costs proportional to Sum Insured - coeff[["Premium"]][["costs"]]["alpha", "SumPremiums",] = -values$unitPremiumSum; - coeff[["Premium"]][["costs"]]["beta", "SumPremiums",] = -values$unitPremiumSum; - coeff[["Premium"]][["costs"]]["gamma", "SumPremiums",] = -values$unitPremiumSum; - - coeff[["Premium"]][["costs"]]["alpha", "GrossPremium",] = -1; - coeff[["Premium"]][["costs"]]["beta", "GrossPremium",] = -1; - coeff[["Premium"]][["costs"]]["gamma", "GrossPremium",] = -1; - - coeff[["SumInsured"]][["costs"]]["alpha", "Constant",] = 1 / params$ContractData$sumInsured; - coeff[["SumInsured"]][["costs"]]["beta", "Constant",] = 1 / params$ContractData$sumInsured; - coeff[["SumInsured"]][["costs"]]["gamma", "Constant",] = 1 / params$ContractData$sumInsured; + coeff[["Premium"]] [["costs"]][affected, "SumPremiums", ] = -values$unitPremiumSum; + coeff[["Premium"]] [["costs"]][affected, "GrossPremium",] = -1; + coeff[["SumInsured"]][["costs"]][affected, "Constant", ] = 1 / params$ContractData$sumInsured; } else if (type == "Zillmer") { # TODO: Include costs with basis NetPremium and fixed costs! - coeff[["SumInsured"]][["costs"]]["Zillmer","SumInsured",] = 1; - coeff[["SumInsured"]][["costs"]]["Zillmer","SumPremiums",] = values$unitPremiumSum * premiums[["unit.gross"]]; - coeff[["SumInsured"]][["costs"]]["Zillmer","GrossPremium",] = premiums[["unit.gross"]]; + affected = c("Zillmer") if (params$Features$betaGammaInZillmer) { - coeff[["SumInsured"]][["costs"]]["beta", "SumInsured",] = 1; - coeff[["SumInsured"]][["costs"]]["gamma", "SumInsured",] = 1; - coeff[["SumInsured"]][["costs"]]["beta", "SumPremiums",] = values$unitPremiumSum * premiums[["unit.gross"]]; - coeff[["SumInsured"]][["costs"]]["gamma", "SumPremiums",] = values$unitPremiumSum * premiums[["unit.gross"]]; - coeff[["SumInsured"]][["costs"]]["beta", "GrossPremium",] = premiums[["unit.gross"]]; - coeff[["SumInsured"]][["costs"]]["gamma", "GrossPremium",] = premiums[["unit.gross"]]; + affected = c(affected, "beta", "gamma") } + coeff[["SumInsured"]][["costs"]][affected,"SumInsured", ] = 1; + coeff[["SumInsured"]][["costs"]][affected,"SumPremiums", ] = values$unitPremiumSum * premiums[["unit.gross"]]; + coeff[["SumInsured"]][["costs"]][affected,"GrossPremium",] = premiums[["unit.gross"]]; } applyHook(params$Hooks$adjustPremiumCoefficients, coeff, type = type, premiums = premiums, params = params, values = values, premiumCalculationTime = premiumCalculationTime) @@ -1022,7 +1012,10 @@ InsuranceTarif = R6Class( frequencyLoading = valueOrFunction(loadings$premiumFrequencyLoading, params = params, values = values); - premiumBeforeTax = (values$premiums[["unit.gross"]]*(1 + noMedicalExam.relative + extraChargeGrossPremium) + noMedicalExam - sumRebate - extraRebate) * sumInsured * (1 - advanceProfitParticipation) + premium.unitcosts; + premiumBeforeTax = (values$premiums[["unit.gross"]]*(1 + noMedicalExam.relative + extraChargeGrossPremium) + noMedicalExam - sumRebate - extraRebate) * sumInsured * (1 - advanceProfitParticipation); + if (params$Features$unitcostsInGross) { + premiumBeforeTax = premiumBeforeTax + premium.unitcosts; + } premiumBeforeTax = premiumBeforeTax * (1 - premiumRebate - advanceProfitParticipationUnitCosts - partnerRebate); # TODO / FIXME: Add a check that frequencyLoading has an entry for the premiumFrequency -> Otherwise do not add any loading (currently NULL is returned, basically setting all premiums to NULL) premiumBeforeTax.y = premiumBeforeTax * (1 + frequencyLoading[[toString(params$ContractData$premiumFrequency)]]); diff --git a/man/InsuranceContract.ParameterDefaults.Rd b/man/InsuranceContract.ParameterDefaults.Rd index f3c00be..b6d01ac 100644 --- a/man/InsuranceContract.ParameterDefaults.Rd +++ b/man/InsuranceContract.ParameterDefaults.Rd @@ -244,6 +244,8 @@ premium paid. In turn, no unearned premiums are applied.} \item{\code{$surrenderIncludesCostsReserves}}{Whether (administration) cost reserves are paid out on surrender (i.e. included in the surrender value before surrender penalties are applied)} +\item{\code{$unitcostsInGross}}{Whether unit costs are included in the +gross premium calculation or added after gross premiums. (default: FALSE)} } } -- GitLab