Skip to content
Snippets Groups Projects
Commit 3b7cd378 authored by Reinhold Kainhofer's avatar Reinhold Kainhofer
Browse files

Implement carry-over (additional/initial capital) from previous contracts

Initial capital from outside can now be given using the initialCapital parameter. No tax is applied on this carry-over.

No acquisition costs are adjusted.

Implements first part of issue #63
parent b63d2b20
No related branches found
No related tags found
No related merge requests found
......@@ -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();
......
......@@ -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
......
......@@ -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)
......
......@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment