diff --git a/R/InsuranceContract.R b/R/InsuranceContract.R index 4a938bd6b5473ea2008ae010e3b266d05ffd6494..a7a1a1d054580059894097ae4f2ddaf4d2b6fe16 100644 --- a/R/InsuranceContract.R +++ b/R/InsuranceContract.R @@ -518,6 +518,9 @@ InsuranceContract = R6Class( #' they no longer represent the actual contract state at these #' times. If values are not recalculated, the reserves at each #' time step represent the proper state at that point in time. + #' @param additionalCapital The capital that is added to the contract + #' (e.g. capital carried over from a previous contract) at the + #' premium calculation time. #' @param recalculatePremiums Whether the premiums should be recalculated #' at time \code{premiumCalculationTime} at all. #' @param recalculatePremiumSum Whether to recalculate the overall premium @@ -525,7 +528,7 @@ InsuranceContract = R6Class( #' @param history_comment The comment for the history snapshot entyr #' @param history_type The type (free-form string) to record in the history snapshot #' - calculateContract = function(calculate = "all", valuesFrom = 0, premiumCalculationTime = 0, preservePastPV = TRUE, recalculatePremiums = TRUE, recalculatePremiumSum = TRUE, history_comment = NULL, history_type = "Contract") { + calculateContract = function(calculate = "all", valuesFrom = 0, premiumCalculationTime = 0, preservePastPV = TRUE, additionalCapital = 0, recalculatePremiums = TRUE, recalculatePremiumSum = TRUE, history_comment = NULL, history_type = "Contract") { if (!is.null(self$blocks)) { for (b in self$blocks) { .args = as.list(match.call()[-1]) @@ -550,6 +553,10 @@ InsuranceContract = R6Class( ending = private$determineCashFlows(), t = valuesFrom); + if (additionalCapital > 0) { + self$values$cashFlows[as.character(premiumCalculationTime), "additional_capital"] = additionalCapital / self$values$ContractData$sumInsured + } + if (recalculatePremiumSum) { # Premium waiver: Premium sum is not affected by premium waivers, i.e. everything depending on the premium sum uses the original premium sum! self$Values$unitPremiumSum = private$determinePremiumSum(); diff --git a/R/InsuranceParameters.R b/R/InsuranceParameters.R index b812c52ce9710ca91007d3250d7283a06c5fe9f2..d2f36961e4934706477749dfe567b298ea7ebad6 100644 --- a/R/InsuranceParameters.R +++ b/R/InsuranceParameters.R @@ -153,6 +153,9 @@ InsuranceContract.Values = list( #' contracts with multiple parts, e.g. dynamic increases), #' default = "Hauptvertrag"} #' \item{\code{$sumInsured}}{Sum insured, default = 100,000} +#' \item{\code{$initialCapital}}{Reserve/Capital that is already available +#' at contract inception, e.g. from a previous contract. No tax +#' or acquisition costs are applied to this capital.} #' \item{\code{$YOB}}{Year of birth of the insured, used to determine the #' age for the application of the mortality table} #' \item{\code{$age}}{Age of the insured} @@ -376,6 +379,7 @@ InsuranceContract.ParameterDefaults = list( deferralPeriod = 0, # deferral period for annuities guaranteedPeriod = 0, # guaranteed payments for annuities contractClosing = NULL, # Contract closing date (day/month is relevant for balance sheet reserves) + initialCapital = 0, blockStart = 0, # When the current tariff block starts (main block starts a 0, dynamic increases start later!), only used by the parent block (i.e. t=0 of child is aligned with t=blockStart of parent) premiumPayments = "in advance", # premium payments in advance or arrears diff --git a/R/InsuranceTarif.R b/R/InsuranceTarif.R index c24d067d154cddc061e59a9cb7596297db97d73a..afd915c3ed531423215dac5c401a10a65ac0301c 100644 --- a/R/InsuranceTarif.R +++ b/R/InsuranceTarif.R @@ -511,6 +511,7 @@ InsuranceTarif = R6Class( cf = data.frame( premiums_advance = zeroes, premiums_arrears = zeroes, + additional_capital = zeroes, guaranteed_advance = zeroes, guaranteed_arrears = zeroes, survival_advance = zeroes, @@ -523,6 +524,7 @@ InsuranceTarif = R6Class( row.names = ages - age ); + cf$additional_capital = pad0(params$ContractData$initialCapital / params$ContractData$sumInsured, cflen) # Premiums: if (!params$ContractState$premiumWaiver) { premiums = self$getPremiumCF(len = cflen, params = params, values = values) @@ -624,6 +626,7 @@ InsuranceTarif = R6Class( values$cashFlows$premiums_advance, values$cashFlows$premiums_arrears, m = params$ContractData$premiumFrequency, mCorrection = premiumFreqCorr, v = v), + additional_capital = calculatePVSurvival(px, qx, values$cashFlows$additional_capital, 0, v = v), guaranteed = calculatePVGuaranteed( values$cashFlows$guaranteed_advance, values$cashFlows$guaranteed_arrears, m = params$ContractData$benefitFrequency, mCorrection = benefitFreqCorr, @@ -701,7 +704,8 @@ InsuranceTarif = R6Class( # of the sumInsured (in cashFlowsBasic) for non-constant sums insured. # So here, we don't need to multiply with values$cashFlowsBasic$sumInsured! propGP = c("premiums_advance", "premiums_arrears"); - propSI = c("guaranteed_advance", "guaranteed_arrears", + propSI = c("additional_capital", + "guaranteed_advance", "guaranteed_arrears", "survival_advance", "survival_arrears", "death_SumInsured", "death_PremiumFree", "disease_SumInsured"); propPS = c("death_GrossPremium", "death_Refund_past"); @@ -744,8 +748,8 @@ InsuranceTarif = R6Class( pv[,c("guaranteed", "survival", "death_SumInsured", "disease_SumInsured", "death_PremiumFree")] = pv[,c("guaranteed", "survival", "death_SumInsured", "disease_SumInsured", "death_PremiumFree")] * params$ContractData$sumInsured; pv[,c("death_GrossPremium", "death_Refund_past", "death_Refund_future")] = pv[,c("death_GrossPremium", "death_Refund_past", "death_Refund_future")] * values$premiums[["gross"]] * params$ContractData$premiumRefund; - pv[,c("benefits", "benefitsAndRefund", "alpha", "Zillmer", "beta", "gamma", "gamma_nopremiums", "unitcosts")] = - pv[,c("benefits", "benefitsAndRefund", "alpha", "Zillmer", "beta", "gamma", "gamma_nopremiums", "unitcosts")] * params$ContractData$sumInsured; + pv[,c("benefits", "additional_capital", "benefitsAndRefund", "alpha", "Zillmer", "beta", "gamma", "gamma_nopremiums", "unitcosts")] = + pv[,c("benefits", "additional_capital", "benefitsAndRefund", "alpha", "Zillmer", "beta", "gamma", "gamma_nopremiums", "unitcosts")] * params$ContractData$sumInsured; # Sum all death-related payments to "death" and remove the death_SumInsured column pv[,"death_SumInsured"] = pv[,"death_SumInsured"] + pv[,"death_GrossPremium"] @@ -813,6 +817,7 @@ InsuranceTarif = R6Class( ); coeff[["Premium"]][["benefits"]][["premiums"]] = 1; + coeff[["SumInsured"]][["benefits"]][["additional_capital"]] = -1; # Costs proportional to NetPremium introduce a non-linearity, as the NP is not available when the gross premium is calculated # => the corresponding costs PV is included in the coefficient! @@ -883,7 +888,7 @@ InsuranceTarif = R6Class( "unit.net" = 0, "unit.Zillmer" = 0, "unit.gross" = 0, "net" = 0, "Zillmer" = 0, "gross" = 0, "unitcost" = 0, "written_yearly" = 0, - "written_beforetax" = 0, "tax" = 0, "written" = 0); + "written_beforetax" = 0, "tax" = 0, "written" = 0, "additional_capital" = 0); coefficients = list("gross" = c(), "Zillmer" = c(), "net" = c()); # Get the present values of the premiums, claims and costs at time 'premiumCalculationTime' (where the premium is to be calculated) @@ -895,6 +900,7 @@ InsuranceTarif = R6Class( return(list("premiums" = values$premiums, "coefficients" = coefficients)) } + values$premiums["additional_capital"] = values$cashFlows[t, "additional_capital"] * sumInsured # net, gross and Zillmer premiums are calculated from the present values using the coefficients on each present value as described in the formulas document coeff = self$getPremiumCoefficients("gross", pv * 0, pvCost * 0, premiums = values$premiums, params = params, values = values, premiumCalculationTime = premiumCalculationTime) diff --git a/R/exportInsuranceContract_xlsx.R b/R/exportInsuranceContract_xlsx.R index 2416af2f3ab69491af638578c8054b4b014a516a..2d4b6fdf75a18f188033ed544a476ef09c5705f6 100644 --- a/R/exportInsuranceContract_xlsx.R +++ b/R/exportInsuranceContract_xlsx.R @@ -131,6 +131,7 @@ labelsReplace = function(labels) { # Cash Flows labels[labels == "premiums_advance"] = "Pr\u00e4m. vorsch."; labels[labels == "premiums_arrears"] = "Pr\u00e4m. nachsch."; + labels[labels == "additional_capital"] = "Einschuss"; labels[labels == "guaranteed_advance"] = "Gar. vorsch."; labels[labels == "guaranteed_arrears"] = "Gar. nachsch."; labels[labels == "survival_advance"] = "Erl. vorsch."; @@ -317,19 +318,20 @@ exportContractDataTable = function(wb, sheet, contract, ccol = 1, crow = 1, styl addStyle(wb, sheet, style = createStyle(valign = "top"), rows = 1:3, cols = 1:11, gridExpand = TRUE, stack = TRUE); crow = crow + 4; - # Values (parameters, premiums, etc.) of all blocks #### tmp = contractValues %>% + mutate(`Initial Capital` = contractPremiums$additional_capital) %>% select( - Vertragsteil = .data$ID, Beginn = .data$`Start of Contract`, Tarif = .data$Tariff, .data$`Sum insured`, + Vertragsteil = .data$ID, Beginn = `Start of Contract`, Tarif = .data$Tariff, .data$`Sum insured`, + `Initial Capital`, .data$`Mortality table`, .data$i, .data$Age, .data$`Policy duration`, .data$`Premium period`, .data$`Deferral period`, .data$`Guaranteed payments`) writeValuesTable(wb, sheet, values = setInsuranceValuesLabels(tmp), caption = "Basisdaten der Vertragsteile", crow = crow, ccol = 1, tableName = "BlocksBasicData", styles = styles) # Second column is start date of contract, fourth is sum insured, sixth is guaranteed interest rate - addStyle(wb, sheet, style = styles$currency0, rows = crow + 1 + (1:NROW(tmp)), cols = 4, gridExpand = TRUE, stack = TRUE); - addStyle(wb, sheet, style = styles$cost0, rows = crow + 1 + (1:NROW(tmp)), cols = 6, gridExpand = TRUE, stack = TRUE); + addStyle(wb, sheet, style = styles$currency0, rows = crow + 1 + (1:NROW(tmp)), cols = 4:5, gridExpand = TRUE, stack = TRUE); + addStyle(wb, sheet, style = styles$cost0, rows = crow + 1 + (1:NROW(tmp)), cols = 7, gridExpand = TRUE, stack = TRUE); crow = crow + NROW(tmp) + 2 + 2 # 2 rows for caption/table header, 2 rows padding