diff --git a/R/InsuranceParameters.R b/R/InsuranceParameters.R index 9caff53ad100a15c1e195efca9ecd95f7f74eb56..1696f23e03083a0cc8675337a1ae493a9e5041b3 100644 --- a/R/InsuranceParameters.R +++ b/R/InsuranceParameters.R @@ -513,6 +513,8 @@ InsuranceContract.Values = list( #' \item{\code{$adjustCosts}}{Function with signature \code{function(costs, params, values, ...)} to adjust the tariff costs after their setup (e.g. contract-specific conditions/waivers, etc.).} #' \item{\code{$adjustMinCosts}}{Function with signature \code{function(minCosts, costs, params, values, ...)} to adjust the tariff minimum (unwaivable) costs after their setup (e.g. contract-specific conditions/waivers, etc.).} #' \item{\code{$adjustPremiumCoefficients}}{Function with signature \code{function(coeff, type, premiums, params, values, premiumCalculationTime)} to adjust the coefficients for premium calculation after their default setup. Use cases are e.g. term-fix tariffs where the Zillmer premium term contains the administration cost over the whole contract, but not other gamma- or beta-costs.} +#' \item{\code{$adjustPVForReserves}}{Adjust the absolute present value vectors used to derive reserves (e.g. when a sum rebate is subtracted from the gamma-cost reserves without influencing the premium calculation). \code{function(absPV, params, values)}} +#' \item{\code{$premiumRebateCalculation}}{Calculate the actual premium rebate from the rebate rate (e.g. when the premium rate is given as a yearly cost reduction applied to a single-premium contract). \code{function(premiumRebateRate, params = params, values = values)}} #' } #' #' @@ -626,7 +628,9 @@ InsuranceContract.ParameterDefaults = list( adjustCashFlowsCosts = NULL, adjustCosts = NULL, adjustMinCosts = NULL, - adjustPremiumCoefficients = NULL # function(coeff, type = type, premiums = premiums, params = params, values = values, premiumCalculationTime = premiumCalculationTime) + adjustPremiumCoefficients = NULL, # function(coeff, type = type, premiums = premiums, params = params, values = values, premiumCalculationTime = premiumCalculationTime) + adjustPVForReserves = NULL, # function(absPresentValues, params, values) + premiumRebateCalculation = NULL # function(premiumRebateRate, params = params, values = values) ) ); diff --git a/R/InsuranceTarif.R b/R/InsuranceTarif.R index 52734ebbdf0c4441e8dc7579d86f07bcaf6957d7..a5d791e393ae51feb05d39ed5d5be4c72780b996 100644 --- a/R/InsuranceTarif.R +++ b/R/InsuranceTarif.R @@ -991,7 +991,9 @@ InsuranceTarif = R6Class( noMedicalExam.relative = valueOrFunction(loadings$noMedicalExamRelative,params = params, values = values); extraRebate = valueOrFunction(loadings$extraRebate, params = params, values = values); sumRebate = valueOrFunction(loadings$sumRebate, params = params, values = values); - premiumRebate = valueOrFunction(loadings$premiumRebate,params = params, values = values); + premiumRebateRate = valueOrFunction(loadings$premiumRebate,params = params, values = values); + premiumRebate = applyHook(params$Hooks$premiumRebateCalculation, premiumRebateRate, params = params, values = values); + extraChargeGrossPremium = valueOrFunction(loadings$extraChargeGrossPremium, params = params, values = values); advanceProfitParticipation = 0; advanceProfitParticipationUnitCosts = 0; @@ -1016,7 +1018,7 @@ InsuranceTarif = R6Class( values$premiums[["unitcost"]] = premium.unitcosts; - frequencyLoading = self$evaluateFrequencyLoading(loadings$premiumFrequencyLoading, params$ContractData$premiumFrequency, params = params, values = values) + frequencyLoading = self$evaluateFrequencyLoading(loadings$premiumFrequencyLoading, params$ContractData$premiumFrequency, params = params, values = values) premiumBeforeTax = (values$premiums[["unit.gross"]]*(1 + noMedicalExam.relative + extraChargeGrossPremium) + noMedicalExam - sumRebate - extraRebate) * sumInsured * (1 - advanceProfitParticipation); if (!params$Features$unitcostsInGross) { premiumBeforeTax = premiumBeforeTax + premium.unitcosts; @@ -1045,20 +1047,22 @@ InsuranceTarif = R6Class( securityFactor = (1 + valueOrFunction(params$Loadings$security, params = params, values = values)); ppScheme = params$ProfitParticipation$profitParticipationScheme; + absPV = applyHook(params$Hooks$adjustPVForReserves, values$absPresentValues, params = params, values = values); + # Net, Zillmer and Gross reserves - resNet = values$absPresentValues[,"benefitsAndRefund"] * securityFactor - values$premiums[["net"]] * values$absPresentValues[,"premiums.unit"]; - BWZcorr = ifelse(values$absPresentValues[t, "premiums"] == 0, 0, - values$absPresentValues[t, "Zillmer"] / values$absPresentValues[t, "premiums"]) * values$absPresentValues[,"premiums"]; + resNet = absPV[,"benefitsAndRefund"] * securityFactor - values$premiums[["net"]] * absPV[,"premiums.unit"]; + BWZcorr = ifelse(absPV[t, "premiums"] == 0, 0, + absPV[t, "Zillmer"] / absPV[t, "premiums"]) * absPV[,"premiums"]; resZ = resNet - BWZcorr; - resAdeq = values$absPresentValues[,"benefitsAndRefund"] * securityFactor + - values$absPresentValues[,"alpha"] + values$absPresentValues[,"beta"] + values$absPresentValues[,"gamma"] - - values$premiums[["gross"]] * values$absPresentValues[,"premiums.unit"]; + resAdeq = absPV[,"benefitsAndRefund"] * securityFactor + + absPV[,"alpha"] + absPV[,"beta"] + absPV[,"gamma"] - + values$premiums[["gross"]] * absPV[,"premiums.unit"]; - #values$premiums[["Zillmer"]] * values$absPresentValues[,"premiums"]; - resGamma = values$absPresentValues[,"gamma"] - - ifelse(values$absPresentValues[t, "premiums"] == 0, 0, - values$absPresentValues[t, "gamma"] / values$absPresentValues[t, "premiums"]) * values$absPresentValues[,"premiums"] + #values$premiums[["Zillmer"]] * absPV[,"premiums"]; + resGamma = absPV[,"gamma"] - + ifelse(absPV[t, "premiums"] == 0, 0, + absPV[t, "gamma"] / absPV[t, "premiums"]) * absPV[,"premiums"] advanceProfitParticipation = 0; if (!is.null(ppScheme)) { @@ -1106,7 +1110,7 @@ InsuranceTarif = R6Class( "reduction" = resReduction #, "Reserve.premiumfree"=res.premiumfree, "Reserve.gamma.premiumfree"=res.gamma.premiumfree); ); - rownames(res) <- rownames(values$absPresentValues); + rownames(res) <- rownames(absPV); values$reserves = res; # The surrender value functions can have arbitrary form, so we store a function @@ -1136,9 +1140,9 @@ InsuranceTarif = R6Class( premiumfreeValue = surrenderValue } Storno = 0; # TODO: Implement storno costs - premiumfreePV = (values$absPresentValues[, "benefits"] * securityFactor + values$absPresentValues[, "gamma_nopremiums"]); # PV of future premium free claims + costs + premiumfreePV = (absPV[, "benefits"] * securityFactor + absPV[, "gamma_nopremiums"]); # PV of future premium free claims + costs newSI = ifelse(premiumfreePV == 0, 0, - (premiumfreeValue - values$absPresentValues[,"death_Refund_past"] * securityFactor - c(Storno)) / + (premiumfreeValue - absPV[,"death_Refund_past"] * securityFactor - c(Storno)) / premiumfreePV * params$ContractData$sumInsured); cbind(res, @@ -1348,7 +1352,9 @@ InsuranceTarif = R6Class( profits.advance = profits.advance + afterProfit - afterUnitCosts; # premium rebate - premiumRebate = valueOrFunction(loadings$premiumRebate,params = params, values = values); + premiumRebateRate = valueOrFunction(loadings$premiumRebate,params = params, values = values); + premiumRebate = applyHook(params$Hooks$premiumRebateCalculation, premiumRebateRate, params = params, values = values); + afterPremiumRebate = afterUnitCosts * (1 - premiumRebate); rebate.premium = afterPremiumRebate - afterUnitCosts; diff --git a/man/InsuranceContract.ParameterDefaults.Rd b/man/InsuranceContract.ParameterDefaults.Rd index 3026da892a3daf36f48e3adc3de060306ec39f16..6060c66bb1d9baf7b7a4f1aab74f1c306cc55e89 100644 --- a/man/InsuranceContract.ParameterDefaults.Rd +++ b/man/InsuranceContract.ParameterDefaults.Rd @@ -110,6 +110,9 @@ those cost components that are defined to be waivable, i.e. by defining a corresponding \code{$minCosts}). Linearly interpolates between \code{$Costs} and \code{$minCosts}, if the latter is set. Otherwise is has no effect.} +\item{\code{$attributes}}{Additional custom attributes (as a named list), +which can be used for particular behaviour of different contracts +or contract slices.} } } @@ -291,6 +294,8 @@ participation rates are defined at the level of profit classes.} \item{\code{$adjustCosts}}{Function with signature \code{function(costs, params, values, ...)} to adjust the tariff costs after their setup (e.g. contract-specific conditions/waivers, etc.).} \item{\code{$adjustMinCosts}}{Function with signature \code{function(minCosts, costs, params, values, ...)} to adjust the tariff minimum (unwaivable) costs after their setup (e.g. contract-specific conditions/waivers, etc.).} \item{\code{$adjustPremiumCoefficients}}{Function with signature \code{function(coeff, type, premiums, params, values, premiumCalculationTime)} to adjust the coefficients for premium calculation after their default setup. Use cases are e.g. term-fix tariffs where the Zillmer premium term contains the administration cost over the whole contract, but not other gamma- or beta-costs.} +\item{\code{$adjustPVForReserves}}{Adjust the absolute present value vectors used to derive reserves (e.g. when a sum rebate is subtracted from the gamma-cost reserves without influencing the premium calculation). \code{function(absPV, params, values)}} +\item{\code{$premiumRebateCalculation}}{Calculate the actual premium rebate from the rebate rate (e.g. when the premium rate is given as a yearly cost reduction applied to a single-premium contract). \code{function(premiumRebateRate, params = params, values = values)}} } } }