diff --git a/DESCRIPTION b/DESCRIPTION index 44a907e53bd8d3eadd6279d31727ae8e6146d8f8..b890141451a91e9ff9a5060faaf46bc2f21369b1 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: LifeInsuranceContracts Type: Package -Version: 0.0.2 -Date: 2020-09-14 +Version: 0.0.3 +Date: 2021-08-24 Title: Framework for Traditional Life Insurance Contracts Description: R6 classes to model traditional life insurance contracts like annuities, whole life insurances or endowments. Such life @@ -29,7 +29,8 @@ Imports: abind, stringr, methods, - rlang + rlang, + tidyr License: GPL (>= 2) RoxygenNote: 7.1.1 Collate: diff --git a/NAMESPACE b/NAMESPACE index 208dc1ab8c5a5aa6064f57c653a708b461288508..9cce71e8cd4085adfcf0fbac57a4cceaae829314 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -62,6 +62,7 @@ export(fallbackFields) export(fillFields) export(fillNAgaps) export(filterProfitRates) +export(freqCharge) export(head0) export(initializeCosts) export(isRegularPremiumContract) @@ -86,6 +87,7 @@ import(dplyr) import(openxlsx) import(scales) import(stringr) +import(tidyr) importFrom(abind,abind) importFrom(lubridate,"year<-") importFrom(lubridate,days) diff --git a/R/InsuranceParameters.R b/R/InsuranceParameters.R index 804ece4eb994c136201a395eae8d6856a81c0100..ef2d07a3bf3a491d1e1c475f46e2a37f6abdf57d 100644 --- a/R/InsuranceParameters.R +++ b/R/InsuranceParameters.R @@ -22,6 +22,7 @@ NULL #' @param type The cost type (alpha, Zillmer, beta, gamma, gamma_nopremiums, unitcosts) #' @param basis The basis fo which the cost rate is applied (default is SumInsured) #' @param frequency How often / during which period the cost is charged (once, PremiumPeriod, PremiumFree, PolicyPeriod, FullContract) +#' @param value The new cost value to set for the given type, basis and frequency #' #' @return The modified cost structure #' @@ -57,6 +58,9 @@ setCost = function(costs, type, basis = "SumInsured", frequency = "PolicyPeriod" #' @param gamma.paidUp Administration costs for paid-up contracts (relative to sum insured) #' @param gamma.premiumfree Administration costs for planned premium-free period (reltaive to sum insured) #' @param gamma.contract Administration costs for the whole contract period (relative to sum insured) +#' @param gamma.afterdeath Administration costs after the insured person has dies (for term-fix insurances) +#' @param gamma.fullcontract Administration costs for the full contract period, +#' even if the insured has already dies (for term-fix insurances) #' @param unitcosts Unit costs (absolute monetary amount, during premium period) #' @param unitcosts.PolicyPeriod Unit costs (absolute monetary amount, during full contract period) #' @@ -166,7 +170,7 @@ InsuranceContract.Values = list( profitParticipation = list() ); -# InsuranceContract.ParameterDefault ####################################### +# InsuranceContract.ParameterDefaults ####################################### #' Default parameters for the InsuranceContract class. A new contract will be #' pre-filled with these values, and values passed in the constructor (or with #' other setter functions) will override these values. @@ -378,7 +382,6 @@ InsuranceContract.Values = list( #' reported in the balance sheet reserves. Otherwise, a premium #' paid at the beginning of the period is added to the reserve at #' that time for balance-sheet purposes. -#' #' For regular premiums, the default is TRUE, i.e. the balance-sheet #' reserve at time $t$ does not include the premium paid at time #' $t$, but unearned premiums are included in the balance sheet @@ -420,7 +423,6 @@ InsuranceContract.Values = list( #' contracts (e.g. following similar risks) together. Profit #' participation rates are defined at the level of profit classes.} #' \item{\code{$profitRates}}{General, company-wide profit rates, key columns are year and profitClass} -#' #' \item{\code{$scenarios}}{profit participation scenarios (list of overridden parameters for each scenario)} #' } #' @@ -433,7 +435,6 @@ InsuranceContract.Values = list( #' } #' #' -#' #' @examples #' InsuranceContract.ParameterDefaults #' @export diff --git a/R/exportInsuranceContract_xlsx.R b/R/exportInsuranceContract_xlsx.R index 9c639facf8e028e5c4b5c50b1a60ac1f8d8e8b48..5e20f6cdfbc2a8740475706c15f335d236f2c1e5 100644 --- a/R/exportInsuranceContract_xlsx.R +++ b/R/exportInsuranceContract_xlsx.R @@ -3,6 +3,8 @@ #' @import openxlsx #' @import MortalityTables #' @import R6 +#' @import tidyr +#' @importFrom rlang .data NULL @@ -277,12 +279,14 @@ getContractBlockPremiums = function(contract) { #' @details Not to be called directly, but implicitly by the [InsuranceContract] object. #' Convert the array containing cost values like cashflows, present #' values, etc. (objects of dimension tx5x3) to a matrix with dimensions (tx15) +#' +#' #parameter costValues Cost definition data structure costValuesAsDF = function(costValues) { as.data.frame.table(costValues, responseName = "Value", stringsAsFactors = TRUE) %>% - mutate(Var4 = recode(Var4, "Erl." = "")) %>% - arrange(Var4, Var2, Var3, Var1) %>% - unite(costtype, Var2, Var3, Var4, sep = " ") %>% - pivot_wider(names_from = costtype, values_from = Value) %>% + mutate(Var4 = recode(.data$Var4, "Erl." = "")) %>% + arrange(.data$Var4, .data$Var2, .data$Var3, .data$Var1) %>% + unite(.data$costtype, .data$Var2, .data$Var3, .data$Var4, sep = " ") %>% + pivot_wider(names_from = .data$costtype, values_from = .data$Value) %>% mutate(Var1 = NULL) } @@ -346,8 +350,8 @@ exportContractDataTable = function(wb, sheet, contract, ccol = 1, crow = 1, styl tmp = contractValues %>% mutate(`Initial Capital` = additional_capital) %>% select( - Vertragsteil = .data$ID, Beginn = `Start of Contract`, Tarif = .data$Tariff, .data$`Sum insured`, - `Initial Capital`, + Vertragsteil = .data$ID, Beginn = .data$`Start of Contract`, Tarif = .data$Tariff, .data$`Sum insured`, + .data$`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), diff --git a/man/InsuranceContract.ParameterDefaults.Rd b/man/InsuranceContract.ParameterDefaults.Rd index aee0e1f4126cd66a803284cb45ac956520fad62e..6c719aba7612ccfc68bd9e195c997cfc8ddfc9b3 100644 --- a/man/InsuranceContract.ParameterDefaults.Rd +++ b/man/InsuranceContract.ParameterDefaults.Rd @@ -83,7 +83,7 @@ value is only used by the parent block (i.e. $t=0$ of the child is aligned with $t=blockStart$ of the parent block.} \item{\code{$premiumPayments}}{Whether premiums are paid in advance (default) or arrears. Value is of type \link{PaymentTimeEnum} -with possible values "in advance" and 'in arrears"} +with possible values "in advance" and "in arrears"} \item{\code{$benefitPayments}}{Whether recurring benefits (e.g. annuities) are paid in advance (default) or arrears. Value is of type \link{PaymentTimeEnum} with possible values "in advance" and @@ -215,16 +215,15 @@ surrender is linear in t or follows the NPV of an annuity} \item{\code{$useUnearnedPremiums}}{Whether unearned premiums should be reported in the balance sheet reserves. Otherwise, a premium paid at the beginning of the period is added to the reserve at -that time for balance-sheet purposes.\preformatted{ For regular premiums, the default is TRUE, i.e. the balance-sheet - reserve at time $t$ does not include the premium paid at time - $t$, but unearned premiums are included in the balance sheet - reserves. For single-premium contracts, there are no "unearned" - premiums, but the initial single premium is added to the reserve - immediately for balance-sheet purposes. In particular, the - balance sheet reserve at time $t=0$ is not 0, but the - premium paid. In turn, no unearned premiums are applied.\} -} - +that time for balance-sheet purposes. +For regular premiums, the default is TRUE, i.e. the balance-sheet +reserve at time $t$ does not include the premium paid at time +$t$, but unearned premiums are included in the balance sheet +reserves. For single-premium contracts, there are no "unearned" +premiums, but the initial single premium is added to the reserve +immediately for balance-sheet purposes. In particular, the +balance sheet reserve at time $t=0$ is not 0, but the +premium paid. In turn, no unearned premiums are applied.} } } @@ -258,9 +257,8 @@ fund, but "old" Austrian terminal bonus)} is assigned to. Profit classes are used to bundle similar contracts (e.g. following similar risks) together. Profit participation rates are defined at the level of profit classes.} -\item{\code{$profitRates}}{General, company-wide profit rates, key columns are year and profitClass}\preformatted{\\item\{\code{$scenarios}\}\{profit participation scenarios (list of overridden parameters for each scenario)\} -} - +\item{\code{$profitRates}}{General, company-wide profit rates, key columns are year and profitClass} +\item{\code{$scenarios}}{profit participation scenarios (list of overridden parameters for each scenario)} } } diff --git a/man/InsuranceTarif.Rd b/man/InsuranceTarif.Rd index 4e960e9b83074c93115be2a3f89d9c691117b986..7798d27cb79a8e11db5fac0ab28092bc15a63b87 100644 --- a/man/InsuranceTarif.Rd +++ b/man/InsuranceTarif.Rd @@ -896,7 +896,7 @@ Not to be called directly, but implicitly by the \link{InsuranceContract} object \if{latex}{\out{\hypertarget{method-getBalanceSheetReserveFactor}{}}} \subsection{Method \code{getBalanceSheetReserveFactor()}}{ Calculate the (linear) interpolation factors for the balance -sheet reserve (Dec. 31) between the yearly contract clowing dates +sheet reserve (Dec. 31) between the yearly contract closing dates \subsection{Usage}{ \if{html}{\out{<div class="r">}}\preformatted{InsuranceTarif$getBalanceSheetReserveFactor(method, params, years = 1)}\if{html}{\out{</div>}} } diff --git a/man/costValuesAsDF.Rd b/man/costValuesAsDF.Rd index 3820bb9adc0c1195bd8bb4360ec89bf37f5eb10b..18c20ba7bd936776255df1381921bf33fd3183e1 100644 --- a/man/costValuesAsDF.Rd +++ b/man/costValuesAsDF.Rd @@ -13,4 +13,6 @@ Convert the cost values array to a tx15 matrix Not to be called directly, but implicitly by the \link{InsuranceContract} object. Convert the array containing cost values like cashflows, present values, etc. (objects of dimension tx5x3) to a matrix with dimensions (tx15) + +#parameter costValues Cost definition data structure } diff --git a/man/freqCharge.Rd b/man/freqCharge.Rd new file mode 100644 index 0000000000000000000000000000000000000000..0cd78aae1abf5a3714bef4dc816633430aaa62e6 --- /dev/null +++ b/man/freqCharge.Rd @@ -0,0 +1,38 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/HelperFunctions.R +\name{freqCharge} +\alias{freqCharge} +\title{Defines a frequency charge (surcharge for monthly/quarterly/semiannual) premium payments #' +Tariffs are typically calculated with yearly premium installments. When +premiums are paid more often then one a year (in advance), the insurance +receives part of the premium later (or not at all in case of death), so a +surcharge for premium payment frequencies higher than yearly is applied to +the premium, typically in the form of a percentage of the premium.} +\usage{ +freqCharge(monthly = 0, quarterly = 0, semiannually = 0, yearly = 0) +} +\arguments{ +\item{monthly}{Surcharge for monthly premium payments} + +\item{quarterly}{Surcharge for quarterly premium payments} + +\item{semiannually}{Surcharge for semi-annual premium payments} + +\item{yearly}{Surcharge for yearly premium payments (optiona, default is no surcharge)} +} +\description{ +This function generates the internal data structure to define surcharges for +monthly, quarterly and semiannual premium payments. The given surcharges can +be either given as percentage points (e.g. 1.5 means 1.5\% = 0.015) or as +fractions of 1 (i.e. 0.015 also means 1.5\% surcharge). The heuristics applied +to distinguish percentage points and fractions is that all values larger than 0.1 +are understood as percentage points and values 0.1 and lower are understood +as fractions of 1. +As a consequence, a frequency charge of 10\% or more MUST be given as percentage points. +} +\details{ +Currently, the frequency charges are internally represented as a named list, +\code{list("1" = 0, "2" = 0.01, "4" = 0.02, "12" = 0.03)}, but that might +change in the future, so it is advised to use this function rather than +explicitly using the named list in your code. +} diff --git a/man/initializeCosts.Rd b/man/initializeCosts.Rd index c464bbe858522e54889869214c81706d63e3a5a8..0c3bed60a72edd6128c642b793f6da61b392e77a 100644 --- a/man/initializeCosts.Rd +++ b/man/initializeCosts.Rd @@ -36,6 +36,11 @@ initializeCosts( \item{gamma.contract}{Administration costs for the whole contract period (relative to sum insured)} +\item{gamma.afterdeath}{Administration costs after the insured person has dies (for term-fix insurances)} + +\item{gamma.fullcontract}{Administration costs for the full contract period, +even if the insured has already dies (for term-fix insurances)} + \item{unitcosts}{Unit costs (absolute monetary amount, during premium period)} \item{unitcosts.PolicyPeriod}{Unit costs (absolute monetary amount, during full contract period)} diff --git a/man/setCost.Rd b/man/setCost.Rd index 95b1c5cdf4dd4b9070f7779b282917abd2bb113d..840e7ad9928de177466956e729cac1b7a26d9752 100644 --- a/man/setCost.Rd +++ b/man/setCost.Rd @@ -14,6 +14,8 @@ setCost(costs, type, basis = "SumInsured", frequency = "PolicyPeriod", value) \item{basis}{The basis fo which the cost rate is applied (default is SumInsured)} \item{frequency}{How often / during which period the cost is charged (once, PremiumPeriod, PremiumFree, PolicyPeriod, FullContract)} + +\item{value}{The new cost value to set for the given type, basis and frequency} } \value{ The modified cost structure