diff --git a/DESCRIPTION b/DESCRIPTION index 9fda3583e535741623415bbea1dcfdc8dc714443..07c56c8e86de013c462452d8810ae7f502175777 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: LifeInsuranceContracts Type: Package -Version: 0.0.1 +Version: 0.0.2 Date: 2020-09-04 Title: A Framework for General, Traditional Life Insurance Contracts, Including Profit Participation and Contract Changes diff --git a/NAMESPACE b/NAMESPACE index 45d60ab6b1e711a7a290baf2e25603d97e53bf6b..91ad374b6432fc7d0a5708e04c898441c4cb976e 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -69,9 +69,11 @@ export(pad0) export(padLast) export(rollingmean) export(showVmGlgExamples) +export(sumProfits) export(valueOrFunction) exportClasses(CalculationSingleEnum) exportClasses(PaymentTimeSingleEnum) +exportClasses(ProfitComponentsMultipleEnum) exportClasses(SexSingleEnum) exportClasses(TariffTypeSingleEnum) import(MortalityTables) diff --git a/R/HelperFunctions.R b/R/HelperFunctions.R index 7dc0be10e91c1d7c8da2e8455488255706101ee9..98bf94f86c32744698d14dbe6c75bd0ccd53b14f 100644 --- a/R/HelperFunctions.R +++ b/R/HelperFunctions.R @@ -18,7 +18,7 @@ PaymentTimeEnum = objectProperties::setSingleEnum("PaymentTime", levels = c("in #' Enum to describe possible sexes in an insurance contract or tariff. #' @details -#' Currently, only possible values are allowed; +#' Currently, the only possible values are: #' * "unisex" #' * "male" #' * "female" @@ -33,6 +33,18 @@ SexEnum = objectProperties::setSingleEnum("Sex", levels = c("unisex", "male", "f #' would be a waste of resources to calculate e.g. all future reserves and #' profit participation, if only premiums are of interest. #' +#' Possible values are: +#' * "all" +#' * "probabilities" +#' * "cashflows" +#' * "presentvalues" +#' * "premiums" +#' * "absvalues" +#' * "reserves" +#' * "premiumcomposition" +#' * "profitparticipation" +#' * "history" +#' #' @export CalculationEnum = objectProperties::setSingleEnum("Calculation", levels = c( @@ -49,6 +61,46 @@ CalculationEnum = objectProperties::setSingleEnum("Calculation", ) ) + +#' Enum to define the different components of profit participation. +#' @details +#' Profit participation schemes typically consist of different components, +#' which are calculated independently. Typical components are interest profit +#' to distribute investment gains to the customer, risk profit and expense profit +#' to return security margins in the biometric risk and the expenses to the customer +#' and sum profit, which aplies to contracts with higher sums insured, where +#' charged expenses are calculated from the sum insured, while the actual +#' expenses are more or less constant. Thus, high contracts are charged more, +#' which causes profits that are returned as sum profit. +#' +#' As a special case, part of the profits can be stored in a terminal bonus +#' reserve and only distributed on maturity (or potentially on death), but +#' not on surrender. Some (older) profit participation schemes add an independently +#' calculated bonus on maturity (e.g. twice the total profit assignment of the +#' last year) at maturity to give customers an additional incentive not to +#' surrender a contract. +#' +#' Possible values are (multiple can be given): +#' * "interest" +#' * "risk" +#' * "expense" +#' * "sum" +#' * "terminal" +#' * "TBF" +#' +#' @export +ProfitComponentsEnum = objectProperties::setMultipleEnum("ProfitComponents", + levels = c( + "advance", + "interest", + "risk", + "expense", + "sum", + "terminal", + "TBF" + ) +) + #' Describes the death benefit of a linearly decreasing whole life insurance (after a possible deferall period) #' #' The death benefit will be the full sumInsured for the first year after the @@ -464,6 +516,26 @@ fallbackFields = function(fields, valuelist) { rollingmean = function(x) (tail(x, -1) + head(x, -1))/2 +# Sum two or more vectors and correctly handle (i.e. ignore) NULL values given +plusNULL = function(v1, v2, ...) { + if (missing(v2) && length(list(...)) == 0) { + if (missing(v1) || is.null(v1)) { + return(0) + } else { + return(v1) + } + } + if (missing(v1) || is.null(v1)) { + return(plusNULL(v2, ...)); + } + if (missing(v2) || is.null(v2)) { + return(plusNULL(v1, ...)); + } else { + return(plusNULL(v1 + v2, ...)) + } +} + + ######################################################################=# # Functions for handling sub-contract blocks #### @@ -493,3 +565,5 @@ sumPaddedArrays = function(arr1 = NULL, arr2 = NULL, pad1 = 0, pad2 = 0) { arr1 + arr2 } } + + diff --git a/R/InsuranceParameters.R b/R/InsuranceParameters.R index 4403f768481efe4982c521da57e937bd8acb6e8a..388ef50b5fc9df7cf8f89b1fbf20b6872a7b1987 100644 --- a/R/InsuranceParameters.R +++ b/R/InsuranceParameters.R @@ -293,7 +293,7 @@ InsuranceContract.Values = list( #' \item{\code{$premiumFrequencyLoading}}{Loading on the premium for premium #' payment frequencies of more than once a year. Format is #' \code{list("1" = 0.0, "2" = 0.0, "4" = 0.0, "12" = 0.0)}} -#' \item{\code{$alphaRefundPeriod}}{How long the acquisition costs should be +#' \item{\code{$alphaRefundPeriod}}{How long the acquisition costs should be #' (partially) refunded in case of surrender or premium waiver.} #' } #' @@ -438,7 +438,7 @@ InsuranceContract.ParameterDefaults = list( terminalBonusFundRate = NULL, profitParticipationScheme = NULL, # Gewinnbeteiligungssystem (object of class Profit Participation) - profitComponents = c("interest", "risk", "expense", "sum", "terminal"), + 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/ProfitParticipation.R b/R/ProfitParticipation.R index a289a893797616b20691283f920e8166dcbf08fc..88ce7efc2602ab6e5a0b0ac280f496e08ed8b12c 100644 --- a/R/ProfitParticipation.R +++ b/R/ProfitParticipation.R @@ -377,24 +377,34 @@ ProfitParticipation = R6Class( } rates = self$setupRates(params = params, values = values, ...) - intBase = self$Functions$getInterestProfitBase(rates = rates, params = params, values = values); - riskBase = self$Functions$getRiskProfitBase(rates = rates, params = params, values = values); - expenseBase = self$Functions$getExpenseProfitBase(rates = rates, params = params, values = values); - sumBase = self$Functions$getSumProfitBase(rates = rates, params = params, values = values); - - intRate = self$Functions$getInterestProfitRate(rates = rates, params = params, values = values); - riskRate = self$Functions$getRiskProfitRate(rates = rates, params = params, values = values); - expenseRate = self$Functions$getExpenseProfitRate(rates = rates, params = params, values = values); - sumRate = self$Functions$getSumProfitRate(rates = rates, params = params, values = values); - - intProfit = self$Functions$calculateInterestProfit(base = intBase, rate = intRate, waiting = waitingFactor, rates = rates, params = params, values = values); - riskProfit = self$Functions$calculateRiskProfit(base = riskBase, rate = riskRate, waiting = waitingFactor, rates = rates, params = params, values = values); - expenseProfit = self$Functions$calculateExpenseProfit(base = expenseBase, rate = expenseRate, waiting = waitingFactor, rates = rates, params = params, values = values); - sumProfit = self$Functions$calculateSumProfit(base = sumBase, rate = sumRate, waiting = waitingFactor, rates = rates, params = params, values = values); + # Initialize all rates, bases and calc functions to NULL and then set + # only those that are actually used in this profit scheme (all values + # with NULL will silently be ignored in the cbind call) + intBase = riskBase = expenseBase = sumBase = NULL; + intRate = riskRate = expenseRate = sumRate = NULL; + intProfit = riskProfit = expenseProfit = sumProfit = NULL interestOnProfitRate = self$Functions$getInterestOnProfits(rates = rates, params = params, values = values); - - + if ("interest" %in% params$ProfitParticipation$profitComponents) { + intBase = self$Functions$getInterestProfitBase(rates = rates, params = params, values = values); + intRate = self$Functions$getInterestProfitRate(rates = rates, params = params, values = values); + intProfit = self$Functions$calculateInterestProfit(base = intBase, rate = intRate, waiting = waitingFactor, rates = rates, params = params, values = values); + } + if ("risk" %in% params$ProfitParticipation$profitComponents) { + riskBase = self$Functions$getRiskProfitBase(rates = rates, params = params, values = values); + riskRate = self$Functions$getRiskProfitRate(rates = rates, params = params, values = values); + riskProfit = self$Functions$calculateRiskProfit(base = riskBase, rate = riskRate, waiting = waitingFactor, rates = rates, params = params, values = values); + } + if ("expense" %in% params$ProfitParticipation$profitComponents) { + expenseBase = self$Functions$getExpenseProfitBase(rates = rates, params = params, values = values); + expenseRate = self$Functions$getExpenseProfitRate(rates = rates, params = params, values = values); + expenseProfit = self$Functions$calculateExpenseProfit(base = expenseBase, rate = expenseRate, waiting = waitingFactor, rates = rates, params = params, values = values); + } + if ("sum" %in% params$ProfitParticipation$profitComponents) { + sumBase = self$Functions$getSumProfitBase(rates = rates, params = params, values = values); + sumRate = self$Functions$getSumProfitRate(rates = rates, params = params, values = values); + sumProfit = self$Functions$calculateSumProfit(base = sumBase, rate = sumRate, waiting = waitingFactor, rates = rates, params = params, values = values); + } res = cbind( # Profit Calculation Bases @@ -417,93 +427,116 @@ ProfitParticipation = R6Class( riskProfit = c(riskProfit), expenseProfit = c(expenseProfit), sumProfit = c(sumProfit), - componentsProfit = c(intProfit + riskProfit + expenseProfit + sumProfit), + componentsProfit = plusNULL(intProfit, riskProfit, expenseProfit, sumProfit), interestOnProfit = c(0), totalProfitAssignment = c(0), totalProfit = c(0) ); - # Use only newly calculated values starting at 'calculateFrom', but use old values up to that moment (might be a contract change with a completely different profit participation system before!) + + # Use only newly calculated values starting at 'calculateFrom', but use + # old values up to that moment (might be a contract change with a + # completely different profit participation system before!) res = mergeValues(starting = profitScenario[,colnames(res)], ending = res, t = calculateFrom); - # res = self$Functions$calculateInterestOnProfit(base = sumBase, rate = sumRate, waiting = waitingFactor, rates = rates, params = params, values = values); if (calculateFrom > 0 && !is.null(profitScenario)) { prev = profitScenario[calculateFrom - 1, "totalProfit"] } else { prev = 0; } + # TODO: turn the interest on profit into a calculator function! + # res = self$Functions$calculateInterestOnProfit(base = sumBase, rate = sumRate, waiting = waitingFactor, rates = rates, params = params, values = values); for (i in (calculateFrom + 1):nrow(res)) { res[i,"interestOnProfit"] = res[i,"interestOnProfitRate"] * prev; res[i,"totalProfitAssignment"] = res[i, "componentsProfit"] + res[i,"interestOnProfit"]; res[i,"totalProfit"] = prev + res[i,"totalProfitAssignment"]; prev = res[i,"totalProfit"]; } + regularBonusAssignment = res[,"totalProfitAssignment"] + ###########################################################################################################%# #### OLD Terminal bonus (not through terminal bonus fund, i.e. part of ongoing profits, but in addition) #### #### Terminal Bonus calculations (might depend on the individual profit assignments calculated above! + ###########################################################################################################%# #### => TODO: Pass the current profit calculation inside the values!) - terminalBase = self$Functions$getTerminalBonusBase(res, rates = rates, params = params, values = values); - terminalRate = self$Functions$getTerminalBonusRate(res, rates = rates, params = params, values = values); - terminalBonus = self$Functions$calculateTerminalBonus(res, base = terminalBase, rate = terminalRate, calculateFrom = calculateFrom, waiting = waitingFactor, rates = rates, params = params, values = values); # TODO: Add the AF(v) factor! - res1 = cbind( - terminalBase, - terminalRate, - terminalBonus - ) - res1 = mergeValues(starting = profitScenario[,colnames(res1)], ending = res1, t = calculateFrom) - if (calculateFrom == 0) { - terminalBonusAccount = cumsum(terminalBonus); # TODO: Generalize! Not every scheme uses a cumulative account! - } else { - past = profitScenario[1:calculateFrom, "terminalBonusAccount"] - # Preserve values up to calculateFrom, start from the last known value at calculateFrom-1 and sum all further contributions: - terminalBonusAccount = c(head(past, -1), cumsum(c(tail(past,1), tail(terminalBonus, -calculateFrom)))) + if ("terminal" %in% params$ProfitParticipation$profitComponents) { + terminalBase = self$Functions$getTerminalBonusBase(res, rates = rates, params = params, values = values); + terminalRate = self$Functions$getTerminalBonusRate(res, rates = rates, params = params, values = values); + terminalBonus = self$Functions$calculateTerminalBonus(res, + base = terminalBase, rate = terminalRate, calculateFrom = calculateFrom, + waiting = waitingFactor, rates = rates, params = params, values = values); # TODO: Add the AF(v) factor! + + if (calculateFrom == 0) { + terminalBonusAccount = cumsum(terminalBonus); # TODO: Generalize! Not every scheme uses a cumulative account! + } else { + past = profitScenario[1:calculateFrom, "terminalBonusAccount"] + # Preserve values up to calculateFrom, start from the last known value at calculateFrom-1 and sum all further contributions: + terminalBonusAccount = c(head(past, -1), cumsum(c(tail(past,1), tail(terminalBonus, -calculateFrom)))) + } + terminalBonusReserve = self$Functions$getTerminalBonusReserve(res, rates = rates, terminalBonus, terminalBonusAccount, params = params, values = values) + + resTerminal = cbind( + terminalBase, + terminalRate, + terminalBonus, + terminalBonusAccount, + terminalBonusReserve + ) + resTerminal = mergeValues(starting = profitScenario[,colnames(resTerminal)], ending = resTerminal, t = calculateFrom) + # Add the terminal bonus values to the array: + res = cbind(res, resTerminal) } - terminalBonusReserve = self$Functions$getTerminalBonusReserve(res, rates = rates, terminalBonus, terminalBonusAccount, params = params, values = values) - res2 = cbind(terminalBonusAccount, terminalBonusReserve) - res = cbind( - res, - # Terminal Bonus values - res1, - mergeValues(starting = profitScenario[,colnames(res2)], ending = res2, t = calculateFrom) - ) + ###########################################################################################################%# #### NEW Terminal bonus fund (part of regular profits, but not paid out on surrender, reserved as part of the free RfB) #### - TBFBase = self$Functions$getTerminalBonusFundBase(res, rates = rates, params = params, values = values); - TBFRate = self$Functions$getTerminalBonusFundRate(res, rates = rates, params = params, values = values); - TBFBonusAssignment = self$Functions$calculateTerminalBonusFund(res, base = TBFBase, rate = TBFRate, calculateFrom = calculateFrom, waiting = waitingFactor, rates = rates, params = params, values = values); - regularBonusAssignment = res[,"totalProfitAssignment"] - TBFBonusAssignment - res1 = cbind( - TBFBase, - TBFRate, - TBFBonusAssignment, - regularBonusAssignment - ) - res1 = mergeValues(starting = profitScenario[,colnames(res1)], ending = res1, t = calculateFrom) + ###########################################################################################################%# + if ("TBF" %in% params$ProfitParticipation$profitComponents) { + TBFBase = self$Functions$getTerminalBonusFundBase(res, rates = rates, params = params, values = values); + TBFRate = self$Functions$getTerminalBonusFundRate(res, rates = rates, params = params, values = values); + TBFBonusAssignment = self$Functions$calculateTerminalBonusFund(res, + base = TBFBase, rate = TBFRate, calculateFrom = calculateFrom, + waiting = waitingFactor, rates = rates, params = params, values = values); + regularBonusAssignment = res[,"totalProfitAssignment"] - TBFBonusAssignment + + # Calculate TBF and regular bonus as cumulative sum of the assignments starting at t = calculateFrom plus the previous value! + if (calculateFrom == 0) { + TBF = cumsum(TBFBonusAssignment) + } else { + past = profitScenario[1:calculateFrom, "TBF"] + # Preserve values up to calculateFrom, start from the last known value at calculateFrom-1 and sum all further contributions: + TBF = c(head(past, -1), cumsum(c(tail(past,1), tail(TBFBonusAssignment, -calculateFrom)))) + } + + + resTBF = cbind( + TBFBase, + TBFRate, + TBFBonusAssignment, + TBF + ) + resTBF = mergeValues(starting = profitScenario[,colnames(resTBF)], ending = resTBF, t = calculateFrom) + # Add the terminal bonus fund values to the array: + res = cbind(res, resTBF) + } - # Calcula TBF and regular bonus as cumulative usm of the assignments starting at t=calculateFrom plus the previous value! + ###########################################################################################################%# + #### Regular bonus assignment / accrued regular bonus AFTER TBF #### + ###########################################################################################################%# + # Calculate regular bonus (after potential TBF subtraction) as cumulative sum of the assignments starting at t = calculateFrom plus the previous value! if (calculateFrom == 0) { - TBF = cumsum(TBFBonusAssignment) regularBonus = cumsum(regularBonusAssignment) } else { - past = profitScenario[1:calculateFrom, "TBF"] - # Preserve values up to calculateFrom, start from the last known value at calculateFrom-1 and sum all further contributions: - TBF = c(head(past, -1), cumsum(c(tail(past,1), tail(TBFBonusAssignment, -calculateFrom)))) past = profitScenario[1:calculateFrom, "regularBonus"] regularBonus = c(head(past, -1), cumsum(c(tail(past,1), tail(regularBonusAssignment, -calculateFrom)))) } - res2 = cbind( - TBF, - regularBonus - ) - res2 = mergeValues(starting = profitScenario[,colnames(res2)], ending = res2, t = calculateFrom) - + resRegular = cbind(regularBonusAssignment, regularBonus) + resRegular = mergeValues(starting = profitScenario[,colnames(resRegular)], ending = resRegular, t = calculateFrom) + res = cbind(res, resRegular) - res = cbind( - res, - res1, - res2 - ) + ###########################################################################################################%# + #### BENEFITS #### + ###########################################################################################################%# survival = self$Functions$calculateSurvivalBenefit(res, rates = rates, params = params, values = values); @@ -516,7 +549,7 @@ ProfitParticipation = R6Class( premiumWaiverAccrued = self$Functions$calculatePremiumWaiverBenefitAccrued(res, rates = rates, params = params, values = values); premiumWaiverTerminalBonus = self$Functions$calculatePremiumWaiverBenefitTerminal(res, rates = rates, params = params, values = values); - res1 = cbind( + resBenefit = cbind( survival = survival, deathAccrued = deathAccrued, @@ -532,45 +565,9 @@ ProfitParticipation = R6Class( premiumWaiver = premiumWaiverAccrued + premiumWaiverTerminalBonus ) # Preserve values up to time t=calculateFrom of the old scenario values - res1 = mergeValues(starting = profitScenario[,colnames(res1)], ending = res1, t = calculateFrom) - - - res = cbind( - res, - res1 - ); - - # Clean the huge dataframe by removing columns that refer to profit - # sources that the current profit plan does not provide - toremove = c(); - cnames = colnames(res) - if (!"interest" %in% params$ProfitParticipation$profitComponents) { - toremove = c(toremove, grep("^interest[BP]", cnames)); - } - if (!"risk" %in% params$ProfitParticipation$profitComponents) { - toremove = c(toremove, grep("^risk", cnames)); - } - if (!"expense" %in% params$ProfitParticipation$profitComponents) { - toremove = c(toremove, grep("^expense", cnames)); - } - if (!"sum" %in% params$ProfitParticipation$profitComponents) { - toremove = c(toremove, grep("^sum", cnames)); - } - if (!"terminal" %in% params$ProfitParticipation$profitComponents) { - toremove = c(toremove, - grep("^terminal", cnames), - grep("^.*TerminalBonus$", cnames) - ); - } - if (!"TBF" %in% params$ProfitParticipation$profitComponents) { - toremove = c(toremove, - grep("^TBF", cnames) - ); - } - if (length(toremove) > 0) { - res = res[,-toremove] - } + resBenefit = mergeValues(starting = profitScenario[,colnames(resBenefit)], ending = resBenefit, t = calculateFrom) + res = cbind(res, resBenefit); res }, diff --git a/R/ProfitParticipation_Functions.R b/R/ProfitParticipation_Functions.R index 5a472429181131c3820db3661d062c6e3fdf2cbe..492514efe08bc6253948f431363abb7ebc9a1d3f 100644 --- a/R/ProfitParticipation_Functions.R +++ b/R/ProfitParticipation_Functions.R @@ -241,11 +241,32 @@ PP.calculate.RateOnBaseSGFFactor = function(base, rate, waiting, rates, params, # rates defined with the functions above. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#' @describeIn ProfitParticipationFunctions +#' Extract the given columns of the profit participation array of values and sum +#' them up. Columns that do not exist, because the profit scheme does not +#' provide the corresponding profit component will be silently ignored. +#' This allows generic benefit calculation functions to be written that do +#' not need to distinguish e.g. whether an old-style terminal bonus or a terminal +#' bonus fund is provided. +#' +#' This function is not meant to be called directly, but within a profit benefit +#' calculation function. +#' +#' @param profits The array of profit participation component values +#' @param cols The columns of the profit values array to be summed (columns given that do not exist in the profits array are ignired) +#' @export +sumProfits = function(profits, cols) { + # extract the columns -- if they exist -- and sum them up: + rowSums( + profits[, intersect(c(), colnames(profits))] + ) +} + #' @describeIn ProfitParticipationFunctions #' Calculate survival benefit as total profit amount plus the terminal bonus reserve #' @export PP.benefit.ProfitPlusTerminalBonusReserve = function(profits, ...) { - profits[,"regularBonus"] + profits[,"TBF"] + profits[,"terminalBonusReserve"] + sumProfits(profits, c("regularBonus", "TBF", "terminalBonusReserve")) }; #' @describeIn ProfitParticipationFunctions @@ -309,7 +330,7 @@ PP.benefit.ProfitGuaranteeSupporting = function(profits, rates, params, values, #' @export PP.benefit.TerminalBonus5YearsProRata = function(profits, params, ...) { n = params$ContractData$policyPeriod; - (profits[, "terminalBonusReserve"] + profits[, "TBF"]) * (0:n)/n * ((0:n) >= max(10, n - 5)) + sumProfits(profits, c("TBF", "terminalBonusReserve")) * (0:n)/n * ((0:n) >= max(10, n - 5)) }; #' @describeIn ProfitParticipationFunctions @@ -317,14 +338,14 @@ PP.benefit.TerminalBonus5YearsProRata = function(profits, params, ...) { #' @export PP.benefit.TerminalBonus5Years = function(profits, params, ...) { n = params$ContractData$policyPeriod; - (profits[, "terminalBonusReserve"] + profits[, "TBF"]) * ((0:n) >= max(10, n - 5)) + sumProfits(profits, c("TBF", "terminalBonusReserve")) * ((0:n) >= max(10, n - 5)) } #' @describeIn ProfitParticipationFunctions #' Calculate benefit from terminal bonus (full bonus), either old-style terminal bonus reserve or Terminal Bonus Fund (TBF) #' @export PP.benefit.TerminalBonus = function(profits, params, ...) { - profits[, "terminalBonusReserve"] + profits[, "TBF"] + sumProfits(profits, c("TBF", "terminalBonusReserve")) }; "dummy" diff --git a/man/CalculationSingleEnum-class.Rd b/man/CalculationSingleEnum-class.Rd index b84793a3914d3099240ace848f33299fdf9d49f8..ed8e8db53fd75487c8da0b8bf1d3d488968e8106 100644 --- a/man/CalculationSingleEnum-class.Rd +++ b/man/CalculationSingleEnum-class.Rd @@ -13,4 +13,18 @@ When an \link{InsuranceContract} object is created, all time series are immediat calculated. However, sometimes, one only needs part of the values, so it would be a waste of resources to calculate e.g. all future reserves and profit participation, if only premiums are of interest. + +Possible values are: +\itemize{ +\item "all" +\item "probabilities" +\item "cashflows" +\item "presentvalues" +\item "premiums" +\item "absvalues" +\item "reserves" +\item "premiumcomposition" +\item "profitparticipation" +\item "history" +} } diff --git a/man/InsuranceContract.ParameterDefaults.Rd b/man/InsuranceContract.ParameterDefaults.Rd index 68ddbb386999887a4733f3e520ca5a565ff35f1c..cc60d3bf09c11c97885fff5967928a30bbe885c1 100644 --- a/man/InsuranceContract.ParameterDefaults.Rd +++ b/man/InsuranceContract.ParameterDefaults.Rd @@ -184,6 +184,8 @@ payment frequencies of more than once a year. Format is \item{\code{$premiumFrequencyLoading}}{Loading on the premium for premium payment frequencies of more than once a year. Format is \code{list("1" = 0.0, "2" = 0.0, "4" = 0.0, "12" = 0.0)}} +\item{\code{$alphaRefundPeriod}}{How long the acquisition costs should be +(partially) refunded in case of surrender or premium waiver.} } } diff --git a/man/ProfitComponentsMultipleEnum-class.Rd b/man/ProfitComponentsMultipleEnum-class.Rd new file mode 100644 index 0000000000000000000000000000000000000000..e0d0f521929d078326f12942d9f72d344c2a1e5f --- /dev/null +++ b/man/ProfitComponentsMultipleEnum-class.Rd @@ -0,0 +1,37 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/HelperFunctions.R +\docType{class} +\name{ProfitComponentsMultipleEnum-class} +\alias{ProfitComponentsMultipleEnum-class} +\alias{ProfitComponentsEnum} +\title{Enum to define the different components of profit participation.} +\description{ +Enum to define the different components of profit participation. +} +\details{ +Profit participation schemes typically consist of different components, +which are calculated independently. Typical components are interest profit +to distribute investment gains to the customer, risk profit and expense profit +to return security margins in the biometric risk and the expenses to the customer +and sum profit, which aplies to contracts with higher sums insured, where +charged expenses are calculated from the sum insured, while the actual +expenses are more or less constant. Thus, high contracts are charged more, +which causes profits that are returned as sum profit. + +As a special case, part of the profits can be stored in a terminal bonus +reserve and only distributed on maturity (or potentially on death), but +not on surrender. Some (older) profit participation schemes add an independently +calculated bonus on maturity (e.g. twice the total profit assignment of the +last year) at maturity to give customers an additional incentive not to +surrender a contract. + +Possible values are (multiple can be given): +\itemize{ +\item "interest" +\item "risk" +\item "expense" +\item "sum" +\item "terminal" +\item "TBF" +} +} diff --git a/man/ProfitParticipationFunctions.Rd b/man/ProfitParticipationFunctions.Rd index 2b2910dae91ccf0ee57c57270c0fc364be8781da..463246dbee555f2ab1e9695478ba6d6a20fe1735 100644 --- a/man/ProfitParticipationFunctions.Rd +++ b/man/ProfitParticipationFunctions.Rd @@ -27,6 +27,7 @@ \alias{PP.calculate.RateOnBaseMin0} \alias{PP.calculate.RatePlusGuaranteeOnBase} \alias{PP.calculate.RateOnBaseSGFFactor} +\alias{sumProfits} \alias{PP.benefit.ProfitPlusTerminalBonusReserve} \alias{PP.benefit.Profit} \alias{PP.benefit.ProfitPlusGuaranteedInterest} @@ -115,6 +116,8 @@ PP.calculate.RateOnBaseSGFFactor( ... ) +sumProfits(profits, cols) + PP.benefit.ProfitPlusTerminalBonusReserve(profits, ...) PP.benefit.Profit(profits, ...) @@ -153,7 +156,7 @@ insurance contract, including cash flows, premiums, reserves etc.).} \item{res}{the data.frame of reserves.} -\item{profits}{The data.frame of profits assigned} +\item{profits}{The array of profit participation component values} \item{terminalBonus}{The terminal bonus calculated} @@ -165,6 +168,8 @@ where terminal bonuses are accrued, potentiall discounted from the maturity)} \item{rate}{The profit participation rate} \item{waiting}{A possible waiting period} + +\item{cols}{The columns of the profit values array to be summed (columns given that do not exist in the profits array are ignired)} } \description{ Various helper functions for the \code{ProfitParticipation} class that @@ -223,6 +228,16 @@ the rates and how the assigned profit is calculated. \item \code{PP.calculate.RateOnBaseSGFFactor}: Calculate profit by a simple rate applied on the basis (with only (1-SGFFactor) put into profit participation, and an optional waiting vector of values 0 or 1) +\item \code{sumProfits}: Extract the given columns of the profit participation array of values and sum +them up. Columns that do not exist, because the profit scheme does not +provide the corresponding profit component will be silently ignored. +This allows generic benefit calculation functions to be written that do +not need to distinguish e.g. whether an old-style terminal bonus or a terminal +bonus fund is provided. + +This function is not meant to be called directly, but within a profit benefit +calculation function. + \item \code{PP.benefit.ProfitPlusTerminalBonusReserve}: Calculate survival benefit as total profit amount plus the terminal bonus reserve \item \code{PP.benefit.Profit}: Calculate benefit as total profit accrued so far diff --git a/man/SexSingleEnum-class.Rd b/man/SexSingleEnum-class.Rd index 370804b793ebf930193b6dc2473833dd6edcb5e6..8d28e94c8d841d3c0058ae95ab6617dc30c18bfa 100644 --- a/man/SexSingleEnum-class.Rd +++ b/man/SexSingleEnum-class.Rd @@ -9,7 +9,7 @@ Enum to describe possible sexes in an insurance contract or tariff. } \details{ -Currently, only possible values are allowed; +Currently, the only possible values are: \itemize{ \item "unisex" \item "male"