diff --git a/NAMESPACE b/NAMESPACE index 371a683ebb5e05d276820772bc2e72366d35dddd..ca57ebf47c4bcf582a3b1ff301f5ec2202a9cb80 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -21,7 +21,9 @@ export(PP.base.contractualReserve) export(PP.base.meanContractualReserve) export(PP.base.previousContractualReserve) export(PP.base.sumInsured) +export(PP.base.totalProfitAssignment) export(PP.benefit.Profit) +export(PP.benefit.ProfitGuaranteeSupporting) export(PP.benefit.ProfitPlusGuaranteedInterest) export(PP.benefit.ProfitPlusHalfGuaranteedInterest) export(PP.benefit.ProfitPlusHalfInterestMinGuaranteeTotal) @@ -29,6 +31,8 @@ export(PP.benefit.ProfitPlusHalfTotalInterest) export(PP.benefit.ProfitPlusInterestMinGuaranteeTotal) export(PP.benefit.ProfitPlusTerminalBonusReserve) export(PP.benefit.ProfitPlusTotalInterest) +export(PP.benefit.TerminalBonus) +export(PP.benefit.TerminalBonus5Years) export(PP.benefit.TerminalBonus5YearsProRata) export(PP.calculate.RateOnBase) export(PP.calculate.RateOnBaseMin0) @@ -42,7 +46,7 @@ export(PP.rate.interestProfitPlusGuarantee) export(PP.rate.riskProfit) export(PP.rate.sumProfit) export(PP.rate.terminalBonus) -export(PP.rate.terminalBonusFundRatio) +export(PP.rate.terminalBonusFund) export(PP.rate.totalInterest) export(PP.rate.totalInterest2) export(ProfitParticipation) diff --git a/R/InsuranceParameters.R b/R/InsuranceParameters.R index efe7da56a640eb8f0cb0186a1524f653e3878cce..0baa3360bc8d36f416bfce78f3f6b0d49824c239 100644 --- a/R/InsuranceParameters.R +++ b/R/InsuranceParameters.R @@ -162,7 +162,7 @@ InsuranceContract.ParameterDefaults = list( expenseProfitRate = NULL, sumProfitRate = NULL, terminalBonusRate = NULL, - terminalBonusQuote = 0, + terminalBonusFundRate = NULL, profitParticipationScheme = NULL, # Gewinnbeteiligungssystem (object of class Profit Participation) profitComponents = c("interest", "risk", "expense", "sum", "terminal"), diff --git a/R/ProfitParticipation.R b/R/ProfitParticipation.R index fbbdff869bb7cd184b9975fa4b83af68e6fe340f..ba501ac009ee9aeeba1cbcc6e991a8ad09516432 100644 --- a/R/ProfitParticipation.R +++ b/R/ProfitParticipation.R @@ -36,7 +36,8 @@ ProfitParticipation = R6Class( getExpenseProfitBase = PP.base.sumInsured, getSumProfitBase = PP.base.sumInsured, getTerminalBonusBase = PP.base.sumInsured, - + getTerminalBonusFundBase = PP.base.totalProfitAssignment, + #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # Profit rates for the various types of profit # Can / shall be overridden in child classes that use other schemes! @@ -46,7 +47,9 @@ ProfitParticipation = R6Class( getExpenseProfitRate = PP.rate.expenseProfit, getSumProfitRate = PP.rate.sumProfit, getTerminalBonusRate = PP.rate.terminalBonus, - + getTerminalBonusFundRate= PP.rate.terminalBonusFund, + + getInterestOnProfits = PP.rate.totalInterest, @@ -61,6 +64,7 @@ ProfitParticipation = R6Class( n = length(terminalBonusAccount) terminalBonusAccount * 1/(1.07) ^ ((n - 1):0) }, + calculateTerminalBonusFund = PP.calculate.RateOnBase, #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # Calculations of the assigned profit amounts, based on the bases and @@ -144,7 +148,7 @@ ProfitParticipation = R6Class( # profitRates # 2) Contract can override individual rates (either for calendar years or contract years): # guaranteedInterest, interestProfitRate, totalInterest, mortalityProfitRate, - # expenseProfitRate, sumProfitRate, terminalBonusRate, terminalBonusFundRatio + # expenseProfitRate, sumProfitRate, terminalBonusRate, terminalBonusFundRate # 3) Explicit function arguments (either for calendar years or contract years). # 4) Any missing values will be taken from the last given year startYear = year(params$ContractData$contractClosing); @@ -156,7 +160,7 @@ ProfitParticipation = R6Class( "guaranteedInterest", "interestProfitRate", "totalInterest", "interestProfitRate2", "totalInterest2", "mortalityProfitRate", "expenseProfitRate", "expenseProfitRate_premiumfree", "sumProfitRate", - "terminalBonusRate", "terminalBonusFundRatio") + "terminalBonusRate", "terminalBonusFundRate") rates = data.frame(matrix(ncol = length(columns), nrow = length(years), dimnames = list(years = years, rates = columns))) rates$year = years; @@ -240,7 +244,6 @@ ProfitParticipation = R6Class( } else { waitingFactor = 1; } - rates = self$setupRates(params = params, values = values, ...) intBase = self$Functions$getInterestProfitBase(rates = rates, params = params, values = values); @@ -289,6 +292,7 @@ ProfitParticipation = R6Class( totalProfit = c(0) ); + # res = self$Functions$calculateInterestOnProfit(base = sumBase, rate = sumRate, waiting = waitingFactor, rates = rates, params = params, values = values); prev = 0; for (i in 1:nrow(res)) { res[i,"interestOnProfit"] = res[i,"interestOnProfitRate"] * prev; @@ -297,7 +301,7 @@ ProfitParticipation = R6Class( prev = res[i,"totalProfit"]; } - + #### 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); @@ -315,6 +319,22 @@ ProfitParticipation = R6Class( terminalBonusReserve = c(terminalBonusReserves) ) + #### 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); + TBFBonus = self$Functions$calculateTerminalBonusFund(res, base = TBFBase, rate = TBFRate, waiting = waitingFactor, rates = rates, params = params, values = values); + regularBonus = res[,"totalProfitAssignment"] - TBFBonus + + res = cbind( + res, + TBFBase = c(TBFBase), + TBFRate = c(TBFRate), + TBFAssignment = c(TBFBonus), + regularBonusAssignment = regularBonus, + TBF = cumsum(TBFBonus), + regularBonus = cumsum(regularBonus) + ) + survival = self$Functions$calculateSurvivalBenefit(res, rates = rates, params = params, values = values); @@ -362,10 +382,15 @@ ProfitParticipation = R6Class( toremove = c(toremove, grep("^sum", cnames)); } if (!"terminal" %in% params$ProfitParticipation$profitComponents) { - toremove = c(toremove, - grep("^terminal", cnames), - grep("^.*TerminalBonus$", cnames) - ); + 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] diff --git a/R/ProfitParticipation_Functions.R b/R/ProfitParticipation_Functions.R index 6660b23126c2695baf5075ba430e5422a0e63c7a..ce407d695bc44085e812d11db9e0268d6c6914f0 100644 --- a/R/ProfitParticipation_Functions.R +++ b/R/ProfitParticipation_Functions.R @@ -17,11 +17,11 @@ shiftBy = function(rate, n = 1) { res = c(rep(0, n), head(rate, -n)) names(res) = nm res - + } ##########################################################################m## -# Calculation bases for the various types of profit #### +# Calculation bases for the various types of profit #### ##########################################################################m## #' @describeIn ProfitParticipationFunctions @@ -80,10 +80,15 @@ PP.base.ZillmerRiskPremium = function(rates, params, values, ...) { #' Basis for expense/sum profit: sum insured #' @export PP.base.sumInsured = function(rates, params, values, ...) { - params$ContractData$sumInsured + params$ContractData$sumInsured }; - +#' @describeIn ProfitParticipationFunctions +#' Basis for Terminal Bonus Fund Assignment: total profit assignment of the year +#' @export +PP.base.totalProfitAssignment = function(res, ...) { + res[,"totalProfitAssignment"] +} #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -94,41 +99,41 @@ PP.base.sumInsured = function(rates, params, values, ...) { #' Returns the array of interest profit rates (keyed by year) #' @export PP.rate.interestProfit = function(rates, ...) { - rates$interestProfitRate + rates$interestProfitRate }; #' @describeIn ProfitParticipationFunctions #' Returns the array of risk profit rates (keyed by year) #' @export PP.rate.riskProfit = function(rates, ...) { - rates$mortalityProfitRate + rates$mortalityProfitRate }; #' @describeIn ProfitParticipationFunctions #' Returns the array of expense profit rates (keyed by year) #' @export PP.rate.expenseProfit = function(rates, ...) { - rates$expenseProfitRate + rates$expenseProfitRate }; #' @describeIn ProfitParticipationFunctions #' Returns the array of sum profit rates (keyed by year) #' @export PP.rate.sumProfit = function(rates, ...) { - rates$sumProfitRate + rates$sumProfitRate }; #' @describeIn ProfitParticipationFunctions #' Returns the array of terminal bonus rates (keyed by year) #' @export PP.rate.terminalBonus = function(rates, ...) { - rates$terminalBonusRate + rates$terminalBonusRate }; #' @describeIn ProfitParticipationFunctions #' Returns the array of terminal bonus rates (keyed by year) as the terminal bonus fund ratio #' @export -PP.rate.terminalBonusFundRatio = function(rates, ...) { - rates$terminalBonusFundRatio +PP.rate.terminalBonusFund = function(rates, ...) { + rates$terminalBonusFundRate }; @@ -150,28 +155,28 @@ PP.rate.interestProfit2PlusGuarantee = function(rates, ...) { #' Rate for interest on past profits: total interest rate #' @export PP.rate.totalInterest = function(rates, ...) { - rates$totalInterest + rates$totalInterest }; #' @describeIn ProfitParticipationFunctions #' Rate for interest on past profits: second total interest rate #' @export PP.rate.totalInterest2 = function(rates, ...) { - rates$totalInterest2 + rates$totalInterest2 }; #' @describeIn ProfitParticipationFunctions #' Rate for interest on past profits: second interest profit rate (not including guaranteed interest), keyed by year #' @export PP.rate.interestProfit2 = function(rates, ...) { - rates$interestProfitRate2 + rates$interestProfitRate2 }; # TODO getTerminalBonusReserves = function(profits, rates, terminalBonus, terminalBonusAccount, params, values, ...) { - n = length(terminalBonusAccount) - terminalBonusAccount * 1/(1.07) ^ ((n - 1):0) + n = length(terminalBonusAccount) + terminalBonusAccount * 1/(1.07) ^ ((n - 1):0) }; @@ -185,28 +190,28 @@ getTerminalBonusReserves = function(profits, rates, terminalBonus, terminalBonus #' Calculate profit by a simple rate applied on the basis (with an optional waiting vector of values 0 or 1) #' @export PP.calculate.RateOnBase = function(base, rate, waiting, rates, params, values, ...) { - base * rate * waiting + base * rate * waiting }; #' @describeIn ProfitParticipationFunctions #' Calculate profit by a simple rate applied on the basis (with an optional waiting vector of values 0 or 1), bound below by 0 #' @export PP.calculate.RateOnBaseMin0 = function(base, rate, waiting, rates, params, values, ...) { - pmax(0, base * rate * waiting) + pmax(0, base * rate * waiting) }; #' @describeIn ProfitParticipationFunctions #' Calculate profit by a rate + guaranteed interest applied on the basis (with an optional waiting vector of values 0 or 1) #' @export PP.calculate.RatePlusGuaranteeOnBase = function(base, rate, waiting, rates, params, values, ...) { - base * (rate + rates$guaranteedInterest) * waiting + base * (rate + rates$guaranteedInterest) * waiting }; #' @describeIn ProfitParticipationFunctions #' 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) #' @export PP.calculate.RateOnBaseSGFFactor = function(base, rate, waiting, rates, params, values, ...) { - base * rate * waiting * (1 - rates$terminalBonusFundRatio) + base * rate * waiting * (1 - rates$terminalBonusFund) }; @@ -220,64 +225,86 @@ PP.calculate.RateOnBaseSGFFactor = function(base, rate, waiting, rates, params, #' Calculate survival benefit as total profit amount plus the terminal bonus reserve #' @export PP.benefit.ProfitPlusTerminalBonusReserve = function(profits, ...) { - profits[,"totalProfit"] + profits[,"terminalBonusReserve"] + profits[,"regularBonus"] + profits[,"TBF"] + profits[,"terminalBonusReserve"] }; #' @describeIn ProfitParticipationFunctions #' Calculate benefit as total profit accrued so far #' @export PP.benefit.Profit = function(profits, ...) { - profits[,"totalProfit"] + profits[,"regularBonus"] }; #' @describeIn ProfitParticipationFunctions #' Calculate accrued death benefit as total profit with (guaranteed) interest for one year #' @export PP.benefit.ProfitPlusGuaranteedInterest = function(profits, rates, ...) { - profits[,"totalProfit"] * (1 + rates$guaranteedInterest) + profits[,"regularBonus"] * (1 + rates$guaranteedInterest) }; #' @describeIn ProfitParticipationFunctions #' Calculate accrued death benefit as total profit with total interest (interest on profit rate) for one year #' @export PP.benefit.ProfitPlusTotalInterest = function(profits, rates, params, values) { - profits[,"totalProfit"] * (1 + profits[,"interestOnProfitRate"]) + profits[,"regularBonus"] * (1 + profits[,"interestOnProfitRate"]) }; #' @describeIn ProfitParticipationFunctions #' Calculate accrued benefit as total profit with total interest (interest on profit rate) for half a year #' @export PP.benefit.ProfitPlusHalfTotalInterest = function(profits, ...) { - profits[,"totalProfit"] * (1 + profits[,"interestOnProfitRate"]/2) + profits[,"regularBonus"] * (1 + profits[,"interestOnProfitRate"]/2) }; #' @describeIn ProfitParticipationFunctions #' Calculate death benefit as total profit with (guaranteed) interest for one year #' @export PP.benefit.ProfitPlusHalfGuaranteedInterest = function(profits, rates, ...) { - profits[,"totalProfit"] * (1 + rates$guaranteedInterest/2) + profits[,"regularBonus"] * (1 + rates$guaranteedInterest/2) }; #' @describeIn ProfitParticipationFunctions #' Calculate accrued benefit as total profit with interest for one year (min of guarantee and total interest) #' @export PP.benefit.ProfitPlusInterestMinGuaranteeTotal = function(profits, rates, ...) { - profits[,"totalProfit"] * (1 + pmin(rates$guaranteedInterest, rates$totalInterest)) + profits[,"regularBonus"] * (1 + pmin(rates$guaranteedInterest, rates$totalInterest)) }; #' @describeIn ProfitParticipationFunctions #' Calculate accrued benefit as total profit with interest for half a year (min of guarantee and total interest) #' @export PP.benefit.ProfitPlusHalfInterestMinGuaranteeTotal = function(profits, rates, ...) { - profits[,"totalProfit"] * (1 + pmin(rates$guaranteedInterest, rates$totalInterest)/2) + profits[,"regularBonus"] * (1 + pmin(rates$guaranteedInterest, rates$totalInterest)/2) +}; + +#' @describeIn ProfitParticipationFunctions +#' Calculate accrued benefit as regular profit, but used to cover initial Zillmerization +#' @export +PP.benefit.ProfitGuaranteeSupporting = function(profits, rates, params, values, ...) { + pmax(0, values$reserves[,"contractual"] + profits[,"regularBonus"] - pmax(0, values$reserves[,"contractual"])) }; #' @describeIn ProfitParticipationFunctions #' Calculate benefit from terminal bonus as 1/n parts of the terminal bonus reserve during the last 5 years #' @export PP.benefit.TerminalBonus5YearsProRata = function(profits, params, ...) { - n = params$ContractData$policyPeriod; - profits[, "terminalBonusReserve"] * (0:n)/n * ((0:n) >= max(10, n - 5)) + n = params$ContractData$policyPeriod; + (profits[, "terminalBonusReserve"] + profits[, "TBF"]) * (0:n)/n * ((0:n) >= max(10, n - 5)) +}; + +#' @describeIn ProfitParticipationFunctions +#' Terminal bonus is only paid out during the last 5 years of the contract (but never during the first 10 year) +#' @export +PP.benefit.TerminalBonus5Years = function(profits, params, ...) { + n = params$ContractData$policyPeriod; + (profits[, "terminalBonusReserve"] + profits[, "TBF"]) * ((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"] }; "dummy" diff --git a/man/ProfitParticipationFunctions.Rd b/man/ProfitParticipationFunctions.Rd index 1ffda3e1ab746e4322d29dcb0af301dbb25b81f6..544f91dcd1be489b280bba4e09d351e029ec9f1f 100644 --- a/man/ProfitParticipationFunctions.Rd +++ b/man/ProfitParticipationFunctions.Rd @@ -10,12 +10,13 @@ \alias{PP.base.meanContractualReserve} \alias{PP.base.ZillmerRiskPremium} \alias{PP.base.sumInsured} +\alias{PP.base.totalProfitAssignment} \alias{PP.rate.interestProfit} \alias{PP.rate.riskProfit} \alias{PP.rate.expenseProfit} \alias{PP.rate.sumProfit} \alias{PP.rate.terminalBonus} -\alias{PP.rate.terminalBonusFundRatio} +\alias{PP.rate.terminalBonusFund} \alias{PP.rate.interestProfitPlusGuarantee} \alias{PP.rate.interestProfit2PlusGuarantee} \alias{PP.rate.totalInterest} @@ -33,7 +34,10 @@ \alias{PP.benefit.ProfitPlusHalfGuaranteedInterest} \alias{PP.benefit.ProfitPlusInterestMinGuaranteeTotal} \alias{PP.benefit.ProfitPlusHalfInterestMinGuaranteeTotal} +\alias{PP.benefit.ProfitGuaranteeSupporting} \alias{PP.benefit.TerminalBonus5YearsProRata} +\alias{PP.benefit.TerminalBonus5Years} +\alias{PP.benefit.TerminalBonus} \title{Helper functions for profit participation} \usage{ PP.base.NULL(rates, params, values, ...) @@ -52,6 +56,8 @@ PP.base.ZillmerRiskPremium(rates, params, values, ...) PP.base.sumInsured(rates, params, values, ...) +PP.base.totalProfitAssignment(res, ...) + PP.rate.interestProfit(rates, ...) PP.rate.riskProfit(rates, ...) @@ -62,7 +68,7 @@ PP.rate.sumProfit(rates, ...) PP.rate.terminalBonus(rates, ...) -PP.rate.terminalBonusFundRatio(rates, ...) +PP.rate.terminalBonusFund(rates, ...) PP.rate.interestProfitPlusGuarantee(rates, ...) @@ -101,7 +107,13 @@ PP.benefit.ProfitPlusInterestMinGuaranteeTotal(profits, rates, ...) PP.benefit.ProfitPlusHalfInterestMinGuaranteeTotal(profits, rates, ...) +PP.benefit.ProfitGuaranteeSupporting(profits, rates, params, values, ...) + PP.benefit.TerminalBonus5YearsProRata(profits, params, ...) + +PP.benefit.TerminalBonus5Years(profits, params, ...) + +PP.benefit.TerminalBonus(profits, params, ...) } \description{ Various helper functions for the \code{ProfitParticipation} class that @@ -126,6 +138,8 @@ the rates and how the assigned profit is calculated. \item \code{PP.base.sumInsured}: Basis for expense/sum profit: sum insured +\item \code{PP.base.totalProfitAssignment}: Basis for Terminal Bonus Fund Assignment: total profit assignment of the year + \item \code{PP.rate.interestProfit}: Returns the array of interest profit rates (keyed by year) \item \code{PP.rate.riskProfit}: Returns the array of risk profit rates (keyed by year) @@ -136,7 +150,7 @@ the rates and how the assigned profit is calculated. \item \code{PP.rate.terminalBonus}: Returns the array of terminal bonus rates (keyed by year) -\item \code{PP.rate.terminalBonusFundRatio}: Returns the array of terminal bonus rates (keyed by year) as the terminal bonus fund ratio +\item \code{PP.rate.terminalBonusFund}: Returns the array of terminal bonus rates (keyed by year) as the terminal bonus fund ratio \item \code{PP.rate.interestProfitPlusGuarantee}: Rate for interest on past profits: total credited rate, but at least the guarantee @@ -172,6 +186,12 @@ the rates and how the assigned profit is calculated. \item \code{PP.benefit.ProfitPlusHalfInterestMinGuaranteeTotal}: Calculate accrued benefit as total profit with interest for half a year (min of guarantee and total interest) +\item \code{PP.benefit.ProfitGuaranteeSupporting}: Calculate accrued benefit as regular profit, but used to cover initial Zillmerization + \item \code{PP.benefit.TerminalBonus5YearsProRata}: Calculate benefit from terminal bonus as 1/n parts of the terminal bonus reserve during the last 5 years + +\item \code{PP.benefit.TerminalBonus5Years}: Terminal bonus is only paid out during the last 5 years of the contract (but never during the first 10 year) + +\item \code{PP.benefit.TerminalBonus}: Calculate benefit from terminal bonus (full bonus), either old-style terminal bonus reserve or Terminal Bonus Fund (TBF) }}