---
title: "Using the LifeInsureR Package"
author:
- name: Reinhold Kainhofer
  affiliation: Open Tools
  email: reinhold@kainhofer.com

date: "`r Sys.Date()`"
output:
    rmarkdown::html_vignette:
        toc: true
        toc_depth: 3
        fig_width: 7
        fig_height: 5
        number_sections: true
vignette: >
  %\VignetteIndexEntry{Using the LifeInsureR Package}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---


```{r setup, echo = FALSE, message=FALSE}
knitr::opts_chunk$set(collapse = TRUE, comment = "#>")
library(knitr)
library(kableExtra)
library(LifeInsureR)
library(dplyr)
library(tibble)
library(lubridate)

library(pander)

panderOptions('round', 2)
panderOptions('digits', 12)
panderOptions('keep.trailing.zeros', TRUE)
panderOptions('table.split.table', 120)

kableTable = function(grd, ...) {
  grd %>% 
    kable(...) %>% 
    add_header_above(header = c(1, dim(grd)[[2]]) %>% `names<-`(names(dimnames(grd))), align = "c") %>%
    kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = F) %>%
    column_spec(1, bold = T, border_right = T)
}

```


The LifeInsureR 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 LifeInsureR package to provide the most flexible contract modelling framework in R.

# General Overview of the Concepts

An insurance contract is described by three different objects;

* `InsuranceContract`: The object describing the actual contract with all 
  contract-specific parameters (age, maturity, sum insured, etc.).
* `InsuranceTarif`: The general (contract-independent) description of the
  insurance product (benefits, present values / reserves, premium calculation,
  premium waivers, surrender value, reserve calculation, premium decomposition).
  It does not store any values (only tarif-provided default values for the 
  insurance contract), but provides all calculation functions. The implementation
  is based on a general approach using cash flows (depending on the type of 
  insurance). Once the cash flows (survival, death and guaranteed) are defined
  for all time steps, all further calculations are idential for all different 
  kinds of life insurance.
* ` ProfitParticipation`: For contracts with profit sharing mechanisms, this
  object describes the profit participation (like the `InsuranceTarif` object
  describes the guaranteed payments) and us used by the `InsuranceContract` 
  object.


The tariff and the profit scheme are purely descriptional and their creation does
not trigger any calculations. 
However, when one creates a contract for a given tariff, the following steps are 
done to calculate all values relevant for the contract:

* Extract the transition probabilities (mortality)
* Set up all cash flow time series (premiums, guaranteed payments, survival payments, death payments, disease payments, charged cost cash flows)
* Calculate all present values for each time for all the cash flows (benefits, premiums and costs)
* Use the actuarial equivalence principle and the present values at time $t=0$ to calculate the premium of the contract
* Express all cash flows also in absolute (monetary) terms
* Calculate the reserves at every moment
* Calculate the premium decomposition
* Apply the (optional) profit participation scheme with the given profit scenario
* Optionally apply contract changes (premiums waivers, dynamic) and further profit scenarios

All steps after the cash flow setup are implemented in a very generic way, as 
the cash flows fully determine an insurance contract and as soon as the cash 
flows are fixed, the valuation and reserve calculation can be expressed in 
terms of expected present values of the cash flows only.

While this might at first seem a bit complicated, it allows for very generic
implementations of life insurance products and contracts.


# A simple example: Term life insurance

To understand how the package implements life insurance contracts, let us look
at a simple example:

## Product description

Term Life Insurance 

* Public product name '**DeathPlus - Short Term Life Insurance**', Internal ID '**L71-U**'
* Only **death benefits**, no survival benefits
* **Mortality table**: Austrian 2010/12 census table unisex (mixed 65:35 from the male:female tables)
* **Guaranteed interest rate**: 0.5%
* Default contract duration: 5 years (to keep the example short)
* **Regular premium** payments (constant premiums) during the whole contract
<!-- * premiums paid more often than once a year in advance get the following surcharge: -->
<!--     * yearly premiums: 0% surcharge -->
<!--     * half-yearly premiums: 1% surcharge -->
<!--     * quarterly premiums: 1.5% surcharge -->
<!--     * monthly premiums: 2% surcharge -->

**Costs**:

* Aquisition costs: 5\% of the total premium sum
* Administration cost: 1% of the sum insured per year (both during premium payments as well as for paid-up contracts)
* Unit costs: 10 Euro per year (fixed) during premium payments
* Tax: 4% insurance tax (default)

Surrender Value:

* Reserve minus 10% surrender penalty, also applied on premium waiver


## Tariff implementation (InsuranceTarif)

```{r SimpleExampleRiskTarif, warning=F, results="hide", message = F}
library(magrittr)
library(MortalityTables)
library(LifeInsureR)
mortalityTables.load("Austria_Census")

Tarif.L71U = InsuranceTarif$new(
    name = "L71-U",
    type = "wholelife",
    tarif = "DeathPlus - Short Term Life Insurance",
    desc = "Term Life insurance (5 years) with constant sum insured and regular premiums",
    policyPeriod = 5, premiumPeriod = 5,  # 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 
    }
);
```

## Creating a contract

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:

```{r SimpleExampleRiskContract}
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 `contract.L71U$Values` 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:

```{r SimpleExampleRiskValuesPremCode, eval=F}
contract.L71U$Values$premiums
```
```{r SimpleExampleRiskValuesPremCodeOut, echo=F}
contract.L71U$Values$premiums %>% kable
```
```{r SimpleExampleRiskValuesResCode, eval=F}
contract.L71U$Values$reserves
```
```{r SimpleExampleRiskValuesResOut, echo=F}
contract.L71U$Values$reserves %>% pander()
```

Looking back at the definition of the tariff, the only spot where the type of
insurance actually came in was the `type` 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 `LifeInsureR::initializeCosts()` function defines all cost cash
flows, which are the starting point for all further calculations (only relevant 
columns of the data.frame are shown):

```{r SimpleExampleRiskCFCode, eval=F}
contract.L71U$Values$cashFlows
```
```{r SimpleExampleRiskCFOut, echo=F}
contract.L71U$Values$cashFlows %>% select(starts_with('premiums'), starts_with('death'), -death_Refund_past ) %>% pander()
```
```{r SimpleExampleRiskCFCostCode, eval=F}
contract.L71U$Values$cashFlowsCosts[,,,"survival"]
```
```{r SimpleExampleRiskCFCostOut, echo=F, results="asis"}
for (base in dimnames(contract.L71U$Values$cashFlowsCosts)[[3]]) {
  cat("* ,,\"", base, "\"\n", sep = "")
  cat(contract.L71U$Values$cashFlowsCosts[,,base, "survival"] %>% pander(round = 4, style = "rmarkdown"))
}
```

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.

```{r SimpleExampleRiskPVCode, eval=F}
contract.L71U$Values$presentValues
```
```{r SimpleExampleRiskPVOut, echo=F}
contract.L71U$Values$presentValues %>% as.data.frame() %>% select(starts_with('premiums'), starts_with('death'), -death_Refund_past ) %>% pander(round=5)
```
```{r SimpleExampleRiskPVCostCode, eval=F}
contract.L71U$Values$presentValuesCosts
```
```{r SimpleExampleRiskPVCostOut, echo=F, results="asis"}
for (base in dimnames(contract.L71U$Values$presentValuesCosts)[[3]]) {
  cat("* ,,\"", base, "\"\n", sep = "")
  cat(contract.L71U$Values$presentValuesCosts[,,base,"survival" ] %>% pander(round = 4, style = "rmarkdown"))
}
```
```{r SimpleExampleRiskPVPremCode, eval=F}
contract.L71U$Values$premiums
```
```{r SimpleExampleRiskPVPremOut, echo=F}
contract.L71U$Values$premiums %>% data.frame() %>% pander()
```

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 `contract.L71U$Values$absCashFlows` and 
`contract.L71U$Values$absPresentValues`). Also, the reserves of the 
contract can be calculated.

```{r SimpleExampleRiskPremiumsCode, eval=F}
contract.L71U$Values$reserves
```
```{r SimpleExampleRiskPremiumsOut, echo=F}
contract.L71U$Values$reserves %>% pander(digits=2)
```

Also, the premium composition into costs, risk premium, savings premium and 
other components is possible.

```{r SimpleExampleRiskPremiumCompositionCode, eval=F}
contract.L71U$Values$premiumComposition
```
```{r SimpleExampleRiskPremiumCompositionOut, echo=F}
contract.L71U$Values$premiumComposition %>% as.data.frame() %>% select(-loading.frequency, -rebate.premium, -rebate.partner, -profit.advance, -rebate.sum, -charge.noMedicalExam, -premium.risk.actual, -premium.risk.security, -risk.disease, -premium.risk.disease.actual, -premium.risk.disease.security, -starts_with('Zillmer')) %>% pander()
```




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.

```{r SimpleExampleRiskConversionCode, eval=F}
contract.L71U.prf = contract.L71U$premiumWaiver(t = 3)
contract.L71U.prf$Values$reserves
```
```{r SimpleExampleRiskConversionOut, echo=F}
contract.L71U.prf = contract.L71U$premiumWaiver(t = 3)
contract.L71U.prf$Values$reserves %>% pander()
```



## Creating tables with various parameters

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 `axes`, 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):
```{r SimpleExampleRiskPremiumGrid, eval=T, results="hide"}
grd = contractGridPremium(
  axes = list(age = seq(20, 80, 5), policyPeriod = seq(10, 40, 5)),
  tarif = Tarif.L71U, 
  contractClosing = as.Date("2020-08-18"), 
  sumInsured = 100000
)
grd
```
```{r SimpleExampleRiskPremiumGridOut, echo = F}
grd %>% kableTable(digits = 2)

```

One can also pass more than two dimensions to the axes:
```{r SimpleExampleRiskPremiumGrid3D, results = "hide"}
grd = 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")
)
grd
```
```{r SimpleExampleRiskPremiumGrid3DOut, echo=F, results="asis"}
for (d in dimnames(grd)[[3]]) {
  cat("\n", "* , , ", names(dimnames(grd))[[3]], "=",  d, "\n\n", sep = "")
  # cat(grd[,,d ] %>% as.data.frame() %>% rownames_to_column("age \\|  policyPeriod") %>% pander(digits = 7, round = 2, style = "rmarkdown"))
  cat(grd[,,d ] %>% kableTable(digits = 2), "\n")
}

```


One can use any of the parameters of the `InsuranceContract$new()` call in the
`axes` argument, even the `tarif` or `mortalityTable` 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 `Tarif.L71U`, 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):

```{r SimpleExampleRiskPremiumGridLifeTables, results = "hide"}
grd = contractGridPremium(
  axes = list(mortalityTable = mort.AT.census["m", ], age = seq(20, 80, 10)),
  tarif = Tarif.L71U, 
  sumInsured = 100000,
  contractClosing = as.Date("2020-08-18")
) 
grd
```
```{r SimpleExampleRiskPremiumGridLifeTablesOUT, echo = F}
grd %>% pander(round=1, digits=15, keep.trailing.zeros = T)
```


# All possible parameters

All 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):

* explicit parameters passed to `InsuranceContract$addProfitScenario()` (applies 
  only for the added profit scenario)
* explicit parameters passed to `InsuranceContract$new()` or `InsuranceContract$clone()`
* parameters set with the `ProfitParticipation`
* parameters set with the `InsuranceTarif`
* Default values set in `InsuranceContract.ParameterDefaults`

In addition to the parameters listed below, the `InsuranceContract$new()`
constructor function takes the following parameters

\define{
\item{tarif}{The `InsuranceTarif` object describing the tarif}
\item{parent}{For contracts with multiple parts, children get passed a pointer to the parent}
\item{calculate}{How much of the contract to calculate (by default everything will be calculated)}
\item{profitid}{The profit ID for contracts with profit participation}
}

```{r}
str(InsuranceContract.ParameterDefaults)
```
```{r, results="asis"}
# pandoc.listRK(InsuranceContract.ParameterDefaults)
```

# Tarif and Contract Specification

An insurance contract is modelled by the abstract product specification 
(`InsuranceTarif` class) and the concrete (individualized) `InsuranceContract`. 

* The `InsuranceTarif` object describes the product in abstract terms, holds
  default parameters and provides all calculation functions for cash flows, 
  present values, premiums and reserves (provided the contract's actual Parameters).
  It does not, however, hold contract-specific data.
* The `InsuranceContract` object holds the individual contract data (like age, contract 
  closing date, sum insured, etc.) that override the tariff's defaults. It also 
  holds a pointer to the insurance tariff and provides the general logic to
  calculate all parts of an insurance contract by calling the corresponding 
  functions of the tariff.

The insurance contract and the underlying insurance tariff have the same possible 
parameters in its constructors: The `InsuranceTarif` uses them to define defaults
for contracts that use the tariff, while the parameters passed to the contract
either provide the individually required data like age, sum insured or maturity, 
or they can override the defaults provided by the tariff. In theory, one could
even create a contract with an empty underlying tariff and provide all tariff-specific
parameters also in the contract's `new` call.

## Creating the tariff

The `InsuranceTarif` class provides a way to define an abstract insurance product.
The most important parameters to be passed in the  `InsuranceTarif$new()` call are:

| | |
|:-----|:----------|
|**General settings for the Tariff** ||
| `name`, `tarif`, `desc` | IDs and human-readable descriptions of the insurance product. They are just used as labels and array keys, but do not influence the calculations.|
| `type` | the most important parameter, defining the type of life insurance product (endowment, pure endowment, annuity, whole life insurance, dread-disease insurance, etc.)|
|**Actuarial Bases for the Tariff**  ||
| `mortalityTable` | a `MortalityTable` Object (package "MortalityTables"), providing the transition probabilities (typically death probabilities, but potentially also morbidity in dread-disease insurances)|
| `i` | Guaranteed interest rate|
| `costs`, `unitcosts` | passed a data structure for all cost parameters (see below)|
| `premiumFrequencyLoading` | surcharge for premium payments more often than yearly (as a named list)|
| `premiumRefund` | how much of the (gross) premium paid is returned upon death (often provided e.g. in deferred annuities or pure endowments with no fixed death benefit)|
| `tax` |insurance tax
|**Benefit calculation** ||
| `surrenderValueCalculation` | can be passed a hook function that calculates the surrender value given the current reserves at each time step|



A typical call looks like the following for a pure endowment with gross premium
refund upon death and a linearly decreasing surrender penalty:



```{r TarifDefinition, message = F}
Tarif.PureEnd = InsuranceTarif$new(
  name = "Example Tariff - Pure Endowment",
  type = "pureendowment",
  tarif = "PE1-RP",
  desc = "A pure endowment with regular premiums (standard tariff)",

  mortalityTable = mort.AT.census.2011.unisex,
  i = 0.005,
  # Costs: 4% acquisition, where 2.5% are zillmered, 5\% of each premium as beta costs, 
  #        1%o administration costs of the sum insured over the whole contract period
  costs = initializeCosts(alpha = 0.04, Zillmer = 0.025, beta = 0.05, gamma.contract = 0.001, gamma.paidUp = 0.001),
  unitcosts = 10,

  # Yearly premiums get no surcharge, monthly premiums add +4%
  premiumFrequencyLoading = list("1" = 0, "12" = 0.04),
  premiumRefund = 1,  # Full gross premium refund upon death
  tax = 0.04,         # 4% insurance tas

  surrenderValueCalculation = function(surrenderReserve, params, values) {
    n = params$ContractData$policyPeriod
    # Surrender Penalty is 10% at the beginning and decreases linearly to 0%
    surrenderReserve * (0.9 + 0.1 * (0:n)/n)
  }
)
```

Many parameters do not need to be given explicitly, but instead use sensible 
defaults (like the `premiumPeriod`, which by default equals the whole contract 
period, i.e. regular premium payments over the whole contract duration).

To create a similar tariff with some changes, one can call the `createModification`
method of the `InsuranceTarif` clas, which takes as arguments all insurance 
parameters that should be changed for the new tarif. 

To create a single-premium version of the pure endowment shown above, one can simply
use a call like:

```{r TarifDefinitionSP}
Tarif.PureEnd.SP = Tarif.PureEnd$createModification(
  name = "Example Tariff - Pure Endowment (SP)",
  tarif = "PE1-SP",
  desc = "A pure endowment with single premiums",
  premiumPeriod = 1
)
```

### Sample tariffs for the most common life insurance types

For the examples in the remainder of this vignette, we can create some more
example tariffs covering the most common types of life insurance. 


**General definitions for all tariffs**
```{r TarifDefinitions.All,message = F}
library(MortalityTables)
mortalityTables.load("Austria_Census")
mortalityTables.load("Austria_Annuities_AVOe2005R")
  # Costs: 4% acquisition, where 2.5% are zillmered, 5\% of each premium as beta costs, 
  #        1%o acquisition costs of the sum insured over the whole contract period
example.Costs = initializeCosts(
  alpha = 0.04, Zillmer = 0.025, 
  beta = 0.05, 
  gamma.contract = 0.001, gamma.paidUp = 0.001
)
example.Surrender = function(surrenderReserve, params, values) {
    n = params$ContractData$policyPeriod
    # Surrender Penalty is 10% at the beginning and decreases linearly to 0%
    surrenderReserve * (0.9 + 0.1 * (0:n)/n)
}
```
 
**Endowment**

```{r TarifDefinitions.All.End}
Tarif.Endowment = InsuranceTarif$new(
  name = "Example Tariff - Endowment",
  type = "endowment",
  tarif = "EN1",
  desc = "An endowment with regular premiums",

  mortalityTable = mort.AT.census.2011.unisex,
  i = 0.005,
  costs = example.Costs,
  unitcosts = 10,
  tax = 0.04,         # 4% insurance tax
  surrenderValueCalculation = example.Surrender
)
```

**Whole / Term Life Insurance**
```{r TarifDefinitions.All.Life}
Tarif.Life = InsuranceTarif$new(
  name = "Example Tariff - Whole/Term Life",
  type = "wholelife",
  tarif = "Life1",
  desc = "A whole or term life insurance with regular premiums",

  mortalityTable = mort.AT.census.2011.unisex,
  i = 0.005,
  costs = example.Costs,
  unitcosts = 10,
  tax = 0.04,         # 4% insurance tax
  surrenderValueCalculation = example.Surrender
)
```

**Immediate Annuity (single premium)**
```{r TarifDefinitions.All.ImmAnnuity}
Tarif.ImmAnnuity = InsuranceTarif$new(
  name = "Example Tariff - Immediate Annuity",
  type = "annuity",
  tarif = "Ann1",
  desc = "An annuity with single-premium",
  premiumPeriod = 1,

  mortalityTable = AVOe2005R.unisex,
  i = 0.005,
  costs = example.Costs,
  tax = 0.04         # 4% insurance tax
)
```

**Deferred Annuity**
```{r TarifDefinitions.All.DefAnnuity}
# Premium periods and deferral periods can also be given as a function of other
# contract parameters (like the age at contract inception, etc.)
Tarif.DefAnnuity = InsuranceTarif$new(
  name = "Example Tariff - Deferred Annuity",
  type = "annuity",
  tarif = "Life1",
  desc = "A deferred annuity (life-long payments start at age 65) with reg. premiums",

  policyPeriod = function(params, values) { 120 - params$ContractData$age},
  deferralPeriod = function(params, values) { 65 - params$ContractData$age},
  premiumPeriod = function(params, values) { 65 - params$ContractData$age},
    
  mortalityTable = AVOe2005R.unisex,
  i = 0.005,
  costs = example.Costs,
  tax = 0.04,         # 4% insurance tax
  surrenderValueCalculation = example.Surrender
)
```

**Dread-Disease Insurance**
```{r TarifDefinitions.All.DD}
# An example dread-disease tariff, morbidity is assumed linearly increasing with age
ddTable = mortalityTable.period(name = "Linear dread-disease table", 
                                ages = 0:100, deathProbs = 0:100/500)
Tarif.DreadDisease = InsuranceTarif$new(
  name = "Example Tariff - Dread-Disease",
  type = "dread-disease",
  tarif = "DD1",
  desc = "A dread disease insurance with a lump-sum payment upon diagnosis",

  sumInsured = 50000,
  mortalityTable = mort.AT.census.2011.unisex,
  invalidityTable = ddTable,
  i = 0.005,
  costs = example.Costs,
  unitcosts = 10,
  tax = 0.04,         # 4% insurance tax
  surrenderValueCalculation = example.Surrender
)
```

## Creating a contract

While the tariff describes the general product features, the contract object
holds the data of a concrete contract. All insurance parameters (see section 
[All possible parameters and their default values]) can be given to override
tarif defaults. 

However, the most important and often used parameters are:

|  |  |
|:-----|:---------|
|**Information about insuree** |
| `age` |the age of the insured person at contract start
| `YOB` | the year of birth of the insured person (`age`, `YOB` and `contractClosing` are redundant, at most two need to be given). YOB is only relevant for cohort mortality tables. For period life tables (which are independent of the birth year of the person), this parameter is not needed. |
| `sex` | relevant for sex-specific life tables (common in the past) |
|**Contract details** |
| `sumInsured` | the benefit when the insured event happens. Typically the lump sum for whole life insurances or endowments, or the (yearly) payment for annuities |
| `policyPeriod` | the duration of the whole contract |
| `premiumPeriod` | how long premiums are paid (1 for single-premiumcontracts, equal to `policyPeriod` (default) for regular premiums) |
| `premiumFrequency` | how often premiums are paid within a year (e.g.1 for yearly premiums, 4 for quarterly, 12 for monthly) |
| `contractClosing` | the starting date of the contract |
| `deathBenefit` | gives the factor of death benefit relative to the sum insured / survival benefit of endowments (1 means equal death and survival probabilities), can also be a function with non-constant values over time |
| `noMedicalExam`, `noMedicalExamRelative`, `sumRebate`, `extraRebate`, `premiumRebate` | various types of rebates or charges. They can either be defined in general functional form in the tariff to apply to all contracts, or given individually for each contract. For the details, when each of these rebates are applied, check the formula reference document.|
  


For the pure endowments defined above, a typical contract would be created like
this:

```{r Contract}
contract.PureEnd = InsuranceContract$new(
    Tarif.PureEnd,
    age = 50, policyPeriod = 20, 
    premiumFrequency = 12,
    sumInsured = 100000,
    contractClosing = as.Date("2020-07-01")
  )
```

```{r Contract.premiums,eval=F}
contract.PureEnd$Values$premiums
```

```{r Contract.premiumsOUT, echo = F}
contract.PureEnd$Values$premiums %>% kable(digits=4)
```
```{r Contract.premiumComposition,eval=F}
contract.PureEnd$Values$premiumComposition
```
```{r Contract.premiumCompositionOUT, echo = F}
contract.PureEnd$Values$premiumComposition %>% as.data.frame() %>% rowid_to_column("t") %>% mutate(t = t-1) %>% select(t, charged, tax, loading.frequency, gross, gamma, beta, alpha, alpha.noZillmer, alpha.Zillmer,  Zillmer, net, risk, savings) %>% pander
```

Due to the full premium refund in case of death, there is only very little 
biometric risk involved. If the premium refund is not included in the contract,
then we have a negative biometric risk over the whole period (i.e. negative 
risk premium, because upon death the existing reserves is shared with the 
collective). The premium refund can be overridden directly in the contract call:

```{r ContractNoRefund}
contract.PureEnd.NoRefund = InsuranceContract$new(
    Tarif.PureEnd,
    age = 50, policyPeriod = 20, 
    premiumFrequency = 12,
    sumInsured = 100000,
    contractClosing = as.Date("2020-07-01"),
    premiumRefund = 0
  )

```
```{r Contract.premiumsCode, eval = F}
cbind(`With refund` = contract.PureEnd$Values$premiums, `Without refund` = contract.PureEnd.NoRefund$Values$premiums)
```{r Contract.premiumsOut, echo = F}
cbind(`With refund` = contract.PureEnd$Values$premiums, `Without refund` = contract.PureEnd.NoRefund$Values$premiums) %>% pander
```
```{r Contract.riskpremiumsCode, eval = F}
cbind(
  `Gross premium with refund` = contract.PureEnd$Values$premiumComposition[,"gross"],
  `Gross premium w/o refund` = contract.PureEnd.NoRefund$Values$premiumComposition[,"gross"],
  `Risk premium with refund` = contract.PureEnd$Values$premiumComposition[,"risk"],
  `Risk premium w/o refund` = contract.PureEnd.NoRefund$Values$premiumComposition[,"risk"]
)

```{r Contract.riskpremiumsOut, echo = F}
cbind(
  `Gross premium with refund` = contract.PureEnd$Values$premiumComposition[,"gross"],
  `Gross premium w/o refund` = contract.PureEnd.NoRefund$Values$premiumComposition[,"gross"],
  `Risk premium with refund` = contract.PureEnd$Values$premiumComposition[,"risk"],
  `Risk premium w/o refund` = contract.PureEnd.NoRefund$Values$premiumComposition[,"risk"]
) %>% as_tibble() %>% rowid_to_column("t") %>% mutate(t = t-1) %>% pander
```


To create a single-premium contract, one can either use the single-premium tarif
defined above, or simply pass `premiumPeriod=1` to the call:

```{r Contract.SP}
contract.PureEnd.SP1 = InsuranceContract$new(
    Tarif.PureEnd,
    age = 40, policyPeriod = 45, premiumPeriod = 1,
    sumInsured = 100000,
    contractClosing = as.Date("2020-07-01")
  )
contract.PureEnd.SP2 = InsuranceContract$new(
    Tarif.PureEnd.SP,
    age = 40, policyPeriod = 45, # premiumPeriod already set by tariff!
    sumInsured = 100000,
    contractClosing = as.Date("2020-07-01")
  )

all_equal(contract.PureEnd.SP1$Values$reserves, contract.PureEnd.SP2$Values$reserves)

```


## Determining Sum Insured from the premium

By default, the insurance contract is created for a given sum insured and the 
premiums are calculated accordingly. Sometimes, the reverse is needed: The 
premium (either actuarial gross premium, written premium before or after taxes) 
is given and the corresponding sum insured should be determined automatically.

The `InsuranceContract` constructor / parameter set has an additional field 
`premium` to indicate the desired premium (written premium after tax by default) 
from which the sum insured is then calculated:
```{r PrescribePremium}
# Premium calculated from sumInsured
contract.End = InsuranceContract$new(
  Tarif.Endowment, age = 35, policyPeriod = 10,
  contractClosing = as.Date("2020-08-18"), 
  sumInsured = 10000);

# sumInsured derived from written premium
contract.End.premium = InsuranceContract$new(
  Tarif.Endowment, age = 35, policyPeriod = 10,
  contractClosing = as.Date("2020-08-18"), 
  premium = 1139.06);

contract.End.premiumBeforeTax = InsuranceContract$new(
  Tarif.Endowment, age = 35, policyPeriod = 10,
  contractClosing = as.Date("2020-08-18"), 
  premium = c(written_beforetax = 1095.25));

contract.End.premiumGross = InsuranceContract$new(
  Tarif.Endowment, age = 35, policyPeriod = 10,
  contractClosing = as.Date("2020-08-18"), 
  premium = c(gross = 1085.25));

```
```{r PrescribePremiumOUTPUT,echo = FALSE}
bind_rows(
  c(Contract = "contract.End", contract.End$Values$premiums[c("net", "Zillmer", "gross", "written_beforetax", "written")], sumInsured = contract.End$Parameters$ContractData$sumInsured),
  c(Contract = "contract.End.premium", contract.End.premium$Values$premiums[c("net", "Zillmer", "gross", "written_beforetax", "written")], sumInsured = contract.End.premium$Parameters$ContractData$sumInsured),
  c(Contract = "contract.End.premiumBeforeTax", contract.End.premiumBeforeTax$Values$premiums[c("net", "Zillmer", "gross", "written_beforetax", "written")], sumInsured = contract.End.premiumBeforeTax$Parameters$ContractData$sumInsured),
  c(Contract = "contract.End.premiumGross", contract.End.premiumGross$Values$premiums[c("net", "Zillmer", "gross", "written_beforetax", "written")], sumInsured = contract.End.premiumGross$Parameters$ContractData$sumInsured)
)
```

The final written premium can be directly passed as the `premium` argument. Other
types of premium must be passed as a named number (i.e. a one-element vector with
name "gross", "written_beforetax" or "written").

If a premium is prescribed, a `sumInsured` must not be given. If both are given, 
the sumInsured is used and the prescribed premium is silently ignored.

The are cases, when the sumInsured cannot be derived from a prescribed premium.
One relevant case is when a premium rebate depends on the sum insured, since in 
this case we need the sumInsured to calculate the rebate and thus the premium.
All rebates, add-ons and other parameters will temporarily use a sumInsured=1 
during the calculation of the actual sumInsured!



## Providing additional capital at contract inception

Often, when a contract is changed significantly, this is modelled as a totally 
new contract, with the existing reserve provided as additional one-time payment
for the follow-up contract. This is different from a single-premium contract, 
because the new contract can have regular premiums, just the existing reserve
is used as the initial reserve of the new contract.

The package provides the argument `initialCapital` to provide initial capital
that is also included in the calculation of the premium of the contract.

```{r InitialCapital}
# Contract with initial capital of 5.000 EUR
contract.Endow.initialCapital = InsuranceContract$new(
  tarif = Tarif.Endowment,
  sumInsured = 10000,
  initialCapital = 5000,
  age = 40, policyPeriod = 10,
  contractClosing = as.Date("2020-09-01")
)
# For comparison: Contract without initial capital of 5.000 EUR
contract.Endow = InsuranceContract$new(
  tarif = Tarif.Endowment,
  sumInsured = 10000,
  age = 40, policyPeriod = 10,
  contractClosing = as.Date("2020-09-01")
)
```
Comparing the reserves, one can clearly see the initial capital used as initial reserve:

```{r InitialCapitalOUTPUT}
data.frame(
  `Premium with initialCapital`= contract.Endow.initialCapital$Values$premiumComposition[,"charged"], 
  `Premium without initialCapital`= contract.Endow$Values$premiumComposition[,"charged"], 
  `Res.with initialCapital`= contract.Endow.initialCapital$Values$reserves[,"contractual"], 
  `Res.without initialCapital`= contract.Endow$Values$reserves[,"contractual"]
)
```


## Premium Waivers

After a while, many customers do not want to pay premiums for the contract any 
more and convert the contract to a paid-up contract. The unit benefit cash flows
from that moment on stay the same, but the sum insured is adjusted, so that the 
existing reserve is able to cover all future benefits and costs. Furthermore,
paid-up contracts typically have differen costs / loadings. Additionally, the
surrender penalty is usually applied to the reserve before the conversion.

Waiving premiums and recalculating the sum insured is very easy, one just calls
the method `InsuranceContract$premiumWaiver(t = ..)` on the existing contract.

```{r Contract.PureEndPrf, results="hide"}
contract.PureEnd.NoRefund.Prf = contract.PureEnd.NoRefund$clone()$premiumWaiver(t = 7)
contract.PureEnd.NoRefund.Prf$Values$reserves
```
```{r Contract.PureEndPrfOUT, echo=F}
contract.PureEnd.NoRefund.Prf$Values$reserves %>% pander
```

Notice that the contract changes are made directly to the contract ("reference semantics"). This is 
different from the typical behavior of R, where any change to e.g. a data.frame 
leaves the original data.frame intact and instead returns a modified copy.




# Calculation Approach


## Valuation

The calculation of all contract values is controlled by the function
`InsuranceContract$calculateContract()` (using methods of the `InsuranceTarif`
object) and follows the following logic:

1. First the **contingent (unit) cash flows** and the **transition probbilities**
are determined.
2. The **actuarial equivalence principle** states that at time of inception, the
(net and gross) premium must be determined in a way that the present value
of the future benefits and costs minus the present value of the future premiums
must be equal, i.e. in expectation the future premiums ove the whole lifetime
of the contract will exactly cover the benefits and costs. Similarly, at all
later time steps, the difference between these two present values needs to be
reserved (i.e. has already been paid by the customer by previous premiums).
2. This allows the premiums to be calculated by first calculating the **present
values** for all of the **benefit and costs cash flow** vectors.
3. The formulas
to calculate the gross, Zillmer and net **premiums** involve simple linear
combinations of these present values, so the **coefficients of these formulas**
are determined next.
4. With the coefficients of the premium formulas calculated, all **premiums
can be calculated** (first the gross premium, because due to potential gross
premium refunds in case of death, the formula for the net premium requires
the gross premium, which the formula for the gross premium involves no other
type of premuim).
5. With premiums determined, all unit cash flows and unit present values can
now be expressed in monetary terms / as **absolute cash flows** (i.e. the actual 
Euro-amount that flows rather than a percentage).
6. As described above, the difference between the present values of premiums
and present values of benefits and costs is defined as the required amount
of reserves, so the **reserves (net, gross, administration cost, balance sheet)**
and all values derived from them (i.e. surrender value, sum insured in case of
premium waiver, etc.) are calculated.
7. The **decomposition of the premium** into parts dedicated to specific purposes
(tax, rebates, net premium, gross premium, Zillmer premium, cost components,
risk premium, savings premium, etc.) can be done once the reserves are
ready (since e.g. the savings premium is defined as the difference of
discounted reserves at times $t$ and $t+1$).
8. If the contract has **(discretionary or obligatory) profit sharing**B mechanisms
included, the corresponding [ProfitParticipation] object can calculate that
profit sharing amounts, once all guaranteed values are calculated. This can
also be triggered manually (with custom profit sharing rates) by calling
the methods `InsuranceContract$profitScenario()` or `InsuranceContract$addProfitScenario()`.


## Cash Flows

An insurance contract is basically defined by the (unit) cash flows it produces:
\itemize{
  \item **Premium payments** (in advance or in arrears) at each timestep
  \item **Survival payments** at each timestep
  \item **Guaranteed payments** at each timestep
  \item **Death benefits** at each timestep
  \item **Disease benefits** at each timestep
}
Together with the transition probabilities (mortalityTable parameter)
the present values can be calculated, from which the premiums follow and
finally the reserves and a potential profit sharing.

For example, a _**term life insurance with regular premiums**_ would have the following
cash flows:

* premium cash flows: 1, 1, 1, 1, 1, ...
* survival cash flows: 0, 0, 0, 0, 0, ...
* guaranteed cash flows: 0, 0, 0, 0, 0, ...
* death benefit cash flows: 1, 1, 1, 1, 1, ...

A _**single-premium term life insurance**_ would look similar, except for the premiums:

* premium cash flows: 1, 0, 0, 0, 0, ...

A _**pure endowment**_ has no death benefits, but a survival benefit of 1 at the
maturity of the contract:

* premium cash flows: 1, 1, 1, 1, 1, ...
* survival cash flows: 0, 0, ..., 0, 1
* guaranteed cash flows: 0, 0, 0, 0, 0, ...
* death benefit cash flows: 0, 0, 0, 0, 0, ...

An _**endowment**_ has also death benefits during the contract duration:

* premium cash flows: 1, 1, 1, 1, 1, ...
* survival cash flows: 0, 0, ..., 0, 1
* guaranteed cash flows: 0, 0, 0, 0, 0, ...
* death benefit cash flows: 1, 1, 1, 1, 1, ...

A _**(deferred) annuity**B_ has premium cash flows only during the deferral peroid
and only survival cash flows during the annuity payment phase. Often, in case
of death during the deferral period, all premiums paid are refunded as a death
benefit.:

* premium cash flows: 1, 1, ...,  1, 0, 0, 0, ...
* survival cash flows: 0, 0, ..., 0, 1, 1, 1,...
* guaranteed cash flows: 0, 0, 0, 0, 0, ...
* death benefit cash flows: 1, 2, 3, 4, 5, ..., 0, 0, ...

A _**terme-fix insurance**_ has a guaranteed payment at maturity, even if the insured
has already died. The premiums, however, are only paid until death (which is
not reflected in the contingent cash flows, but rather in the transition
probabilities):

* premium cash flows: 1, 1, 1, 1, ...,  1
* survival cash flows: 0, 0, 0, 0, ..., 0
* guaranteed cash flows: 0, 0, 0, ..., 0, 1
* death benefit cash flows: 0, 0, 0, 0, ..., 0




# Cost structure

Costs of an insurance contracts can have various forms and bases.

The `InsuranceContract` class provides all common types of costs:


* Type of cost: Acquisition (Alpha-costs), Zillmer, Beta-costs, Administration (Gamma-costs during / after premiums and for paid-up contracts)
* Basis for costs: SumInsured, Premium Sum, Gross Premium, Net Premium, Reserve, constant costs
* Duration of costs: Once (up-front), during premium payments, after premium payments, during whole contract

The cost structure generated by `initializeCosts()` is a three-dimensional array
with the above-mentioned coordinates: 
```{r costStructureDimensions}
initializeCosts() %>% dimnames
```

The most common types of cost can be directly given in the call to `initializeCosts()`,
but for some uncommon combinations, one can directly fill any of the fields in the
three-dimensional array manually.
```{r costExample, eval=F}
initializeCosts(alpha = 0.04, Zillmer = 0.025, beta = 0.05, gamma.contract = 0.001)

# the above is the short form of:
costs.Bsp = initializeCosts()
costs.Bsp[["alpha", "SumPremiums", "once"]] = 0.04
costs.Bsp[["Zillmer", "SumPremiums", "once"]] = 0.025 # German Zillmer maximum
costs.Bsp[["beta", "GrossPremium", "PremiumPeriod"]] = 0.05
costs.Bsp[["gamma", "SumInsured", "PolicyPeriod"]] = 0.001
```

These costs parameters are immediately converted to the corresponding cash flows
when the contract is created. In the above example of a pure endowment (with 
premium waiver at time 7), the absolute cost cash flows are:

```{r costCashFlowsCode, eval=F}
contract.PureEnd.NoRefund$Values$absCashFlows
```
```{r costCashFlows, echo=F}
contract.PureEnd.NoRefund$Values$absCashFlows[1:11,] %>% select(alpha, Zillmer, beta, gamma, gamma_nopremiums, unitcosts) %>% pander()
```


In addition to these standardized costs, which are included in the expense-loaded
premium (sometimes also called the "(actuarial) gross premium"), there are certain
loadings and rebates that are applied after the expense-loaded premium $BP_x$:

$$P_x = \left\{ (BP_x + oUZu - SuRa) \cdot VS \cdot (1-VwGew) + unitC\right\} \cdot  \left(1-PrRa-VwGew_{StkK}-PartnerRa\right)\cdot \left(1+uz(k)\right) \cdot (1+tax)$$

with the following surcharges and rebates:

* $oUZu$ ... Surcharge for contracts without medical exam (parameter `noMedicalExam`)
* $SuRa$ ... Sum rebate (depending on the sum insured) (parameter `sumRebate`)
* $VwGew$ ... Advance profit participation (as premium rebate) (parameter `advanceProfitParticipation`)
* $unitC$ ... Unit costs per year (only during premium payments) (parameter `unitcosts`)
* $PrRa=PrRa(BP)$ ... Premium rebate (depending on premium amount) (parameter `premiumRebate`)
* $VwGew_{StkK}$ ... Advance profit participation (as premium rebate, on premium after unit costs) (parameter `advanceProfitParticipationInclUnitCost`)
* $PartnerRa$ ... Partner rebate on the premium (for multiple similar contracts) (parameter `partnerRebate`)
* $uz(k)$ ... Frequency charge for monthly/quarterly/half-yearly premium payments instead of yearly premiums (parameter `premiumFrequencyLoading`)
* $tax$ ... Insurance tax (0% in most countries, 4% or 11% in Austria) (parameter `tax`)




## Frequency charges

Typically, an insurance premium is calculated with yearly premiums paid in advance.
If premiums are paid more often per year (Parameter `premiumFrequency` or 
`benefitFrequency` set to a value larger than 1, typically 2 for half-yearly, 
4 for quarterly, or 12 for monthly payments), part of the interest during the year
is lost, as well as the premiums for the remainder of the year if the insured event
happens. So usually there is some kind of extra charge included:

* A frequency charge is added on the gross premium => Parameter `premiumFrequencyLoading` 
  and `benefitFrequencyLoading` are set to a list with keys "1", "2", "4" and "12" 
  and values that correspond to the extra charge (as a factor on the gross premium, 
  i.e. a percentage).
* The premium or benefit payments are calculated (approximately) as payments 
  $k$-times per year using yearly death / incidence probabilities. This calculation
  is typically using some approximations in $k$ => Parameter `premiumFrequencyOrder` 
  and `benefitFrequencyOrder` set to a value larger than 0. 
* Contracts with $k>1$ have higher cost loadings on the gross premium. => 
  Parameter `costs` is implemented a function with signature $function(params, values)$, 
  which accesses `params$ContractData$premiumFrequency` to return different expense
  rates for different premium payment frequencies.
* If the guaranteed interest rate is 0\%, the exact moment of payment during a year 
  is irrelevant for the guaranteed values. However, if a yield larger than 0\% is
  achieved, it is assigned to the contract via profit participation. So it makes
  sense adjust profit participation rates depending on the premium frequency 
  rather than modifying the premium. The higher the profit participation, the
  higher the effect of the $k$-th yearly premium payments and the higher the 
  modification of the rates can be. => Parameter `getInterestProfitRate` of
  the profit scheme can be implemented as a function that modifies the 
  rate depending on the premium or benefit frequency (similar to the cost adjustment 
  mentioned in the previous item).

```{r FrequencyCharges}
Tarif.Life.FrequencyLoading = Tarif.Life$createModification(
  name = "Term life (frequency loading)",
  premiumFrequencyLoading = list("1" = 0.0, "2" = 0.01, "4" = 0.015, "12" = 0.02)
)
Tarif.Life.FrequencyApprox1 = Tarif.Life$createModification(
  name = "Term life (k-th yearly, approx. 1.Ord.)",
  premiumFrequencyOrder = 1
)
Tarif.Life.FrequencyApprox2 = Tarif.Life$createModification(
  name = "Term life (k-th yearly, approx. 2.Ord.)",
  premiumFrequencyOrder = 2
)
Tarif.Life.FrequencyApprox3 = Tarif.Life$createModification(
  name = "Term life (k-th yearly, exact)",
  premiumFrequencyOrder = Inf
)

Tarif.Life.FrequencyExpense = Tarif.Life$createModification(
  name = "Term life (modified gamma costs)",
  costs = function(params, values) {
    switch (toString(params$ContractData$premiumFrequency),
        "12" = initializeCosts(alpha = 0.04, Zillmer = 0.025,  beta = 0.05,  gamma.contract = 0.00127, gamma.paidUp = 0.001),
        "4" = initializeCosts(alpha = 0.04, Zillmer = 0.025,  beta = 0.05,  gamma.contract = 0.00119, gamma.paidUp = 0.001),
        "2" = initializeCosts(alpha = 0.04, Zillmer = 0.025,  beta = 0.05,  gamma.contract = 0.0011, gamma.paidUp = 0.001),
        initializeCosts(alpha = 0.04, Zillmer = 0.025,  beta = 0.05,  gamma.contract = 0.001, gamma.paidUp = 0.001)
    )
  }
)
```

Of course, the loadings and costs mentioned above are not necessarily mathematically 
derived to offset the interest effect of k-th yearly payments. Rather, they are 
often simply decided by the management. Thus, the three approaches implemented
here can have quite different results:
```{r FrequencyCharges.Grid}
contractGridPremium(
  axes = list(tarif = c(Tarif.Life.FrequencyLoading, Tarif.Life.FrequencyApprox1, 
                        Tarif.Life.FrequencyApprox2, Tarif.Life.FrequencyApprox3, 
                        Tarif.Life.FrequencyExpense),
              premiumFrequency = c(1, 2, 4, 12)),
  age = 40, policyDuration = 20,
  sumInsured = 100000,
  contractClosing = as.Date("2020-09-01")
) %>% kableTable
```



## Security loadings

Although most mortality tables and expense loadings already have a certain amount 
of security margins included, often a tariff (mostly protection products) adds 
an additional security loading directly to the net present value of the benedits.

This can be easily implemented using the parameter `security`:

```{r Protection.Security}
contractGridPremium(
  axes = list(age = seq(30, 60, 10), security = 10*(0:5)/100),
  tarif = Tarif.Life,
  policyDuration = 20,
  sumInsured = 100000,
  contractClosing = as.Date("2020-09-01")
) %>% kableTable(digits = 2)
```


# Rounding values

In an ideal world, all calculations would be done with perfect accuracy. However,
in reality insurance tariffs are often implemented in systems that support only 
a limited number of digits. Or it is company policy to round premiums to whole 
Euro or Dollar amounts.

For this reason, the package also provides a `RoundingHelper` class that provides
an easy interfact for rounding intermediate values in the calculation. The 
instance of this class is stored in the tariff (and the contract) as 
`$Parameters$Hooks$Rounding` and the methods of the `InsuranceTarif` make use
of it in all places where rounding can typicall happen.

Each place where a number/vector/matrix is rounded in the package uses a separate
ID, which can and must be used to adjust the rounding behavior at that position.
If no rounding setting is set, no rounding occurs and no accuracy is lost.

An easy example of how rounding works is:
```{r RoundingHelper}
# Define three different rounding IDs / instances: "raw" with rounding to
# the nearest integer, "hundred" with rounding to the nearest multiple of 
# 100 and "accurate" rounded to the nearest multiple of 0.0001:
rounding = RoundingHelper$new(raw = 0, hundred = -2, accurate = 4)

# The rounding IDs are used as first argument in the rounding$round function:
rounding$round("raw", c(1234.567891, 0.00012345, 1234))
rounding$round("hundred", c(1234.567891, 0.00012345, 1234))
rounding$round("accurate", c(1234.567891, 0.00012345, 1234))

# If the given spec does not exist, no rounding it applied
rounding$round("non-existing", c(1234.567891, 0.00012345, 1234))

# Add a new spec with different settings:
rounding$setRounding("non-existing", 1)
rounding$round("non-existing", c(1234.567891, 0.00012345, 1234))
```


The `InsuranceTarif` class makes heavy use of these rounding settings. For 
example, to round the gross premium to Euros and the net premium to cent, 
one can use the setting `Rounding = list("Premium gross" = 0, "Premium net" = 2)`:

```{r RoundingHelper.Contract}
Tarif.EndowmentSI = InsuranceTarif$new(
    type = "pureendowment",
    tarif = "Endow1",
    age = 40, policyPeriod = 20,
    premiumRefund = 1,

    mortalityTable = mort.AT.census.2011.unisex,
    cost = initializeCosts(alpha = 0.04, gamma.contract = 0.0005),
    i = 0.03,
    sumInsured = 10000,
    contractClosing = as.Date("2020-09-01")
)
Tarif.EndowmentSI.rounded = Tarif.EndowmentSI$createModification(
    Rounding = list("Premium gross unit" = 3, "Premium net unit" = 6, "Premium net" = 2)
)
Contract.sumInsured = InsuranceContract$new(tarif = Tarif.EndowmentSI)
Contract.sumInsured.rounded = InsuranceContract$new(tarif = Tarif.EndowmentSI.rounded)


# premiums of the original tariff:
Contract.sumInsured$Values$premiums[c("unit.net", "-1et", "unit.gross", "gross")]
```

This rounding is applied immediately when the corresponding entity is calculated.
As a consequence, all further calculations depending on the entity will also be 
affected. This means that e.g. rounding only the gross premium will also have a
slight effect on the net premium with contracts that grant premium refunds in 
case of death, as the example above shows.


Here is a list of all rounding IDs used throughout the InsuranceTarif class. 
Each of them can be used to adjust rounding just one particular value/vector:

```{r eval=TRUE,echo=FALSE,result='asis'}
src = list.files(path = file.path(getwd(), "R"), pattern = ".R$", full.names = TRUE)
filecontents = unlist(lapply(src, readLines, warn = FALSE), use.names = FALSE)
results = stringr::str_extract(filecontents, "\\$round\\(\"([^\"]*)\"", group = 1)
results = results[!is.na(results)]
results = results[!(results %in% c("raw", "hundred", "accurate", "non-existing"))] %>% sort
cat(paste('-', results), sep = '\n')
```



# Creating premium and contract grids

When developing a new product or comparing different products, it is often
required to create tables of premiums or reserves for a product/tarif where 
just some of the parameters (like age, sum insured or maturity) change. 

For this purpose, this package provides two functions to create two- or 
higher-dimensional grids of contracts with each dimension representing one 
of the parameters varying.

* `contractGrid()` creates a (two- or higher-dimensional) grid of `InsuranceContract` object
* `contractGridPremium()` creates a grid of the premiums

The grid is defined by the `axes` argument to the `contractGrid()` call. This is
a named list giving all parameters that should vary inside the grid. Any of the
parameters of the `InsuranceContract$new()` constructor can be used in the axes.

For example, one can compare multiple tariffs or multiple varying pararameters. 

Let us look at the pure endowment above, which we implemented as a single-premium
variant and a variant with regular premiums, both of which have a potential 
(partial or full) premium refund in case of death. How do the premiums of these
contracts compare and how do the premiums depend on the premium refund proportion?

```{r Grid.Endowment.compare, results = "hide"}
grd = contractGridPremium(
  axes = list(tarif = c(Tarif.PureEnd, Tarif.Endowment, Tarif.PureEnd.SP), premiumRefund = c(0, 0.5, 1)),
  age = 50, policyPeriod = 20,
  sumInsured = 10000,
  contractClosing = as.Date("2020-09-01")
)
grd
```
```{r Grid.Endowment.compareOUT, echo = F}
grd %>% kableTable
```

The default implementation of `contractGridPremium` returns the written premium,
but one can also choose other types of premiums to display, or even other 
contract values (like reserves).

If one needs to investigate multiple values, it is better to first create a grid
of insurance contract objects and store it, so that the call to `contractGridPremium`
does not have to re-calculate the same contracts over and over again, extract just
one premium and discard the whole contract.

```{r Grid.Endowment.compareOther}
grd = contractGrid(
  axes = list(tarif = c(Tarif.PureEnd, Tarif.Endowment, Tarif.PureEnd.SP), premiumRefund = c(0, 0.5, 1)),
  age = 50, policyPeriod = 20,
  sumInsured = 10000,
  contractClosing = as.Date("2020-09-01")
)
```
```{r Grid.Endowment.compareOtherG1, eval = F}
# Compare net premiums without loadings:
contractGridPremium(grd, premium = "net")
```
```{r Grid.Endowment.compareOtherG1Out, echo = F}
contractGridPremium(grd, premium = "net") %>% kableTable
```

```{r Grid.Endowment.compareOtherG2, eval = F}
# Compare premium sums over the whole contract period (all contracts have the same sumInsured)
contractGridPremium(grd, .fun = function(c) {with(c$Values, 
     unitPremiumSum * premiums["written"])
})
```
```{r Grid.Endowment.compareOtherG2Out, echo = F}
# Compare premium sums over the whole contract period (all contracts have the same sumInsured)
contractGridPremium(grd, .fun = function(c) {with(c$Values, 
     unitPremiumSum * premiums["written"])
}) %>% kableTable(digits = 2)
```

```{r Grid.Endowment.compareOtherG3, eval = F}
# Compare risk premiums at time t=10 (the 11th row of the premium decomposition)
contractGridPremium(grd, .fun = function(c) {c$Values$premiumComposition[11, "risk"]})
```
```{r Grid.Endowment.compareOtherG3Out, echo = F}
# Compare risk premiums at time t=10 (the 11th row of the premium decomposition)
contractGridPremium(grd, .fun = function(c) {c$Values$premiumComposition[11, "risk"]}) %>% kableTable(digits = 2)
```

```{r Grid.Endowment.compareOtherG4, eval = F}
# Compare present value of all benefits and refunds (without costs) at time t=0
contractGridPremium(grd, .fun = function(c) {c$Values$absPresentValues[1, "benefitsAndRefund"]})
```
```{r Grid.Endowment.compareOtherG4Out, echo = F}
# Compare present value of all benefits and refunds (without costs) at time t=0
contractGridPremium(grd, .fun = function(c) {c$Values$absPresentValues[1, "benefitsAndRefund"]}) %>% kableTable(digits = 2)
```




Other useful examples of grid comparisons include e.g. the effect of the interest 
rate and the mortality table on the premiums:

```{r Grid.Protection, results ="hide"}
grd = contractGridPremium(
  axes = list(mortalityTable = mort.AT.census["m", -(1:10)], i = c(0, 0.005, 0.01), age = c(30, 45, 60), policyPeriod = c(10, 20)),
  tarif = Tarif.Life,
  contractClosing = as.Date("2020-09-01"),
  sumInsured = 10000
)
grd
```

```{r Grid.ProtectionOUT, echo=F, results="asis"}
for (a in dimnames(grd)[[3]]) {
for (d in dimnames(grd)[[4]]) {
  cat("\n", "* ", names(dimnames(grd))[[3]], "=",  a, ", ", names(dimnames(grd))[[4]], "=",  d, "\n\n", sep = "")
  # cat(grd[,,d ] %>% as.data.frame() %>% rownames_to_column("age \\|  policyPeriod") %>% pander(digits = 7, round = 2, style = "rmarkdown"))
  cat(grd[,, a, d] %>% kableTable(digits = 2), "\n")
}
}
```


# Exporting contract data to Excel

The LifeInsureR package also provides a function to export a given 
contract to a spreadsheet in Excel format:

* `exportInsuranceContract.xlsx(contract, filename)`

This function takes the contract and exports all data.frames in the contract's 
`contract$Values` data list as separate tabs to a spreadsheet file. It also 
adds some nice formatting and additional markup. For contracts with multiple
contract blocks (e.g. dynamic increases / sum increases or riders), the main
contract and all its child blocks are exported as well.

The tab containing the premiums and the premium calculation coefficients even
include the formulas, so one can in theory play around with the parameters to 
see how the premium changes.

If the contract has profit participation features and some profit scenarios have 
been added, they are exported as well.

Notice, however, that the Excel export is in general a static file containing 
the current state of the contract and all its values (cash flows, present values,
premiums, reserves, profit participation, etc.) as well as the most important
parameters and an overview of the history of the contract.

```{r ExcelExport,eval=F}
contract.exportExample = contract.PureEnd.NoRefund$clone()$
  addDynamics(t = 3, SumInsuredDelta = 10000)$
  addDynamics(t = 5, SumInsuredDelta = 15000)$
  addDynamics(t = 10, SumInsuredDelta = 15000)$
  addDynamics(t = 14, SumInsuredDelta = 10000)
exportInsuranceContract.xlsx(contract.exportExample, filename = "Example_PureEndowment_Dynamics.xlsx")
```



# Creating examples for the Austrian Financial Market Authority

When introducing a new tariff, an Austrian insurance company has to submit
a detailled mathematical description (so-called "Versicherungsmathematische 
Grundlagen") of the tariff to the Financial Market Authority (FMA), which have
to follow the [regulation on actuarial bases for life insurance -- LV-VMGV](https://www.ris.bka.gv.at/GeltendeFassung.wxe?Abfrage=Bundesnormen&Gesetzesnummer=20009298). The sections and contents
of this document are strictly defined in the regulation, and in addition to the
formulas of the tariff, an example contract has to be calculated with the following
key parameters:

* age 35, duration 30 years (15 years for protection tariffs)
* sum insured 100 000 Euro / monthly annuity 1000 Euro for annuities
* yearly premiums during the whole contract period (defereal period of 30 years for annuities)
* intermediate values (reserves, etc.) have to be calculated at $t=10$.

Given a tariff and a derived contract (with the above key parameters), this
package provides two functions to calculate and print / export
the required values either to the console / screen or to a file:

* `showVmGlgExamples(contract, prf = 10, t = 10, t_prf = 12, file = "", ...)`
* `exportInsuranceContractExample(contract, prf = 10, outdir = ".", basename=NULL, extraname = NULL, ...)`

The function `showVmGlgExamples` calculates all required values for the actuarial
bases document in the required order (including values after a premium waiver 
at the given time). If a filename is given, the output is exported to that text file,
otherwise it is simply printed out in the R console:

```{r VmGlgExample}
VMGL.contract = InsuranceContract$new(
    Tarif.PureEnd,
    age = 35, policyPeriod = 30, 
    premiumFrequency = 1,
    sumInsured = 100000,
    contractClosing = as.Date("2020-07-01")
  )

showVmGlgExamples(VMGL.contract)
```


The `exportInsuranceContractExample` provides no new functionality, but combines 
the Excel export feature and the regulatory example together. For a given contract
it will create three files:

* Excel export of the contract
* Excel export of the contract with a premium waiver applied at the given time
* The regulatory example (with premium waiver at the same time as in the Excel export) in a text file

One can give a base name and an extra name to distinguish different calculations
in the file names.


# Contracts combining multiple contract layers / slices

In real life, an insurance contract is not merely signed initially and then left 
untouched until it expires or is surrendered. Rather, some contracts already have
an automatic increase of the sumInsured or the premium (depending usually on some 
kind of observed consumer price index) included in the contract. Other contracts
have additional biometric riders like an additional death or disability cover. 
Other contracts are extended after their expiration, using the existing reserve
as a one-time payment (`initialCapital`) for the follow-up contract.

In all these cases, the original contract can be calculated as an `InsuranceContract`, 
but the additional dynamic increases, additional riders or extensions are mathematically
calculated as separate contracts (potentiall using different tariffs / types of 
insurance), although most parameters are shared from the original main contract.

In addition to modelling one particular tariff, the LifeInsuranceContract class 
can also act as a wrapper to bundle multiple related contracts / contract slices 
together. The class provides several methods for this:
* `$addDynamics(t, NewSumInsured, SumInsuredDelta, id, ...)`: 
        Include (at time `t`) a dynamic increase of premium or sumInsured, but 
        with the same basic parameters (age, tariff, maturity, 
        interest rate, etc.) as the main contract. The increase can 
        be given either as the new total sumInsured or as the 
        increase in the sumInsured caused by that one increase. Other parameters
        given as `...` are passed on to the `InsuranceContract$new` constructor
        of the layer for the dynamic increase. This also means that one can
        potentially override all parameters for the increase, including the 
        tariff or the interest rate.
* `$addExtension(t = NULL, policyPeriod, ...)`
        After the original contracts maturity, append a follow-up contract (by 
        default paid-up, i.e. no new premiums are paid) that uses the existing 
        reserve as initial capital. By default, no further premiums are paid 
        and the sumInsured is calculated from the existing reserve and the tariff
        of the extension. One can, however, also provide either a sumInsured or 
        a premium of the contract extension. In that case, the premium or the sumInsured
        will be calculated, using the existing reserves as initialCapital.
* `$addBlock(id = NULL, block = NULL, t, ...)`
        Generic function to add a child block to the contract. If a block (object 
        of type `LifeInsuranceContract` is passed, it is inserted and flagged as 
        starting at time `t`. If no block is passed, a new insurance contract
        is created using the arguments passed as `...`, combined with the
        parameters of the main contract. If `t>0`, the child block starts later 
        than the original contract. It is also possible that the child block extends
        beyond the maturity of the original contract (e.g. contract extensions
        are implemented this way).


In these case, the main contract will have several child blocks (also
LifeInsuranceContract objects), and the values of the main contract object will 
be the aggregated values of all its children, rather than the results of a 
calculation from an underlying tariff.

## Dynamic increases

To increase the sum insured or premium by a given value ()

```{r contractLayers}
# Contract with initial capital of 5.000 EUR
ctr.dynInc = InsuranceContract$new(
  tarif = Tarif.Endowment,
  sumInsured = 10000,
  age = 40, policyPeriod = 10,
  contractClosing = as.Date("2020-09-01")
)$
  addDynamics(t = 1, SumInsuredDelta = 1000)$
  addDynamics(t = 5, NewSumInsured = 15000)$
  addDynamics(t = 8, SumInsuredDelta = 4000)


ctr.dynInc$Values$basicData
```
As seen in this table, the sum insured increases and the premium with it. The 
`PremiumPayment` column is no longer a 0/1-column indicating whether a premium is
paid or not, but rather is the number of blocks/layers where a premium is paid.

The individual blocks can be accessed with the `contract$blocks` list:
```{r contractLayers.blocks}
for (b in ctr.dynInc$blocks) {
  cat(paste0("Block: ", b$Parameters$ContractData$id, ", starts at t=", b$Parameters$ContractData$blockStart, ", policyPeriod=", b$Parameters$ContractData$policyPeriod, "\n"))
}
```

Each block is formally handled like a separate contract, each starting at its own time `t=0`.
The over-all contract then takes care to correctly shift the child blocks to the
time relative to the parent block, before aggregating the data:
```{r contractLayers.blocks.data}
ctr.dynInc$blocks$Hauptvertrag$Values$basicData
ctr.dynInc$blocks$dyn1$Values$basicData
ctr.dynInc$blocks$dyn2$Values$basicData
ctr.dynInc$blocks$dyn3$Values$basicData
```


## General biometric riders

Instead of adding a dynamic increase, which typically uses the same tariff as 
the main contract, it is also possible to bundle e.g. a protection rider to a 
saving product. The savings product and the protection rider are calculated 
individually as child blocks, and the overall values of the contract are 
obtained by aggregating the values from the two children (savings and protection
part). Of course, in this scenario, the combined sumInsured of the overall contract 
is not meaningful, but the sumInsured of the individual blocks is.

```{r addBlock.rider}
ctr.main = InsuranceContract$new(
  tarif = Tarif.Endowment,
  sumInsured = 10000,
  age = 40, policyPeriod = 10,
  contractClosing = as.Date("2020-09-01")
)
ctr.Rider = InsuranceContract$new(
  tarif = Tarif.L71U, 
  sumInsured = 100000, 
  age = 40, policyPeriod = 10,
  contractClosing = as.Date("2020-09-01")
)
ctr.main$addBlock(block = ctr.Rider)

ctr.withRider = InsuranceContract$new(
  tarif = Tarif.Endowment,
  sumInsured = 10000,
  age = 40, policyPeriod = 10,
  contractClosing = as.Date("2020-09-01")
)$
  addBlock(tarif = Tarif.L71U, sumInsured = 100000, 
           age = 40, policyPeriod = 10,
           contractClosing = as.Date("2020-09-01"))
```


## Extending a contract beyond its maturity

When a contract expires, many companies offer premium-free contract extensions,
where the existing reserve is used as initial reserve for a follow-up contract
(possibly with new terms and parameters like interest rate or mortalities).

Instead of modifying the original contract and re-calculating it, it is easier 
to model the extension as a new block with the existing reserve given as
\code{initialCapital}. The extension will be calculated like a standalone-contract 
and the overall contract will aggregate the values from the original contract
and the extension. As the extension is a separate contract object, one can pass
all contract parameters to the \code{$addExtension} method.

The original premiumPeriod of the main contract is used, so by default the extension
will be a premium-free extension, where the sumInsured is calculated from the 
existing reserve and the benefits and costs of the extensions' tariff.

To create a premium-free extension explicitly, one can pass \code{premiumPeriod=0} (which
is the default anyway). To create an extension with regular (or single) premium
payments, one can pass either a \code{sumInsured} or a \code{premium} to provide
the sum insured and the premium and calculate the other from the given value

```{r contractExtension}
# original contract, expiring after 20 years
ContractA = InsuranceContract$new(
  tarif = Tarif.Endowment,
  age = 40, policyPeriod = 20,
  sumInsured = 10000,
  contractClosing = as.Date("2000-07-01")
)

# premium-free extension
ContractB = ContractA$clone()$
  addExtension(id = "Verlaengerung1", contractPeriod = 5, premiumPeriod = 0)
# sumInsured calculated from existing reserve:
ContractB$blocks$Verlaengerung1$Parameters$ContractData$sumInsured
ContractB$Values$basicData

# extension with given sumInsured resulting in 0 (gross) premiums
ContractC = ContractA$clone()$
  addExtension(id = "Verlaengerung1", contractPeriod = 5, sumInsured = 10723.07973354)
ContractC$blocks$Verlaengerung1$Values$premiums[["gross"]]
ContractC$Values$basicData

# extension with increased sumInsured: real premiums are charged, reserves start from the existing reserve:
ContractD = ContractA$clone()$
  addExtension(id = "Verlaengerung1", contractPeriod = 5, sumInsured = 20000)
ContractD$Values$basicData

# extension with regular premiums, which are given: sumInsured is calculated from it, reserves start from the existing reserve:
ContractD = ContractA$clone()$
  addExtension(id = "Verlaengerung1", contractPeriod = 5, premium = 597.8771)
ContractD$Values$basicData
```


# Handling contracts with increases

While many insurance contracts have a fixed sum insured and constant premium,
many contracts include some kind of adjustment to account for inflation. There
are various ways to achieve such an adjustment:

* The initial contract already includes a planned increase in the benefits by a
  pre-determined factor $(1+s)$ each year, premiums are constant over the whole 
  duration. 
* The initial contract has fixed sum insured, but the premiums increase by a 
  factor $(1+s)$ each year due to salary increases.
* "Dynamic increases": The initial contract has fixed sum insured with fixed 
  regular premiums. However, every year (or triggered based on an inflation or 
  consumer price index) the sum insured is increased by a certain amount (either 
  fixed or by the same percentage as the index) and the premiums are increased 
  accordingly. Internally, this is represented by a second, shorter contract
  covering only the increase in sumInsured, from which the additional premium can 
  be calculated according to the tariff.

The LifeInsuranceContract package provides functionality for each of these increases. 
All three increases can in theory be combined in the same contract, although 
in practice this usually does not happen and at most one kind of increase is 
included in a contract

## Fixed yearly premium increases

With this kind of increases, the initial contract valuation (i.e. the determination 
of the premium at contract inception) already takes into account that the premium
will not stay constant over the whole period,
but increases by a constant factor each year. The sum insured is calculated by 
the equivalence principle so that the expected present value of all future 
benefits and costs equals the expected present value of all future (i.e. 
increasing) premium payments.

This type of yearly premium increase by a fixed factor can be implemented by 
the parameter:

* `premiumIncrease` ... The factor, by which the premium increases yearly. Default is 1.0 (no increase in premium).

In the following example, we create a 10-year endowment contract with constant 
premiums over the whole period and another one with idential parameters except 
that the premium increases by 4\% each year:

```{r PremiumIncrease.Endowment, results = "hide"}
# For comparison: Contract with constant premiums
contract.Endow.Constant = InsuranceContract$new(
  tarif = Tarif.Endowment,
  sumInsured = 10000,
  age = 50, policyPeriod = 10,
  contractClosing = as.Date("2020-09-01")
)
# Contract with 4% yearly premium increase and same sum insured
contract.Endow.PremInc = InsuranceContract$new(
  tarif = Tarif.Endowment,
  sumInsured = 10000,
  premiumIncrease = 1.04,
  age = 50, policyPeriod = 10,
  contractClosing = as.Date("2020-09-01")
)
premium.comparison = data.frame(
  `Sum Insured` = contract.Endow.Constant$Values$basicData[,"SumInsured"],
  `Constant Premium` = contract.Endow.Constant$Values$basicData[,"Premiums"],
  `4% Yearly Increase` = contract.Endow.PremInc$Values$basicData[,"Premiums"],
  check.names = F
  )
```
```{r PremiumIncrease.EndowmentOut, results = "asis"}
premium.comparison %>% pander
```


## Fixed yearly benefit increases with constant premium

With this kind of increases, the premium will stay constant over the whole 
contract maturity, but the death and/or survival benefit (or the annuity payment)
will increase by a fixed factor each year. This is typically to safeguard the
benefit against inflation, so that the value of the annuity payment or death benefit
does not diminish due to inflation. The initial contract valuation (i.e. the determination 
of the constant premium at contract inception) already takes into account that 
the benefits will not stay constant over the whole period,
but increases by a constant factor each year. 

This type of yearly benefit increase by a fixed factor can be implemented by 
the parameters:

* `annuityIncrease` ... The factor, by which potential annuity payments increase yearly. Default is 1.0 (no increase in annuity benefits)
* `deathBenefit` ... The vector of death benefits (relative to the sum insured, which for endowments describes the survival benefit)

In the following example, we create a 10-year endowment contract with constant 
premiums over the whole period and another one with idential parameters except 
that the premium increases by 4\% each year:

```{r FixedSumIncrease.WholeLife, results = "hide"}
# For comparison: Contract with constant premiums
contract.TermLife.Constant = InsuranceContract$new(
  tarif = Tarif.Life,
  sumInsured = 10000,
  age = 50, policyPeriod = 10,
  contractClosing = as.Date("2020-09-01")
)
# Contract with 4% yearly increase in sum insured (final survival benefit is 10.000)
contract.TermLife.SumInc = InsuranceContract$new(
  tarif = Tarif.Life,
  sumInsured = 10000,
  deathBenefit = (1.04)^(0:20),
  age = 50, policyPeriod = 10,
  contractClosing = as.Date("2020-09-01")
)
premium.comparison = data.frame(
  `Const S.I.` = contract.TermLife.Constant$Values$absCashFlows[,"death"],
  `Const. Premium` = contract.TermLife.Constant$Values$absCashFlows[,"premiums_advance"],
  `4% sum increase` = contract.TermLife.SumInc$Values$absCashFlows[,"death"],
  `Premium w. sum increase` = contract.TermLife.SumInc$Values$absCashFlows[,"premiums_advance"],
  check.names = F
  )
premium.comparison
```
```{r FixedSumIncrease.WholeLifeOut, results = "asis", echo=F}
premium.comparison %>% pander
```

For annuities, the benefit increase is not handled through `deathBenefits`, but
rather through the parameter

* `annuityIncrease` ... yearly increase factor of the annuity payments

In the following example, we create a 10-year endowment contract with constant 
premiums over the whole period and another one with idential parameters except 
that the premium increases by 4\% each year:

```{r FixedSumIncrease.Annuity, results = "hide"}
# For comparison: Contract with constant annuity
contract.Annuity.Constant = InsuranceContract$new(
  tarif = Tarif.DefAnnuity,
  sumInsured = 1200,
  age = 55, 
  policyPeriod = 10,
  deferralPeriod = 5,
  premiumPeriod = 5,
  contractClosing = as.Date("2020-09-01")
)
# Contract with 4% yearly increase in annuity benefits
contract.Annuity.Increasing = InsuranceContract$new(
  tarif = Tarif.DefAnnuity,
  sumInsured = 1200,
  annuityIncrease = 1.04,
  age = 55, 
  policyPeriod = 10,
  deferralPeriod = 5,
  premiumPeriod = 5,
  contractClosing = as.Date("2020-09-01")
)
# Contract with 4% yearly increase in premiums and in annuity payments
contract.Annuity.IncreasingBoth = InsuranceContract$new(
  tarif = Tarif.DefAnnuity,
  sumInsured = 1200,
  annuityIncrease = 1.04,
  premiumIncrease = 1.04,
  age = 55, 
  policyPeriod = 10,
  deferralPeriod = 5,
  premiumPeriod = 5,
  contractClosing = as.Date("2020-09-01")
)
premium.comparison = data.frame(
  `Const. Annuity` = contract.Annuity.Constant$Values$absCashFlows[,"survival_advance"],
  `Const. Premium` = contract.Annuity.Constant$Values$absCashFlows[,"premiums_advance"],
  `4% Annuity Increase` = contract.Annuity.Increasing$Values$absCashFlows[,"survival_advance"],
  `Premium w. Ann.Increase` = contract.Annuity.Increasing$Values$absCashFlows[,"premiums_advance"],
  `Inc.Premium w. Ann.Increase` = contract.Annuity.IncreasingBoth$Values$absCashFlows[,"premiums_advance"],
  check.names = F
  )
```
```{r FixedSumIncrease.AnnuityOut, results = "asis"}
premium.comparison %>% pander
```



## Dynamic Increases

With dynamic increases, the contract initially is written with a fixed sum insured
and constant premiums over the whole contract period. The future increases are
not considered at all.

After the initial contract inception, either yearly or when a consumer price 
index changes by a value larger than a given threshold, the sum insured is 
increased (either by a fixed amount or by an amount determined by the index change)
and the premium is adjusted accordingly. Internally, the original contract is
left untouched and the increase is modelled by a separate contract with the 
same key parameters, only with shorter duration and a sum insured that represents
only the increase. The premium for this increase is calculated like a separate
contract with only the difference in the over-all sum insured as its sum insured.

Each dynamic increase then adds another separate tiny InsuranceContract object 
and the over-all values are the sums of all those contract blocks (sometimes 
also called "contract slices").

The `InsuranceContract` class provides a method to add a dynamic increase:

* `InsuranceContract$addDynamics(t, NewSumInsured, SumInsuredDelta, id, ...)`

Only one of `NewSumInsured` (new total sum insured) and `SumInsuredDelta` (only 
the difference between old and new sum insured) is needed. This method adds a
new contract block to the given InsuranceContract, starting at time $t$ with 
`SumInsuredDelta` as its sum insured and its premium calculated from the 
shorter contract period and the sum insured delta. These blocks for dynamic increases 
are stored in the contract's `$blocks` list of children. The values stored in the
contract are then simply the sum of all its children.

Here is an example of a 10-year endowment, which has dynamic increases at times $t=5$, $t=7$ and $t=8$:


```{r DynamicIncrease.Endowment}
# For comparison: Contract with constant annuity
contract.Endowment.Dynamics = InsuranceContract$new(
  tarif = Tarif.Endowment,
  sumInsured = 10000,
  age = 40, 
  policyPeriod = 10,
  contractClosing = as.Date("2020-09-01"),
  id = "Initial contract"
)$
  addDynamics(t = 5, NewSumInsured = 11000, id = "Dynamic at 5")$
  addDynamics(t = 7, NewSumInsured = 12000, id = "Dynamic at 7")$
  addDynamics(t = 8, NewSumInsured = 13500, id = "Dynamic at 8")

# Over-all contract sum insured and premiums for all blocks combined
contract.Endowment.Dynamics$Values$basicData[,c("SumInsured", "Premiums")] %>% pander
```
```{r DynamicIncrease.EndowmentOut, results = "asis", echo = F}
blk = c(list(`Over-all contract` = contract.Endowment.Dynamics), contract.Endowment.Dynamics$blocks)

padArray = function(arr = NULL, pad = 0, len = 0) {
  padEnd = max(0, len - pad - NROW(arr)) # if len is too short, return an array containing at least the arr
  nrcols = ifelse(is.null(arr), 0, NCOL(arr))
  rbind(
    array(0, dim = c(pad, nrcols)) %>% `colnames<-`(colnames(arr)),
    arr,
    array(0, dim = c(padEnd, nrcols)) %>% `colnames<-`(colnames(arr))
  ) %>% `colnames<-`(colnames(arr))
}

lapply(blk, function(b) {
  basic = padArray(b$Values$basicData, pad = b$Parameters$ContractData$blockStart)
  basic[,"SumInsured"]
}) %>% 
  bind_cols() %>% 
  rowid_to_column("t") %>% 
  mutate(t = t-1) %>% 
  pander(caption = "Sum Insured for the over-all contract and each of the blocks")

lapply(blk, function(b) {
  basic = padArray(b$Values$basicData, pad = b$Parameters$ContractData$blockStart)
  basic[,"Premiums"]
}) %>% 
  bind_cols() %>% 
  rowid_to_column("t") %>% 
  mutate(t = t-1) %>% 
  pander(caption = "Premium time series for the over-all contract and each of the blocks")

```



# Profit participation

In addition to the above guaranteed values, many contracts also include some 
kind of profit sharing. The total amount of money to be distributed is usually
predetermined by law or regulation (in Austria by the
["Lebensversicherung-Gewinnbeteiligungsverordnung -- LV-GBV"](https://www.ris.bka.gv.at/GeltendeFassung.wxe?Abfrage=Bundesnormen&Gesetzesnummer=20009295), 
but the actual way they are distributed to individual contracts is up the
insurance undertaking. The profit participation scheme defines profit participation
allocations based on certain rates and bases, where the formulas and the types 
of profit are pre-determined in a formal document (which in this package will 
be implemented as an object of class `ProfitParticipation`), while the profit 
rates are determined by the management of the undertaking ("discretionary benefits").


Typical Austrian insurance contracts have one of two
kinds of profit sharing mechanisms:

* "Advance profit participation" or "direct contributions", which is a direct 
  premium rebate, which can in theory be lowered or revoked at any time.
* Yearly profit assignments into the reserves based on "total credited interet 
  rate" and other profit attribution rates.

## Advance profit participation (premium rebate)

To implement advance profit participation, one still needs to create a 
`ProfitParticipation` object, which can be empty. The contract parameters 
`advanceProfitParticipation` and `advanceProfitParticipationInclUnitCost` then 
define the premium rebate. They can be set either in the profit scheme or in
the tariff definition. The latter is usually the easier way, as one profit 
scheme might be applicable to multiple different tariffs with different advance 
profit participation rates.

As an example, we will use our `Tarif.Life` whole life tarif defined above and
add a $38\%$ advance profit participation on the premium:
```{r AdvanceProfitExample}
profit.Advance.V1 = ProfitParticipation$new(
    name = "Profit Scheme for advance profit participation, V 1.0",
    advanceProfitParticipation = 0.38
);

Tarif.Life.withPP = Tarif.Life$createModification(
  name = "Example Tariff - Whole/Term Life with profit sharing",
  tarif = "Life1PP",
  profitParticipationScheme = profit.Advance.V1
)

contract.LifePP = InsuranceContract$new(
  tarif = Tarif.Life.withPP,
  age = 40, policyPeriod = 10,
  sumInsured = 100000,
  contractClosing = as.Date("2019-09-01")
)
```

The premium composition shows that the profit participation 
```{r advanceProfitExample.PremiumComposition, eval=F}
contract.LifePP$Values$premiumComposition
```
```{r advanceProfitExample.PremiumCompositionOUT, echo=F}
contract.LifePP$Values$premiumComposition[,c("charged", "tax", "unitcosts", "profit.advance", "gross", "net")] %>% as.data.frame() %>% rowid_to_column("t") %>% mutate(t = t-1) %>% pander
```


## The ProfitParticiption class

The profit participation scheme of a tarif is represented by an object of the
`ProfitParticipation` class. While the `InsuranceContract.Parameters` list contains
elements for the profit rates, the implementation of the calculation of the
profit parts is done by functions defined in the `ProfitParticipation` 
constructor.

This scheme is passed to the `InsuranceTarif` or `InsuranceContract` via the 
`profitParticipationScheme` parameter.
`

There are different types of profit participation assignments, based on the type
of risks they are based upon:

* __Interest profit__: total credited rate (minus guarantee) applied to some kind of reserve
* __Risk profit__: risk profit rate applied to the risk premium, capital or the sum insured
* __Expense profit__: expense profit rate applied to the sum insured
* __Sum profit__: rate (depending on sum insured) applied to the sum insured 
* __Terminal bonus__: yearly attributions are collected and paid out only on contract maturity
* __Terminal bonus fund__: Part of the ongoing profit allocation is not immediately attributed to the contract, but stored in a special reserve and paid out only on maturity.

Each of these profit components in general depends in some way on a profit rate and a basis to which the rate is applied. So each component has the general functional form:
$$Profit^{type}_t = Calc\left(Rate^{type}_t, Basis^{type}_t\right)$$
The most common calculation function is a simple multiplication, i.e.
$Calc(r, b) = r\cdot b$, but other functions are possible, to


The (default) parameters that can be passed to the `ProfitParticipation` constructor
are:

| | |
|:-----|:----------|
|**General profit setup** ||
| `waitingPeriod`   | During the waiting period at the beginning of a contract, no profit participation is assigned |
| `profitComponents` | describes the different components of profit participation ("interest", "risk", "expense", "sum", "terminal") |
| `profitClass`      | a profit ID used to identify the correct profit rates (rates are defined per profit class) |
| `profitRates`      | a data frame containing company-wide profit rates. Key columns are year and profitClass |
|**Advance profit participation rates** ||
| `advanceProfitParticipation`             | premium rebate (percentage discount on the gross premium) |
| `advanceProfitParticipationInclUnitCost` | premium rebate (percentage discount on the gross premium including unit costs) |
|**Regular profit participation rates** ||
| `guaranteedInterest` $i$        | Contract-specific override of the guaranteed intereste rate (only for profit participation purposes) |
| `interestProfitRate` $ip_t$     | Profit interest rate (added to the guaranteed interest rate to arrive at the total credited rate) |
| `totalInterest` $tcr_t$         | The total credited interest rate (sum of guaranteed interest and profit participation interest) |
| `mortalityProfitRate` $rp_t$    | Mortality / risk profit rate |
| `expenseProfitRate` $ep_t$      | Expenso profit rate |
| `sumProfitRate` $sp_t$          | Sum profit rate (typically a function, depending on sum insured) |
| `terminalBonusRate` $tb_t$      | Terminal bonus rate |
| `terminalBonusFundRate` $tbf_t$ | Terminal bonus fund rate, i.e. which percentage of the assigned profits are withheld in a separate terminal bonus fund and only paid out at maturity. |





For the calculation of the profit participation, the `ProfitParticipation` class
holds a list of function pointers to calculate each component of profit participation, as outlined above.
For each of interest, risk, expense, sum, terminal and terminal bonus fund the 
following three functions can be given:

* **Profit rate**: return the profit rate as a function from the values of the contract
  
  Function signature: `function(rates, ...)`
* **Profit base**: The quantity on which to apply the rate. Typically this function 
  returns either the current reserve, the previous reserve (or some combination), 
  the sum insured or the current risk premium.
  
  Function signature: `function(rates, params, values, ...)`
* **Calculation**: A function taking the rate and the base and calculate the 
  profit assigned for the specific profit component. Most common are a simple 
  multiplication of base and rate, but other formulas are possible, too.
  
  Function signature: `function(base, rate, waiting, rates, params, values, ...) `
  

Thus, the constructor of the `ProfitParticipation` class also takes the following
parameters:

|Type of profit      |Function for rate          | Function for base         | Function for calculation    |
|:-------------------|:--------------------------|:--------------------------|:----------------------------|
|interest on accrued profit |`getInterestOnProfits` |- (existing profit)    |-                            |
|interest profit     |`getInterestProfitRate`    |`getInterestProfitBase`    |`calculateInterestProfit`    |
|risk profit         |`getRiskProfitRate`        |`getRiskProfitBase`        |`calculateRiskProfit`        |
|expense profit      |`getExpenseProfitRate`     |`getExpenseProfitBase`     |`calculateExpenseProfit`     |
|sum profit          |`getSumProfitRate`         |`getSumProfitBase`         |`calculateSumProfit`         |
|terminal bonus      |`getTerminalBonusRate`     |`getTerminalBonusBase`     |`calculateTerminalBonus`     |
|terminal bonus fund |`getTerminalBonusFundRate` |`getTerminalBonusFundBase` |`calculateTerminalBonusFund` |

In addition, the following parameters define functions for reserves:

* `getTerminalBonusReserve` ... Calculate the reserve for the terminal bonus 
  from the bonus assignments (old tariffs often use some kind of discounting or 
  conditional reserving for the terminal bonus reserve)
  
  Function signature: `function(profits, rates, terminalBonus, terminalBonusAccount, params, values)`


To calculate the actual benefits paid out from profit participation, the following 
parameters take the corresponding functions (signature: `function(profits, rates, params, values, ...)` )

| |        |
|:---|:---------|
|`calculateSurvivalBenefit`  |Benefit from profit participation at maturity (in addition to the guaranteed payout) |
|`calculateDeathBenefitAccrued` |Benefit from profit participation upon death (in addition to the guaranteed payout) |
|`calculateDeathBenefitTerminal` |Benefit from terminal bonus upon death  (in addition to the guaranteed payout and regular profit participation) |
|`calculateSurrenderBenefitAccrued` |Benefit from profit participation upon contract surrender (in addition to the surrender value) |
|`calculateSurrenderBenefitTerminal` |Benefit from terminal bonus upon  contract surrender (in addition to the surrender value and regular profit participation) |
|`calculatePremiumWaiverBenefitAccrued` |Benefit from profit participation upon premium waiver (in addition to the surrender value) |
|`calculatePremiumWaiverBenefitTerminal` |Benefit from terminal bonus upon premium waiver surrender (in addition to the surrender value and regular profit participation) |

### Existing functions to use

While the details of a profit participation scheme are very specific and no two 
profit schemes are exactly alike, the basic functionality to extract rates and 
bases and the calculation functions are usually not so different. For this 
reason, the `LifeInsureR` package provides several little helper functions
that provide the most common functionality for the definition of rates, bases and
the profit calculation. See `?ProfitParticipationFunctions` for the full list.

The most common functions are:

* `PP.base.PreviousZillmerReserve(rates, params, values, ...)`
* `PP.base.contractualReserve(rates, params, values, ...)`
* `PP.base.previousContractualReserve(rates, params, values, ...)`
* `PP.base.meanContractualReserve(rates, params, values, ...)`
* `PP.base.ZillmerRiskPremium(rates, params, values, ...)`
* `PP.base.sumInsured(rates, params, values, ...)`
* `PP.base.totalProfitAssignment(res, ...)`

* `PP.rate.interestProfit(rates, ...)`
* `PP.rate.riskProfit(rates, ...)`
* `PP.rate.expenseProfit(rates, ...)`
* `PP.rate.sumProfit(rates, ...)`
* `PP.rate.terminalBonus(rates, ...)`
* `PP.rate.terminalBonusFund(rates, ...)`
* `PP.rate.interestProfitPlusGuarantee(rates, ...)`
* `PP.rate.totalInterest(rates, ...)`

* `PP.calculate.RateOnBase(base, rate, waiting, rates, params, values, ...)`
* `PP.calculate.RateOnBaseMin0(base, rate, waiting, rates, params, values, ...)`
* `PP.calculate.RatePlusGuaranteeOnBase(base, rate, waiting, rates, params, values, ...)`

* `PP.benefit.ProfitPlusTerminalBonusReserve(profits, ...)`
* `PP.benefit.Profit(profits, ...)`
* `PP.benefit.ProfitPlusGuaranteedInterest(profits, rates, ...)`
* `PP.benefit.ProfitPlusTotalInterest(profits, rates, params, values)`
* `PP.benefit.ProfitPlusHalfTotalInterest(profits, ...)`
* `PP.benefit.ProfitPlusInterestMinGuaranteeTotal(profits, rates, ...)`
* `PP.benefit.TerminalBonus5YearsProRata(profits, params, ...)`
* `PP.benefit.TerminalBonus5Years(profits, params, ...)`
* `PP.benefit.TerminalBonus(profits, params, ...)`




### Example profit scheme

For example, imagine a tariff's total cumulated assigned profit $G_t$ and the benefits at time $t$ have the formulas:
$$Prof_t = \left(G_{t-1} + TBF_{t-1}\right) \cdot \left(1 + i + ip_t\right) + ip_t \cdot \frac{\left(Res_{t-1} + Res_{t}\right)}{2} + rp_t \cdot P^r_t + ep_t \cdot SumInsured + sp_t(SI) \cdot SumInsured$$
$$G_t = G_{t-1} + (1 - tbf_t) \cdot Prof_t$$
$$TBF_t = TBF_{t-1} + tbf_t \cdot Prof_t$$
$$Death_t = G_t \cdot \left(1 + i + ip_t\right) + TBF_t$$
$$Matu_n = G_n + TBF_n$$
$$Surrender_t = G_t\cdot \left(1+\frac{i + ip_t}{2}\right) + 0.5 \cdot TBF_t$$
$$Red_t = G_t + 0.5 \cdot TBF_t$$


These formulas can be interpreted as following: 

* There are multiple profit components: interest profit, risk profit, expense profit and sum profit.
* The total profit assignment $Prof_t$ in year $t$ consists of:
  * Interest (guarantee + interest profit rate) on the accrued profits and the terminal bonus fund
  * Interest profit on the average reserve
  * Risk profit as part of the risk premium (similar to advance profit participation, but on a year-by-year basis on the actual risk premium)
  * Expense profit relative to the sum insured
  * Sum profit relative to the sum insured. The rate depends on the sum insured, too (e.g. higher SI typically have higher sum profit)
  * Only a portion $(1-tbf_t)$ is added to the accrued bonus, while the rest ist 
    stored in the Terminal Bonus Fund.
* The existing cumulated profit $G_{t-1}$ and the terminal bonus fund $TBF_{t-1}$ yields interest with the guaranteed 
  interest rate plus potentially the interest profit rate. If the total credited 
  rate is lower than the guarantee, the guarantee is still applied to the 
  existing profits. => `PP.rate.interestProfitPlusGuarantee`
* Additionaly, interest profit is assigned with rate $ip_t$ (=0 if total 
  credited rate is below guarantee) multiplied with the average of the current
  and the previous reserve for the guaranteed part. => `PP.base.meanContractualReserve`
* The risk profit works similar to advance profit participation, only that part 
  of the (actual) risk premium of the year is returned to the customer after 
  having paid it. => `PP.base.ZillmerRiskPremium` 
* Expense profit is based on the sum insured, since most cost structures are 
  linear in the sum insured and contain certain loadings, which are returned 
  to the customer via this profit component.
* A sum profit of $sp_t$ of the sum insured is added, even if no interest profit
  is distributed. The sum profit rate depends on the sum insured (as a function),
  since the charges expenses increase linearly in the sum insured while the actual
  cost do increase only sub-linear. So for higher sums typically more expenses
  are returned. => The sum profit rate will be a function rather than a single 
  value each year.
* Only a part $(1-tbf_t)$ of the profit assignment in year $t$ is added to the 
  accrued profits $G_t$, while the rest $tbf_t$ is stored in the terminal bonus 
  fund $TBF_t$, which is partially lost on surrender or premium waiver.
  
The values of $Res_t$, $P^r_t$, $SumInsured$ and the guaranteed interest $i^g_t$ are 
prescribed by the tariff or contract, while the profit participation rates 
$ip_t$, $rp_t$, $ep_t$ and $sp_t$ are decided on a year-by-year basis by the management boards.

The benefits for death, maturity, surrender and premium waivers are:

* In case of death, the existing cumulated profits yield one additional year of interest => `PP.benefit.ProfitPlusInterestMinGuaranteeTotal`
* At maturity of the contract, the existing cumulated profits are paid out in 
  addition to the guaranteed benefits of the contract. => `PP.benefit.Profit`
* In case of surrender (on average half a year after the contract's anniversary), 
  half a year of interest is added to the existing cumulated profits from the 
  last anniversary => `PP.benefit.ProfitPlusHalfInterestMinGuaranteeTotal`
* When premiums are waived, the existing accrued profits are taken into account
  without any additional interest. => `PP.benefit.Profit`
* The terminal bonus fund is paid out fully on death and at maturity, while half 
  of the TBF is lost on surrender or premium waiver.

This profit scheme can be easily be implemented as a `ProfitParticipation` 
object, where one can pass the functions for bases and calculation and also 
provide default profit rates:

```{r Example.ProfitParticipation}
ProfitScheme.example = ProfitParticipation$new(
  name = "Example Profit Scheme, V 1.0",
  profitComponents = c("interest", "risk", "expense", "sum", "TBF"),

  getInterestOnProfits    = PP.rate.interestProfitPlusGuarantee,
  getInterestProfitBase   = PP.base.meanContractualReserve,
  getRiskProfitBase       = PP.base.ZillmerRiskPremium,
  getExpenseProfitBase    = PP.base.sumInsured,
  getSumProfitBase        = PP.base.sumInsured,
  getTerminalBonusFundBase = PP.base.totalProfitAssignment,
  
  mortalityProfitRate = 0.15,
  expenseProfitRate = 0.01,
  sumProfitRate = function(params, ...) {if (params$ContractData$sumInsured > 1000000) 0.005 else 0;},
  terminalBonusFundRate = 0.3,
  
  calculateSurvivalBenefit      = PP.benefit.ProfitPlusTerminalBonusReserve,
  
  calculateDeathBenefitAccrued  = PP.benefit.ProfitPlusInterestMinGuaranteeTotal,
  calculateDeathBenefitTerminal = PP.benefit.TerminalBonus,
  calculateSurrenderBenefitAccrued = PP.benefit.ProfitPlusHalfInterestMinGuaranteeTotal,
  calculateSurrenderBenefitTerminal = function(profits, ...) {  profits[, "TBF"] / 2 },
  calculatePremiumWaiverBenefitAccrued = PP.benefit.Profit,
  calculatePremiumWaiverBenefitTerminal = function(profits, ...) {  profits[, "TBF"] / 2 },
  
  profitClass = NULL
)
```

The calculation functions are not given, as they default to the correct
`PP.calculate.RateOnBase` anyway. The interest profit rates are not given, as
they will vary over time with no default value. Rathery, they need to be  passed 
to the call to `InsuranceContract$addProfitScenario()` to calculate one particular
profit scenario with given rates.
In contrast, the mortality, expense and sum profit rates are initialized with 
some default values, which will be used if a profit scenario does not explicitly 
give those profit rates.


### Using the profit scheme in a tariff or contract

The profit scheme defined above can now be used with the `profitParticipationScheme` 
parameter in a tariff or a contract. Usually, the profit scheme is a property of
the product, so it should be specified in the tariff, but can be overridden in 
a contract.

As an example, let us create an endowment contract with 500\% death benefit 
that uses this profit scheme:

```{r Example.PP.Endowment}
contract.Endow.PP = InsuranceContract$new(
  tarif = Tarif.Endowment,
  sumInsured = 10000,
  deathBenefit = 5,
  age = 50, policyPeriod = 15,
  
  profitParticipationScheme = ProfitScheme.example,
  contractClosing = as.Date("2020-09-01")
)
```

In contrast to the guaranteed values, which can and will be calculated as soon
as the contract is created, the profit participation needs to be explicitly 
called with the desired rates. A contract can store multiple different profit
scenarios, which can be added with the `addProfitScenario()` method. This method
can also be chained to add multiple scenarios (e.g. )
```{r ExamplePP.Endowment.addScenario}
contract.Endow.PP$
  addProfitScenario(id = "Current total credited rate", guaranteedInterest = 0.005, interestProfitRate = 0.02, totalInterest = 0.025)$
  addProfitScenario(id = "Current TCR-1%", guaranteedInterest = 0.005, interestProfitRate = 0.01, totalInterest = 0.015)$
  addProfitScenario(id = "Current TCR+1%", guaranteedInterest = 0.005, interestProfitRate = 0.03, totalInterest = 0.035)
  
```
All profit scenarios are stored in the `InsuranceContract$Values$profitScenarios`
list indexed with the id given in the call.

The array containing all values of the profit scenario first holds the calculation 
basis and the rate for each of the profit components:
```{r ExamplePP.Endowment.Scenarios}
contract.Endow.PP$Values$profitScenarios$`Current total credited rate` %>%
  as.data.frame() %>%
  select(ends_with("Base"), ends_with("Interest"), ends_with("Rate"), -TBFRate, -TBFBase, -totalInterest) %>%
  rowid_to_column("t") %>% mutate(t = t - 1) %>% kable()
```

The base for interest profit is the average of the reserve:
```{r ExPP.End.reserve, echo = F}
contract.Endow.PP$Values$reserves %>% as.data.frame() %>% 
  rownames_to_column("t") %>% 
  select(t, SumInsured, Zillmer) %>% 
  mutate(AvgZillmer = rollingmean(c(0,Zillmer))) %>%
  pander()
```

From the bases and rates, the calculation function (in our case simply the multiplication of rate and base) is applied to arrive at the yearly profit allocation of each component:

```{r ExamplePP.Endowment.ScenariosAttib}
contract.Endow.PP$Values$profitScenarios$`Current total credited rate` %>%
  as.data.frame() %>%
  select(ends_with("Profit"), totalProfitAssignment, -totalProfit) %>%
  rowid_to_column("t") %>% mutate(t = t - 1) %>%
  pander

```

The `totalProfitAssignment` column is the sum of all component allocations in the given year (the $Prof_t$ in the formulas above).

After all components are calculated, the yearly profit assignment is split into the part that is accrued in the regular bonus and the part that is placed in the terminal bonus fund, using the terminal bonus fund rate. Finally, the yearly regular and terminal bonus assignments can be summed up to the regular and the terminal bonus:

```{r ExamplePP.Endowment.ScenariosTBFTotal}
contract.Endow.PP$Values$profitScenarios$`Current total credited rate` %>%
  as.data.frame() %>%
  select(TBFBase, TBFRate, TBFBonusAssignment, regularBonusAssignment, TBF, regularBonus, totalProfit) %>%
  rowid_to_column("t") %>% mutate(t = t - 1) %>%
  pander
```


The last step in the calculation of a scenario is to calculate the benefits for 
each of the possible types of payout:

```{r ExamplePP.Endowment.ScenariosBenefits}
contract.Endow.PP$Values$profitScenarios$`Current total credited rate` %>%
  as.data.frame() %>%
  select(survival, deathAccrued, death, surrenderAccrued, surrender, premiumWaiverAccrued, premiumWaiver) %>%
  rowid_to_column("t") %>% mutate(t = t - 1) %>%
  pander
```

One can add as many profit scenarios as desired. Each of the rates in the 
`addProfitScenario`-call can also be a vector giving the corresponding rate
for each year of the contract:

```{r ExamplePP.Endowment.Scenario.Decr}
contract.Endow.PP$
  addProfitScenario(id = "decreasing TCR", guaranteedInterest = 0.005, 
                    interestProfitRate = (15:0)/15 * 0.02, 
                    expenseProfitRate = c(rep(0.01, 5), rep(0.005, 5), rep(0, 6)))

contract.Endow.PP$Values$profitScenarios$`decreasing TCR` %>%
  as.data.frame() %>%
  select(interestBase, expenseBase, interestProfitRate, expenseProfitRate, interestOnProfitRate, interestProfit, expenseProfit, totalProfit) %>%
  rowid_to_column("t") %>% mutate(t = t - 1) %>%
  kable
```

In the Excel export, a separate tab of the Excel file will hold all profit scenarios added to the contract.



# Modifying the default calculation approach

While the cash-flow approach described above and based on the `type` parameter of the
`InsuranceTarif` works very well for all standart types of life insurance, sometimes 
a tariff does not follow the standard behaviour exactly. The valuation approach
with all-determining cash flows is still correct, but the cash flows might need 
to be adjusted. For this, some hook functions are provided that allow modification 
of the contract's internals (e.g. cash flows) before all other calculations commence.

Two hooks are provided, which allow modifications of the cash flow profiles before 
present values, premiums and reserves are calculated:

|    |      |
|:---|:-----|
|`adjustCashFlows` | Adjust the premium and benefit cash flows of the contract |
|`adjustCashFlowsCosts` | Adjust the cost cash flows |
|`adjustPremiumCoefficients` | Adjust the coefficients of the premium calculation formulas |

The function signature is `function(x, params, values, ...)`, where `x` is the 
object holding the standard cash flows determined for the contract. The return 
value of the hook function will be used instead of `x`.

The \code{adjustPremiumCoefficients} hook has a slightly extended function signature 
\code{function(coeff, type, premiums, params, values, premiumCalculationTime)}.

An example where the cash-flow-approach solely based on `type` does not immediately
work is a waiting period of 3 years for the death benefit. In particular,
if a person dies during the first 3 years of the contract, no death benefit is paid out.

The easiest way to implement such cash flows is to let the `InsuranceTarif` first
create the standard cash flows (with benefits during the first three years) and then
provide a hook function that nullifies the benefits in the waiting period, before
all present values, premiums and reserves are calculated.

```{r WaitingPeriod.Hook}
contract.Endow.Waiting = InsuranceContract$new(
  tarif = Tarif.Endowment,
  sumInsured = 10000,
  age = 50, policyPeriod = 15,
  
  contractClosing = as.Date("2020-09-01"),
  adjustCashFlows = function(x, ...) { x[1:3, "death_SumInsured"] = 0; x }
)

contract.Endow.Waiting$Values$cashFlows[,c("premiums_advance", "survival_advance", "death_SumInsured")] %>% pander

contractGridPremium(
  axes = list(age = seq(20, 80, 10), adjustCashFlows = c(function(x, ...) x, function(x, ...) { x[1:3, "death_SumInsured"] = 0; x })),
  tarif = Tarif.Endowment,
  sumInsured = 10000,
  policyPeriod = 15,
  
  contractClosing = as.Date("2020-09-01")
) %>% `colnames<-`(c("Full benefit", "Waiting period"))

```

Another example are term-fixe insurances where the Zillmer premium also includes the administration (gamma) costs over the whole contract period.

```{r termfix.Zillmeradjust.Hook, eval=FALSE}
  costs = initializeCosts(alpha = 0.04, Zillmer = 0.035, gamma = 0.0015, gamma.fullcontract = 0.001),
  adjustPremiumCoefficients = function(coeff, type, premiums, params, values, premiumCalculationTime) {
    if (type == "Zillmer") {
      coeff[["SumInsured"]][["costs"]]["gamma", "SumInsured", "guaranteed"] = 1
    }
    coeff
  },
```

