The LifeInsuranceContracts package provides a full-featured framework to model classical life insurance contracts (non-unit linked). Mathematically, a general life insurance contracts can be defined using death and survival (and disability) benefit vectors to define the cash flows and calculate all premiums and reserves recursively. This powerful approach is taken by the LifeInsuranceContracts package to provide the most flexible contract modelling framework in R.
An insurance contract is described by three different objects;
While this might at first seem a bit complicated, it allows for very generic implementations of life insurance products and contracts.
To understand how the package implements life insurance contracts, let us look at a simple example:
Term Life Insurance
Costs:
Surrender Value:
library(magrittr)
library(MortalityTables)
#> Lade nötiges Paket: ggplot2
#> Lade nötiges Paket: scales
#> Lade nötiges Paket: pracma
#>
#> Attache Paket: 'pracma'
#> The following objects are masked from 'package:magrittr':
#>
#> and, mod, or
library(LifeInsuranceContracts)
mortalityTables.load("Austria_Census")
#> Loading table dataset 'Austria_Census'
Tarif.L71U = InsuranceTarif$new(
name = "L71-U",
type = "wholelife",
tarif = "DeathPlus - Short Term Life Insurance",
desc = "Term Life insurance (10 years) with constant sum insured and regular premiums",
policyPeriod = 10, premiumPeriod = 10, # premiumPeriod not needed, defaults to maturity
mortalityTable = mortalityTable.mixed(
table1 = mort.AT.census.2011.male, weight1 = 0.65,
table2 = mort.AT.census.2011.female, weight2 = 0.35
),
i = 0.005,
tax = 0.04,
costs = initializeCosts(alpha = 0.05, gamma = 0.01, gamma.paidUp = 0.01, unitcosts = 10),
surrenderValueCalculation = function(surrenderReserve, params, values) {
surrenderReserve * 0.9
}
);With the above product / tariff definition, it is now easy to instantiate one particular contract for this tariff. All we need to do is pass the tariff and the corresponding contract-specific information (mainly age, sum insured and contract closing) to the InsuranceContract object:
contract.L71U = InsuranceContract$new(
Tarif.L71U,
age = 35,
contractClosing = as.Date("2020-08-18"),
sumInsured = 100000);Just creating the contract will already calculate all cash flows, present values, premiums, reserves, etc. for the whole contract period. They can be accessed through the list.
A full list of all possible arguments can be found in the section All possible parameters and their default values.
Once the contract is created, all values can be accessed like this:
| x | |
|---|---|
| unit.net | 0.0010366 |
| unit.Zillmer | 0.0010366 |
| unit.gross | 0.0116337 |
| net | 103.6556459 |
| Zillmer | 103.6556459 |
| gross | 1163.3700119 |
| unitcost | 10.0000000 |
| written_yearly | 1220.3048124 |
| written_beforetax | 1173.3700119 |
| tax | 46.9348005 |
| written | 1220.3048124 |
| SumInsured | net | Zillmer | adequate | gamma | contractual | conversion | alphaRefund | reduction | PremiumsPaid | Surrender | PremiumFreeSumInsured | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 100000 | 0.00 | 0.00 | 0.00 | 0 | 0.00 | 0.00 | 0 | 0.00 | 1163.37 | 0.00 | 0.00 |
| 1 | 100000 | 33.87 | 33.87 | -491.08 | 0 | 33.87 | 33.87 | 0 | 33.87 | 2326.74 | 30.48 | 313.05 |
| 2 | 100000 | 63.18 | 63.18 | -404.73 | 0 | 63.18 | 63.18 | 0 | 63.18 | 3490.11 | 56.87 | 652.78 |
| 3 | 100000 | 87.30 | 87.30 | -323.27 | 0 | 87.30 | 87.30 | 0 | 87.30 | 4653.48 | 78.57 | 1023.64 |
| 4 | 100000 | 105.32 | 105.32 | -247.59 | 0 | 105.32 | 105.32 | 0 | 105.32 | 5816.85 | 94.79 | 1430.17 |
| 5 | 100000 | 116.17 | 116.17 | -178.78 | 0 | 116.17 | 116.17 | 0 | 116.17 | 6980.22 | 104.55 | 1877.91 |
| 6 | 100000 | 118.36 | 118.36 | -118.29 | 0 | 118.36 | 118.36 | 0 | 118.36 | 8143.59 | 106.52 | 2371.32 |
| 7 | 100000 | 109.96 | 109.96 | -68.07 | 0 | 109.96 | 109.96 | 0 | 109.96 | 9306.96 | 98.96 | 2910.44 |
| 8 | 100000 | 88.89 | 88.89 | -30.15 | 0 | 88.89 | 88.89 | 0 | 88.89 | 10470.33 | 80.00 | 3494.90 |
| 9 | 100000 | 53.00 | 53.00 | -6.71 | 0 | 53.00 | 53.00 | 0 | 53.00 | 11633.70 | 47.70 | 4123.97 |
| 10 | 100000 | 0.00 | 0.00 | 0.00 | 0 | 0.00 | 0.00 | 0 | 0.00 | 11633.70 | 0.00 | 0.00 |
Looking back at the definition of the tariff, the only spot where the type of insurance actually came in was the argument of the [InsuranceTarif] definition. This is one of the most important flags and is central to correct implementation of a tarif. On the other hand, all it does is to cause different vectors of survival, death and guaranteed cash flows. Once the cash flows are determined, the insurance contract and tariff does not need the insurance type any more.
In our term life example, the insurance contract’s unit cash flows are 1 for death benefits (both when premiums are paid and when the contract is paid-up) and for premiums in advance. All other cash flows (guaranteed, survival or disease cash flows) are zero. Similarly, the cost structure described above and implemented by the [LifeInsuranceContracts::initializeCosts()] function defines all cost cash flows, which are the starting point for all further calculations:
| premiums_advance | premiums_arrears | guaranteed_advance | guaranteed_arrears | survival_advance | survival_arrears | death_SumInsured | disease_SumInsured | death_GrossPremium | death_Refund_past | death_PremiumFree | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
| 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
| 2 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
| 3 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
| 4 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
| 5 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
| 6 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
| 7 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
| 8 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
| 9 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
| 10 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| alpha.SumInsured | Zillmer.SumInsured | beta.SumInsured | gamma.SumInsured | gamma_nopremiums.SumInsured | unitcosts.SumInsured | alpha.SumPremiums | Zillmer.SumPremiums | beta.SumPremiums | gamma.SumPremiums | gamma_nopremiums.SumPremiums | unitcosts.SumPremiums | alpha.GrossPremium | Zillmer.GrossPremium | beta.GrossPremium | gamma.GrossPremium | gamma_nopremiums.GrossPremium | unitcosts.GrossPremium | alpha.NetPremium | Zillmer.NetPremium | beta.NetPremium | gamma.NetPremium | gamma_nopremiums.NetPremium | unitcosts.NetPremium | alpha.Constant | Zillmer.Constant | beta.Constant | gamma.Constant | gamma_nopremiums.Constant | unitcosts.Constant | alpha.Reserve | Zillmer.Reserve | beta.Reserve | gamma.Reserve | gamma_nopremiums.Reserve | unitcosts.Reserve | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0.01 | 0.01 | 0 | 0.05 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | 0 | 0 | 0 | 0.01 | 0.01 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | 0 | 0 | 0 | 0.01 | 0.01 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 0 | 0 | 0 |
| 3 | 0 | 0 | 0 | 0.01 | 0.01 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 0 | 0 | 0 |
| 4 | 0 | 0 | 0 | 0.01 | 0.01 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 0 | 0 | 0 |
| 5 | 0 | 0 | 0 | 0.01 | 0.01 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 0 | 0 | 0 |
| 6 | 0 | 0 | 0 | 0.01 | 0.01 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 0 | 0 | 0 |
| 7 | 0 | 0 | 0 | 0.01 | 0.01 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 0 | 0 | 0 |
| 8 | 0 | 0 | 0 | 0.01 | 0.01 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 0 | 0 | 0 |
| 9 | 0 | 0 | 0 | 0.01 | 0.01 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 0 | 0 | 0 |
| 10 | 0 | 0 | 0 | 0.00 | 0.00 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Once these unit cash flows are set, all insurance contracts are handled identically. First, present values of each of the cash flows are calculated, from which the premiums can be calculated by the equivalence principle.
| premiums | guaranteed | survival | death_SumInsured | disease_SumInsured | death_GrossPremium | death_Refund_past | death_Refund_future | death_PremiumFree | benefits | benefitsAndRefund | alpha | Zillmer | beta | gamma | gamma_nopremiums | unitcosts | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 9.741123 | 0 | 0 | 0.0100972 | 0 | 0 | 0 | 0 | 0.0100972 | 0.0100972 | 0.0100972 | 0.0058169 | 0 | 0 | 0.0974112 | 0.0974112 | 0.0009741 |
| 1 | 8.791012 | 0 | 0 | 0.0094510 | 0 | 0 | 0 | 0 | 0.0094510 | 0.0094510 | 0.0094510 | 0.0000000 | 0 | 0 | 0.0879101 | 0.0879101 | 0.0008791 |
| 2 | 7.835850 | 0 | 0 | 0.0087541 | 0 | 0 | 0 | 0 | 0.0087541 | 0.0087541 | 0.0087541 | 0.0000000 | 0 | 0 | 0.0783585 | 0.0783585 | 0.0007836 |
| 3 | 6.875560 | 0 | 0 | 0.0079999 | 0 | 0 | 0 | 0 | 0.0079999 | 0.0079999 | 0.0079999 | 0.0000000 | 0 | 0 | 0.0687556 | 0.0687556 | 0.0006876 |
| 4 | 5.910060 | 0 | 0 | 0.0071794 | 0 | 0 | 0 | 0 | 0.0071794 | 0.0071794 | 0.0071794 | 0.0000000 | 0 | 0 | 0.0591006 | 0.0591006 | 0.0005910 |
| 5 | 4.939252 | 0 | 0 | 0.0062815 | 0 | 0 | 0 | 0 | 0.0062815 | 0.0062815 | 0.0062815 | 0.0000000 | 0 | 0 | 0.0493925 | 0.0493925 | 0.0004939 |
| 6 | 3.963017 | 0 | 0 | 0.0052915 | 0 | 0 | 0 | 0 | 0.0052915 | 0.0052915 | 0.0052915 | 0.0000000 | 0 | 0 | 0.0396302 | 0.0396302 | 0.0003963 |
| 7 | 2.981210 | 0 | 0 | 0.0041898 | 0 | 0 | 0 | 0 | 0.0041898 | 0.0041898 | 0.0041898 | 0.0000000 | 0 | 0 | 0.0298121 | 0.0298121 | 0.0002981 |
| 8 | 1.993626 | 0 | 0 | 0.0029554 | 0 | 0 | 0 | 0 | 0.0029554 | 0.0029554 | 0.0029554 | 0.0000000 | 0 | 0 | 0.0199363 | 0.0199363 | 0.0001994 |
| 9 | 1.000000 | 0 | 0 | 0.0015666 | 0 | 0 | 0 | 0 | 0.0015666 | 0.0015666 | 0.0015666 | 0.0000000 | 0 | 0 | 0.0100000 | 0.0100000 | 0.0001000 |
| 10 | 0.000000 | 0 | 0 | 0.0000000 | 0 | 0 | 0 | 0 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0 | 0 | 0.0000000 | 0.0000000 | 0.0000000 |
| alpha.SumInsured | Zillmer.SumInsured | beta.SumInsured | gamma.SumInsured | gamma_nopremiums.SumInsured | unitcosts.SumInsured | alpha.SumPremiums | Zillmer.SumPremiums | beta.SumPremiums | gamma.SumPremiums | gamma_nopremiums.SumPremiums | unitcosts.SumPremiums | alpha.GrossPremium | Zillmer.GrossPremium | beta.GrossPremium | gamma.GrossPremium | gamma_nopremiums.GrossPremium | unitcosts.GrossPremium | alpha.NetPremium | Zillmer.NetPremium | beta.NetPremium | gamma.NetPremium | gamma_nopremiums.NetPremium | unitcosts.NetPremium | alpha.Constant | Zillmer.Constant | beta.Constant | gamma.Constant | gamma_nopremiums.Constant | unitcosts.Constant | alpha.Reserve | Zillmer.Reserve | beta.Reserve | gamma.Reserve | gamma_nopremiums.Reserve | unitcosts.Reserve | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0.0974112 | 0.0974112 | 0 | 0.05 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 97.41123 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | 0 | 0 | 0 | 0.0879101 | 0.0879101 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 87.91012 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | 0 | 0 | 0 | 0.0783585 | 0.0783585 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 78.35850 | 0 | 0 | 0 | 0 | 0 | 0 |
| 3 | 0 | 0 | 0 | 0.0687556 | 0.0687556 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 68.75560 | 0 | 0 | 0 | 0 | 0 | 0 |
| 4 | 0 | 0 | 0 | 0.0591006 | 0.0591006 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 59.10060 | 0 | 0 | 0 | 0 | 0 | 0 |
| 5 | 0 | 0 | 0 | 0.0493925 | 0.0493925 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 49.39252 | 0 | 0 | 0 | 0 | 0 | 0 |
| 6 | 0 | 0 | 0 | 0.0396302 | 0.0396302 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 39.63017 | 0 | 0 | 0 | 0 | 0 | 0 |
| 7 | 0 | 0 | 0 | 0.0298121 | 0.0298121 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 29.81210 | 0 | 0 | 0 | 0 | 0 | 0 |
| 8 | 0 | 0 | 0 | 0.0199363 | 0.0199363 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 19.93626 | 0 | 0 | 0 | 0 | 0 | 0 |
| 9 | 0 | 0 | 0 | 0.0100000 | 0.0100000 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 10.00000 | 0 | 0 | 0 | 0 | 0 | 0 |
| 10 | 0 | 0 | 0 | 0.0000000 | 0.0000000 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0.00000 | 0 | 0 | 0 | 0 | 0 | 0 |
| x | |
|---|---|
| unit.net | 0.0010366 |
| unit.Zillmer | 0.0010366 |
| unit.gross | 0.0116337 |
| net | 103.6556459 |
| Zillmer | 103.6556459 |
| gross | 1163.3700119 |
| unitcost | 10.0000000 |
| written_yearly | 1220.3048124 |
| written_beforetax | 1173.3700119 |
| tax | 46.9348005 |
| written | 1220.3048124 |
The actual calculation of the premiums has to be in the order gross premium, Zillmer premiuem, then net premium. The reason for this particular order is that some tariffs have a gross premium refund in case of death. So to calculate the net premium, the gross premium is required.
The premiums allow the unit cash flows and present values to be converted to monetary terms (fields and ). Also, the reserves of the contract can be calculated.
| SumInsured | net | Zillmer | adequate | gamma | contractual | conversion | alphaRefund | reduction | PremiumsPaid | Surrender | PremiumFreeSumInsured | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 100000 | 0.00 | 0.00 | 0.00 | 0 | 0.00 | 0.00 | 0 | 0.00 | 1163.37 | 0.00 | 0.00 |
| 1 | 100000 | 33.87 | 33.87 | -491.08 | 0 | 33.87 | 33.87 | 0 | 33.87 | 2326.74 | 30.48 | 313.05 |
| 2 | 100000 | 63.18 | 63.18 | -404.73 | 0 | 63.18 | 63.18 | 0 | 63.18 | 3490.11 | 56.87 | 652.78 |
| 3 | 100000 | 87.30 | 87.30 | -323.27 | 0 | 87.30 | 87.30 | 0 | 87.30 | 4653.48 | 78.57 | 1023.64 |
| 4 | 100000 | 105.32 | 105.32 | -247.59 | 0 | 105.32 | 105.32 | 0 | 105.32 | 5816.85 | 94.79 | 1430.17 |
| 5 | 100000 | 116.17 | 116.17 | -178.78 | 0 | 116.17 | 116.17 | 0 | 116.17 | 6980.22 | 104.55 | 1877.91 |
| 6 | 100000 | 118.36 | 118.36 | -118.29 | 0 | 118.36 | 118.36 | 0 | 118.36 | 8143.59 | 106.52 | 2371.32 |
| 7 | 100000 | 109.96 | 109.96 | -68.07 | 0 | 109.96 | 109.96 | 0 | 109.96 | 9306.96 | 98.96 | 2910.44 |
| 8 | 100000 | 88.89 | 88.89 | -30.15 | 0 | 88.89 | 88.89 | 0 | 88.89 | 10470.33 | 80.00 | 3494.90 |
| 9 | 100000 | 53.00 | 53.00 | -6.71 | 0 | 53.00 | 53.00 | 0 | 53.00 | 11633.70 | 47.70 | 4123.97 |
| 10 | 100000 | 0.00 | 0.00 | 0.00 | 0 | 0.00 | 0.00 | 0 | 0.00 | 11633.70 | 0.00 | 0.00 |
Also, the premium composition into costs, risk premium, savings premium and other components is possible.
| charged | tax | loading.frequency | rebate.premium | rebate.partner | unitcosts | profit.advance | rebate.sum | charge.noMedicalExam | gross | gamma | beta | alpha | alpha.noZillmer | alpha.Zillmer | Zillmer | net | risk | premium.risk.actual | premium.risk.security | risk.disease | premium.risk.disease.actual | premium.risk.disease.security | savings | Zillmer.risk | Zillmer.risk.actual | Zillmer.risk.security | Zillmer.risk.disease | Zillmer.risk.disease.actual | Zillmer.risk.disease.security | Zillmer.savings | Zillmer.amortization | Zillmer.savings.real |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1220.3 | 46.93 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 1163.37 | 1000 | 0 | 59.71 | 59.71 | 0 | 103.66 | 103.66 | 69.96 | 69.96 | 0 | 0 | 0 | 0 | 33.70 | 69.96 | 69.96 | 0 | 0 | 0 | 0 | 33.70 | 0 | 33.70 |
| 1220.3 | 46.93 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 1163.37 | 1000 | 0 | 59.71 | 59.71 | 0 | 103.66 | 103.66 | 74.65 | 74.65 | 0 | 0 | 0 | 0 | 29.00 | 74.65 | 74.65 | 0 | 0 | 0 | 0 | 29.00 | 0 | 29.00 |
| 1220.3 | 46.93 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 1163.37 | 1000 | 0 | 59.71 | 59.71 | 0 | 103.66 | 103.66 | 79.97 | 79.97 | 0 | 0 | 0 | 0 | 23.68 | 79.97 | 79.97 | 0 | 0 | 0 | 0 | 23.68 | 0 | 23.68 |
| 1220.3 | 46.93 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 1163.37 | 1000 | 0 | 59.71 | 59.71 | 0 | 103.66 | 103.66 | 86.16 | 86.16 | 0 | 0 | 0 | 0 | 17.50 | 86.16 | 86.16 | 0 | 0 | 0 | 0 | 17.50 | 0 | 17.50 |
| 1220.3 | 46.93 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 1163.37 | 1000 | 0 | 59.71 | 59.71 | 0 | 103.66 | 103.66 | 93.39 | 93.39 | 0 | 0 | 0 | 0 | 10.27 | 93.39 | 93.39 | 0 | 0 | 0 | 0 | 10.27 | 0 | 10.27 |
| 1220.3 | 46.93 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 1163.37 | 1000 | 0 | 59.71 | 59.71 | 0 | 103.66 | 103.66 | 102.05 | 102.05 | 0 | 0 | 0 | 0 | 1.60 | 102.05 | 102.05 | 0 | 0 | 0 | 0 | 1.60 | 0 | 1.60 |
| 1220.3 | 46.93 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 1163.37 | 1000 | 0 | 59.71 | 59.71 | 0 | 103.66 | 103.66 | 112.61 | 112.61 | 0 | 0 | 0 | 0 | -8.95 | 112.61 | 112.61 | 0 | 0 | 0 | 0 | -8.95 | 0 | -8.95 |
| 1220.3 | 46.93 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 1163.37 | 1000 | 0 | 59.71 | 59.71 | 0 | 103.66 | 103.66 | 125.16 | 125.16 | 0 | 0 | 0 | 0 | -21.50 | 125.16 | 125.16 | 0 | 0 | 0 | 0 | -21.50 | 0 | -21.50 |
| 1220.3 | 46.93 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 1163.37 | 1000 | 0 | 59.71 | 59.71 | 0 | 103.66 | 103.66 | 139.81 | 139.81 | 0 | 0 | 0 | 0 | -36.16 | 139.81 | 139.81 | 0 | 0 | 0 | 0 | -36.16 | 0 | -36.16 |
| 1220.3 | 46.93 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 1163.37 | 1000 | 0 | 59.71 | 59.71 | 0 | 103.66 | 103.66 | 156.66 | 156.66 | 0 | 0 | 0 | 0 | -53.00 | 156.66 | 156.66 | 0 | 0 | 0 | 0 | -53.00 | 0 | -53.00 |
| 0.0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0.00 | 1000 | 0 | 59.71 | 59.71 | 0 | 103.66 | 103.66 | 0.00 | 0.00 | 0 | 0 | 0 | 0 | 0.00 | 0.00 | 0.00 | 0 | 0 | 0 | 0 | 0.00 | 0 | 0.00 |
As we see, the whole history and future of the contract is calculated as soon as it is created. It is, however, also possible to modify a contract later on, e.g. by stopping premium payments and converting it to a paid-up contract.
contract.L71U = contract.L71U$premiumWaiver(t = 5)
contract.L71U$Values$reserves %>% kable(digits=2)| SumInsured | net | Zillmer | adequate | gamma | contractual | conversion | alphaRefund | reduction | PremiumsPaid | Surrender | PremiumFreeSumInsured | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 100000.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0 | 0.00 | 1163.37 | 0.00 | 0.00 |
| 1 | 100000.00 | 33.87 | 33.87 | -491.08 | 0.00 | 33.87 | 33.87 | 0 | 33.87 | 2326.74 | 30.48 | 313.05 |
| 2 | 100000.00 | 63.18 | 63.18 | -404.73 | 0.00 | 63.18 | 63.18 | 0 | 63.18 | 3490.11 | 56.87 | 652.78 |
| 3 | 100000.00 | 87.30 | 87.30 | -323.27 | 0.00 | 87.30 | 87.30 | 0 | 87.30 | 4653.48 | 78.57 | 1023.64 |
| 4 | 100000.00 | 105.32 | 105.32 | -247.59 | 0.00 | 105.32 | 105.32 | 0 | 105.32 | 5816.85 | 94.79 | 1430.17 |
| 5 | 1877.91 | 11.80 | 11.80 | 104.55 | 92.75 | 104.55 | 104.55 | 0 | 104.55 | 5816.85 | 104.55 | 1877.91 |
| 6 | 1877.91 | 9.94 | 9.94 | 84.36 | 74.42 | 84.36 | 84.36 | 0 | 84.36 | 5816.85 | 84.36 | 1877.91 |
| 7 | 1877.91 | 7.87 | 7.87 | 63.85 | 55.98 | 63.85 | 63.85 | 0 | 63.85 | 5816.85 | 63.85 | 1877.91 |
| 8 | 1877.91 | 5.55 | 5.55 | 42.99 | 37.44 | 42.99 | 42.99 | 0 | 42.99 | 5816.85 | 42.99 | 1877.91 |
| 9 | 1877.91 | 2.94 | 2.94 | 21.72 | 18.78 | 21.72 | 21.72 | 0 | 21.72 | 5816.85 | 21.72 | 1877.91 |
| 10 | 1877.91 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0 | 0.00 | 5816.85 | 0.00 | 0.00 |
When prototyping a new product or creating marketing material, it is often needed to create tables of premiums, reserves, benefits or surrender values for different parameters (e.g. different ages, maturities and sums insured for the marketing department, or different guaranteed interest rates, mortality tables or costs for the product development group).
This can be easily done by the functions [contractGridPremium()] or [contractGrid()]. They take one argument , which gives the parameters for the axes of the table (more than two dimensions are possible!), while all other parameters are passed unchanged to [InsuranceContract$new()].
First, let us create a grid of premiums for different ages and maturities (for sum insured 100,000 Euro):
contractGridPremium(
axes = list(age = seq(20, 80, 5), policyPeriod = seq(5, 40, 5)),
tarif = Tarif.L71U,
contractClosing = as.Date("2020-08-18"),
sumInsured = 100000
)
#> policyPeriod
#> age 5 10 15 20 25 30 35
#> 20 1169.853 1168.075 1199.161 1240.469 1303.557 1410.318 1585.448
#> 25 1164.503 1168.336 1210.805 1275.666 1385.428 1565.480 1850.114
#> 30 1170.548 1183.146 1249.849 1362.728 1547.892 1840.607 2274.448
#> 35 1194.338 1220.305 1336.514 1527.142 1828.495 2275.137 2872.007
#> 40 1245.159 1297.609 1494.339 1805.337 2266.275 2882.249 3710.479
#> 45 1349.637 1435.423 1757.889 2235.825 2874.514 3733.287 4976.711
#> 50 1521.824 1657.738 2157.231 2824.729 3722.239 5021.749 6831.597
#> 55 1796.462 1993.474 2699.839 3649.608 5024.786 6940.017 9052.437
#> 60 2197.241 2439.539 3462.609 4943.919 7006.962 9282.412 10902.557
#> 65 2692.767 3078.238 4712.042 6987.466 9497.163 11284.095 11950.511
#> 70 3491.667 4280.494 6889.785 9767.724 11816.848 12581.046 12581.046
#> 75 5174.046 6676.763 10245.338 12786.202 13733.789 13733.789 13733.789
#> 80 8555.299 10940.868 14604.915 15971.380 15971.380 15971.380 15971.380
#> policyPeriod
#> age 40
#> 20 1862.300
#> 25 2271.977
#> 30 2854.210
#> 35 3674.550
#> 40 4909.681
#> 45 6708.446
#> 50 8827.783
#> 55 10556.502
#> 60 11506.771
#> 65 11950.511
#> 70 12581.046
#> 75 13733.789
#> 80 15971.380One can also pass more than two dimensions to the axes:
contractGridPremium(
axes = list(age = seq(20, 80, 10), policyPeriod = seq(10, 40, 10), sumInsured = c(10000, 50000, 100000)),
tarif = Tarif.L71U,
contractClosing = as.Date("2020-08-18")
)
#> , , sumInsured = 10000
#>
#> policyPeriod
#> age 10 20 30 40
#> 20 126.1675 133.4069 150.3918 195.5900
#> 30 127.6746 145.6328 193.4207 294.7810
#> 40 139.1209 189.8937 297.5849 500.3281
#> 50 175.1338 291.8329 511.5349 892.1383
#> 60 253.3139 503.7519 937.6012 1160.0371
#> 70 437.4094 986.1324 1267.4646 1267.4646
#> 80 1103.4468 1606.4980 1606.4980 1606.4980
#>
#> , , sumInsured = 50000
#>
#> policyPeriod
#> age 10 20 30 40
#> 20 589.2374 625.4344 710.3591 936.3501
#> 30 596.7732 686.5640 925.5037 1432.3049
#> 40 654.0047 907.8685 1446.3243 2460.0403
#> 50 834.0689 1417.5647 2516.0746 4419.0915
#> 60 1224.9697 2477.1596 4646.4058 5758.5857
#> 70 2145.4472 4889.0622 6295.7230 6295.7230
#> 80 5475.6342 7990.8901 7990.8901 7990.8901
#>
#> , , sumInsured = 100000
#>
#> policyPeriod
#> age 10 20 30 40
#> 20 1168.075 1240.469 1410.318 1862.300
#> 30 1183.146 1362.728 1840.607 2854.210
#> 40 1297.609 1805.337 2882.249 4909.681
#> 50 1657.738 2824.729 5021.749 8827.783
#> 60 2439.539 4943.919 9282.412 11506.771
#> 70 4280.494 9767.724 12581.046 12581.046
#> 80 10940.868 15971.380 15971.380 15971.380One can use any of the parameters of the [InsuranceContract$new()] call in the argument, even the or parameters. This means that one can create tables comparing different tariffs, or showing the effect of different life tables.
In the following example, we use the tarif , but instead of the unisex table (mixed 65:35 from male:female tables), we use the male mortality tables of the Austrian census from 1870 to 2011 (with a contract period of 10 years fixed, and varying ages):
contractGridPremium(
axes = list(mortalityTable = mort.AT.census["m", ], age = seq(20, 80, 10)),
tarif = Tarif.L71U,
sumInsured = 100000,
contractClosing = as.Date("2020-08-18")
)
#> age
#> mortalityTable 20 30 40 50 60 70
#> ÖVSt 1868/71 M 2212.172 2370.833 2913.478 4059.368 7022.578 14017.657
#> ÖVSt 1879/82 M 2147.026 2335.900 2825.171 3951.679 6608.802 13409.890
#> ÖVSt 1889/92 M 2009.219 2205.402 2734.159 3838.403 6529.774 13236.981
#> ÖVSt 1899/1902 M 1848.012 2086.656 2645.843 3759.487 6311.541 12602.831
#> ÖVSt 1909/12 M 1775.956 2032.367 2578.437 3713.325 6278.540 12182.859
#> ÖVSt 1930/33 M 1555.504 1705.504 2130.348 3115.449 5360.127 10852.444
#> ÖVSt 1949/51 M 1361.781 1427.295 1765.242 2769.684 4846.955 9758.327
#> ÖVSt 1959/61 M 1332.548 1376.032 1632.237 2606.202 4854.636 9525.460
#> ÖVSt 1970/72 M 1323.656 1390.671 1683.444 2475.901 4785.257 9986.520
#> ÖVSt 1980/82 M 1291.107 1329.127 1646.102 2430.469 4109.816 8803.434
#> ÖVSt 1990/92 M 1242.549 1282.667 1528.445 2127.950 3654.002 7122.623
#> ÖVSt 2000/02 M 1214.154 1231.645 1426.524 1923.090 2976.936 5910.656
#> ÖVSt 2010/2012 M 1186.464 1201.235 1334.159 1773.809 2725.250 4841.859
#> age
#> mortalityTable 80
#> ÖVSt 1868/71 M 28131.00
#> ÖVSt 1879/82 M 27353.08
#> ÖVSt 1889/92 M 26292.55
#> ÖVSt 1899/1902 M 24700.31
#> ÖVSt 1909/12 M 24136.69
#> ÖVSt 1930/33 M 22882.25
#> ÖVSt 1949/51 M 20655.13
#> ÖVSt 1959/61 M 19874.48
#> ÖVSt 1970/72 M 19725.83
#> ÖVSt 1980/82 M 18825.90
#> ÖVSt 1990/92 M 16067.46
#> ÖVSt 2000/02 M 13821.41
#> ÖVSt 2010/2012 M 11904.62All possible parameters of an insurance contract are stored in sub-lists of a a structure [InsuranceContract.Parameters]. If not provided by the call to [InsuranceContract$new()], the values will be taken from either the [InsuranceTariff]’s default parameters, the ProfitParticipation’s default parameters or the global defaults in the [InsuranceContract.ParameterDefault]. The cascade or parameters is (from top to bottom):
str(InsuranceContract.ParameterDefaults)
#> List of 8
#> $ ContractData :List of 23
#> ..$ id : chr "Hauptvertrag"
#> ..$ sumInsured : num 100000
#> ..$ YOB : NULL
#> ..$ age : NULL
#> ..$ technicalAge : NULL
#> ..$ ageDifferences : NULL
#> ..$ sex : chr "unisex"
#> ..$ policyPeriod : num 25
#> ..$ premiumPeriod : NULL
#> ..$ deferralPeriod : num 0
#> ..$ guaranteedPeriod : num 0
#> ..$ contractClosing : NULL
#> ..$ blockStart : num 0
#> ..$ premiumPayments : chr "in advance"
#> ..$ benefitPayments : chr "in advance"
#> ..$ premiumFrequency : num 1
#> ..$ benefitFrequency : num 1
#> ..$ widowProportion : num 0
#> ..$ deathBenefitProportion: num 1
#> ..$ premiumRefund : num 0
#> ..$ premiumIncrease : num 1
#> ..$ annuityIncrease : num 1
#> ..$ deathBenefit : num 1
#> $ ContractState :List of 3
#> ..$ premiumWaiver : logi FALSE
#> ..$ surrenderPenalty: logi TRUE
#> ..$ alphaRefunded : logi FALSE
#> $ ActuarialBases :List of 9
#> ..$ mortalityTable : NULL
#> ..$ invalidityTable : NULL
#> ..$ invalidityEndsContract : logi TRUE
#> ..$ i : num 0
#> ..$ balanceSheetDate : Date[1:1], format: "1900-12-31"
#> ..$ balanceSheetMethod : chr "30/360"
#> ..$ surrenderValueCalculation: NULL
#> ..$ premiumFrequencyOrder : num 0
#> ..$ benefitFrequencyOrder : num 0
#> $ Costs : num [1:6, 1:6, 1:4] 0 0 0 0 0 0 0 0 0 0 ...
#> ..- attr(*, "dimnames")=List of 3
#> .. ..$ type : chr [1:6] "alpha" "Zillmer" "beta" "gamma" ...
#> .. ..$ basis : chr [1:6] "SumInsured" "SumPremiums" "GrossPremium" "NetPremium" ...
#> .. ..$ frequency: chr [1:4] "once" "PremiumPeriod" "PremiumFree" "PolicyPeriod"
#> $ Loadings :List of 13
#> ..$ ongoingAlphaGrossPremium: num 0
#> ..$ tax : num 0.04
#> ..$ unitcosts : num 0
#> ..$ security : num 0
#> ..$ noMedicalExam : num 0
#> ..$ noMedicalExamRelative : num 0
#> ..$ sumRebate : num 0
#> ..$ extraRebate : num 0
#> ..$ premiumRebate : num 0
#> ..$ partnerRebate : num 0
#> ..$ extraChargeGrossPremium : num 0
#> ..$ benefitFrequencyLoading :List of 4
#> .. ..$ 1 : num 0
#> .. ..$ 2 : num 0
#> .. ..$ 4 : num 0
#> .. ..$ 12: num 0
#> ..$ premiumFrequencyLoading :List of 4
#> .. ..$ 1 : num 0
#> .. ..$ 2 : num 0
#> .. ..$ 4 : num 0
#> .. ..$ 12: num 0
#> $ Features :List of 2
#> ..$ betaGammaInZillmer: logi FALSE
#> ..$ alphaRefundLinear : logi TRUE
#> $ ProfitParticipation:List of 16
#> ..$ advanceProfitParticipation : num 0
#> ..$ advanceProfitParticipationInclUnitCost: num 0
#> ..$ waitingPeriod : NULL
#> ..$ guaranteedInterest : NULL
#> ..$ interestProfitRate : NULL
#> ..$ totalInterest : NULL
#> ..$ mortalityProfitRate : NULL
#> ..$ expenseProfitRate : NULL
#> ..$ sumProfitRate : NULL
#> ..$ terminalBonusRate : NULL
#> ..$ terminalBonusFundRate : NULL
#> ..$ profitParticipationScheme : NULL
#> ..$ profitComponents : chr [1:5] "interest" "risk" "expense" "sum" ...
#> ..$ profitClass : NULL
#> ..$ profitRates : NULL
#> ..$ scenarios : list()
#> $ Hooks :List of 2
#> ..$ adjustCashFlows : NULL
#> ..$ adjustCashFlowsCosts: NULLAn insurance contract is modelled by
Costs of an insurance contracts can have