knitr::opts_chunk$set(collapse = TRUE, comment = "#>") library(knitr) library(kableExtra) library(LifeInsureR) library(dplyr) library(tibble) library(lubridate) library(pander)
The LifeInsureR package provides a full-featured framework to model classical life insurance contracts (non-unit linked). This is typically sufficient to implement simple example calculations or validate a single contract or tariff by a single individual.
However, when working for a company (either from inside the company or as an external consultant), one typically wants the implementation to be nicely structured, easily available for the whole team and still have the chance to improve the implementation. This can be achieved by encapsulating the company-specific tariff implementations in an R package that provides and exports the individual products of the company.
The LifeInsureR package even provides an RStudio project template to create a new skeleton of a company-specific implementation to use as the foundation of such an implementation.
The LifeInsureR
package provides an RStudio project template that sets
up a package for a company-specific tariff implementation. After
installing the package, simply create a new RStudio project from the
template:
{width="61%"}
{width="61%"}
{width="61%"}
The resulting RStudio project will have the following file structure:
DESCRIPTION
file provides the package name and its settings
(author, explanation, dependencies, etc.). This is typically the
first file to update.NAMESPACE
file will be automatically handled by roxygenR/
subdirectory contain the tariff / product
definitions, i.e. they implement the LifeInsuranceTarif
objects
for each product. The *_General.R
file contains general
definitions, like mortality tables, parameter / cost sets, surrender
penalty functions, etc. and is typically sourced from each tariff's
implementation file.tests/testthat/
directory are unit tests for the
testthat package. Typically, you will use the example prescribed (by
the regulator) in the official tariff definitions as test cases, so
that the implementation will always correspond to the official
documents.Once the individual products are implemented in the R/ directory, one typical application is to use them for batch-testing the contract administration or financial statement system.
To automate this, the template [MyCompany]RechnungGesamtbestand.R
is
provided in the project's top-level directory. It's purpose is to read
in a set of contract data and calculate the corresponding reserves (e.g.
to validate the official numbers in the financial statements).
R/
subdirectory. Use the (LifeInsureR documentation)LifeInsuranceContract$new(..)
calls.VTmodify.*
functions correspondingly.readXXXCOMPANYXXXBestand(..)
function. This helps preventing errors, as these columns are always
cast to the required type.calculate_contract(..)
function might need to some adjustments
/ modifications, in particular when modified contracts, premiums
waivers, additional tariffs / single-payment add-ons etc. are
present.calculate_portfolio(…)
function might need to be adjusted.files
and outfile
variables to point to the input
files ("Bestandsdaten") and the output file namecalculate_portfolio
function on the contract data set
(potentially filtered to some subsets to prevent performance issues)Typically, a call to calculate a portfolio and store the results in a dedicated (Excel) output file is:
results = NULL; results = calculate_portfolio(bestandinfos.all, tarif = c("ProdName1", "ProdName2"), GV = c("123"), debug =TRUE) openxlsx::write.xlsx(results, outfile("Prods-1-2"), asTable = TRUE, overwrite = TRUE, sheetName = "Vergleichsrechnung") openXL(outfile("Prods-1-2"))
The contract data are read in from the filenames provided in the
files
list and stored in the data.frame called bestandinfos.all
.
readXXXCOMPANYXXXBestand
.readXXXCOMPANYXXXBestand
function uses read_excel to read
in the raw data, then ensures the defined columns have the
proper data type.colMapping
Polizzennummer
VTmodify.general
.readXXXCOMPANYXXXBestand
or in VTmodify.general
All contracts are calculated by a call to calculate_portfolio
. The
arguments tarif
and GV
can be used to restrict the calculation
only to certain products and/or profit classes. Additionally,
n_max
can be used to calculate only the first n_max
contracts.
The calculate_portfolio
function does its work with the following
steps:
SliceID
. This allows multiple
portfolio data rows to be combined to one contract with several
slices / sum increases, which are calculated as one contract
(see section "10.3 Dynamic Increases" of the LifeInsureR
vignette). If each slice / dynamic increase is supposed to be
calculated individually and independent from the main contract /
other increases, then the column mapped to the SliceID
column
needs to have a different value for each portfolio data row. If
SliceID
uses contract numbers, all dynamics, etc. belonging to
the same contract number will be combined and calculated using
$addDynamics
SliceID
value) is
calculated in a loop using the by_slice
function, which calls
the calculate_contract
function for each contract.The calculate_contract
function calculates one individual
contract, with the individual columns of the portfolio data passed
as named parameters to the function.
LifeInsuranceContract
(with the given tariff / product) is
created and all values of the contract are automatically
calculated by the package by default.SliceID
are added using the $addDynamics
method of the
LifeInsuranceContract
class. The slice start date and duration
are adjusted correspondingly.data.frame
z. If debug=TRUE
, a column is added to the
resulting data.frame containing the R code to reproduce with
full contract.calculate_portfolio
combines the data.frame
s returned
for each contract's calculate_contract
call into one large
data frame, adds some derived columns and returns the data frame
as result of the calculations.The following columns / named parameters are typically used by a
LifeInsuranceTariff
implementation or the concrete contract as a
LifeInsuranceContract
object. Most parameters are not mandatory.
Additional arguments / columns are possible and will be preserved, even
if they are not used by the contract.
Polizzennummer
SliceID
balanceSheetDate
tarif
GV
i
sex
age
contractClosing
sliceDate
policyPeriod
premiumPeriod
premiumFrequency
annuityFrequency
sumInsured
Columns used for comparison with the calculated values:
Bruttoprämie
Sparprämie
Risikoprämie
Kostenprämie
Bilanzreserve
Gewinnreserve
Prämienübertrag
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.