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

Implement dread-disease insurances

parent d12564a1
No related branches found
No related tags found
No related merge requests found
No preview for this file type
......@@ -92,7 +92,8 @@ Bemerkung: Sämtliche Barwerte werden rekursiv bestimmt, daher werden alle Forme
$Beg$ & Versicherungsbeginn (Datum, TODO)\\[0.5em]
$q_{x+t}$ & einjährige Sterbewahrscheinlichkeit der versicherten Person (aus $YOB$ und $x$ bestimmt) & \texttt{contract\$params\$transitionProbabilities\$q}\\
$p_{x+t}$ & einjährige Überlebenswahrscheinlichkeit, $p_{x+t} = 1-q_{x+t}$ & \texttt{contract\$params\$transitionProbabilities\$p} \\
$i_{x+t}$ & einjährige Erkrankungswahrscheinlichkeit (z.B. Dread Disease, Krebs, etc.) & \texttt{contract\$params\$transitionProbabilities\$i} \\
$p_{x+t}$ & einjährige Überlebenswahrscheinlichkeit als Aktiver, $p_{x+t} = 1-q_{x+t}-i_{x+1}$ & \texttt{contract\$params\$transitionProbabilities\$p} \\
$\omega$ & Höchstalter gemäß der benutzten Sterbetafel & \texttt{getOmega(tarif\$mortalityTable)} \\[0.5em]
......@@ -361,30 +362,39 @@ Jede Kostenart ($\alpha$/Zillmer/$\beta$/$\gamma$/$\tilde{\gamma}$) und Bemessun
\pagebreak
\section{Cashflows}
\section{Normierte Cashflows (auf Einheitswerte)}
\begin{longtable}{lp{6.5cm}v{2.5cm}v{2.5cm}v{2.5cm}}
& Beschreibung & LR & ALV & ELV \\\hline
$pr_t$ \dots & Prämienzahlungen (vorschüssig) zu $t$ & $\delta(t<m)$ & $\delta(t<m)$ & $\delta(t<m)$ \\
$PS$ & Prämiensumme, $PS=\sum_{t=0}^n pr_t$\\[1em]
% \begin{sidewaystable}
\begin{center}
$\ddot{e}_t$ \dots & Erlebenszahlungen vorschüssig zu $t$ & $\delta(l+g\le t< n)$ & 0 & $\delta(t=n)$\\
$e_t$ \dots & Erlebenszahlungen nachschüssig zu $t+1$& $\delta(l+g\le t< n)$ & 0 & $\delta(t=n)$\\
$\ddot{e}_t^{*}$ \dots & garantierte Zahlungen vorschüssig zu $t$ & $\delta(l\le t< l+g)$ & 0 & 0 \\
$e_t^{*}$ \dots & garant. Zahlungen nachschüssig zu $t+1$ & $\delta(l\le t< l+g)$ & 0 & 0 \\[1em]
% \rotatebox{90}{
\begin{tabular}{lp{6.5cm}v{1.6cm}v{1.5cm}v{1.5cm}v{1cm}v{1cm}}
& Beschreibung & LR & ALV & ELV & T-F & DD\\\hline\\[0.01em]
$pr_t$ \dots & Prämienzahlungen (vorschüssig) zu $t$ & $t<m$ & $t<m$ & $t<m$ & $t<m$ & $t<m$ \\
$PS$ & Prämiensumme, $PS=\sum_{t=0}^n pr_t$\\[0.5em]\hline\\[0em]
$a_t$ \dots & Ablebenszahlung zu $t+1$ & 0 & $\delta(l\le t < n)$ & 0 \\
$a_t^{(RG)}$ & Ablebenszahlungen für PRG zu $t+1$ (Ableben im Jahr $t$) & $\min(t+1,m,f)$ & 0 & $\min(t+1,m,f)$ \\
$\ddot{e}_t$ \dots & Erlebenszahlungen vorschüssig zu $t$ & $(l+g)...n$ & 0 & $t=n$ & 0 & 0 \\
$e_t$ \dots & Erlebenszahlungen nachschüssig zu $t+1$& $(l+g)...n$ & 0 & $t=n$ & 0 & 0 \\
$\ddot{e}_t^{*}$ \dots & garantierte Zahlungen vorschüssig zu $t$ & $(l+g)...n$ & 0 & 0 & $t=n$ & 0 \\
$e_t^{*}$ \dots & garant. Zahlungen nachschüssig zu $t+1$ & $(l+g)...n$ & 0 & 0 & 0 & 0 \\[0.5em]\hline\\[0em]
\end{longtable}
$a_t$ \dots & Ablebenszahlung zu $t+1$ & 0 & $l...n$ & 0 & 0 & 0 \\
$d_t$ \dots & Zahlung zu $t+1$ bei Eintritt der Erkrankung zwischen $t$ und $t+1$ & 0 & 0 & 0 & 0& $l...n$ \\[0.5em]\hline\\[0em]
$a_t^{(RG)}$ & Ablebenszahlungen für PRG zu $t+1$ (Ableben im Jahr $t$) & $\min(t+1, m, f)$ & 0 & $\min(t+1,m,f)$ & 0 & 0 \\[0.5em]\hline
\end{tabular}
% }
\end{center}
% \end{sidewaystable}
Die Cash-Flows können auch in Matrixform dargestellt werden:
\begin{align*}
%
\overrightarrow{CF}^L_t &= \left(
\begin{matrix} % TODO: Add an indication that the first row is in advance, the second in arrears
pr_t & \ddot{e}_t^{*} & \ddot{e}_t & 0 & 0 \\
pr^{(nachsch)}_t & e_t^{*} & e_t & a_t & a_t^{(RG)}\\
pr_t & \ddot{e}_t^{*} & \ddot{e}_t & 0 & 0 & 0 \\
pr^{(nachsch)}_t & e_t^{*} & e_t & a_t & d_t & a_t^{(RG)}\\
\end{matrix}
\right)
%
......@@ -522,10 +532,16 @@ A^{(RG+)}_\xn(t) &= A^{(RG)}_\xn(t) - A^{(RG-)}_\xn(t)
\intertext{Dieser Wert ist rekursiv nicht darstellbar.}
\end{align*}
\subsection{Disease-Barwert}
\begin{align*}
A^d_\xn(t) &= i_{x+t} \cdot v \cdot d_t + p_{x+t} \cdot v \cdot A^d_\xn(t+1)\\
\end{align*}
\subsection{Leistungsbarwert}
\begin{align*}
BW^L_\xn(t) &= E_\xn(t) + A_\xn(t) + (1+\rho^{RG}) \cdot A^{(RG)}_\xn(t)\cdot BP_\xn
BW^L_\xn(t) &= E_\xn(t) + A_\xn(t) + A^d_\xn(t) &\text{ohne Prämienrückgewähr}\\
BW^{L,RG}_\xn(t) &= BW^L_\xn(t) + (1+\rho^{RG}) \cdot A^{(RG)}_\xn(t)\cdot BP_\xn &\text{inkl. Prämienrückgewähr}
\end{align*}
......@@ -556,7 +572,8 @@ allen Termen der Subscript $\xn$ unterlassen):
\begin{align*}
\overrightarrow{BW}^L(t) &= \left(
\begin{matrix}
P(t), & E^{Gar}(t), & E(t), & A(t), & A^{(RG)}(t)
P(t), & %E^{Gar}(t), & E(t), & A(t),
BW^L(t), & A^{(RG)}(t)
\end{matrix}
\right)
%
......@@ -585,7 +602,9 @@ VK^{(VS)}(t) & VK^{(PS)}(t) & -\\
\subsection{Nettoprämie:}
\begin{align*}
NP_\xn &= \frac{E_\xn(0) + A_\xn(0) + \left(1+\rho^{RG}\right) \cdot A^{(RG)}_\xn(0) \cdot BP_\xn}{P_\xn(0)} \cdot \left(1+\rho\right)
NP_\xn &= \frac{%E_\xn(0) + A_\xn(0) + \left(1+\rho^{RG}\right) \cdot A^{(RG)}_\xn(0) \cdot BP_\xn}
BW^{L}_\xn(0) + \left(1+\rho^{RG}\right) \cdot A^{(RG)}_\xn(0) \cdot BP_\xn}
{P_\xn(0)} \cdot \left(1+\rho\right)
\end{align*}
......@@ -594,7 +613,8 @@ NP_\xn &= \frac{E_\xn(0) + A_\xn(0) + \left(1+\rho^{RG}\right) \cdot A^{(RG)}_\x
\begin{align*}
ZP_\xn &=
\frac{%
NP_\xn\cdot P_\xn(0) +
% NP_\xn\cdot P_\xn(0) +
\overbrace{\left(BW^{L}_\xn(0) + \left(1+\rho^{RG}\right) \cdot A^{(RG)}_\xn(0) \cdot BP_\xn\right) \cdot (1+\rho)}^{=NP_\xn\cdot P_\xn(0)} +
ZK^{(VS)}_\xn(0) +
ZK^{(PS)}_\xn(0) \cdot BP_\xn \cdot PS +
ZK^{(BP)}_\xn(0)\cdot BP_\xn
......@@ -609,7 +629,8 @@ Varianten:
\begin{align*}
ZP_\xn &=
\left[%
NP_\xn\cdot P_\xn(0) +
% NP_\xn\cdot P_\xn(0) +
BW^{L,RG}_\xn(0) \cdot (1+\rho) +
\left(ZK^{(VS)}_\xn(0) + IK^{(VS)}_\xn(0) + VK^{(VS)}_\xn(0)\right) + \right.\\
&\qquad\left.\left(ZK^{(PS)}_\xn(0) + IK^{(PS)}_\xn(0) + VK^{(PS)}_\xn(0)\right) \cdot BP_\xn \cdot PS + \right.\\
&\qquad\left.\left(ZK^{(BP)}_\xn(0) + IK^{(BP)}_\xn(0) + VK^{(BP)}_\xn(0)\right) \cdot BP_\xn
......@@ -621,8 +642,8 @@ ZP_\xn &=
\item % REFERENCE: ME
Prämienrückgewähr proportional zu Zillmerprämie (für Berechnung der Zillmerprämie):
\begin{align*}
ZP_\xn &= \frac{E_\xn(0) + A_\xn(0) + \left(1+\rho^{RG}\right) \cdot A^{(RG)}_\xn(0) \cdot ZP_\xn}{P_\xn(0)} \cdot \left(1+\rho\right)\\
ZP_\xn &= \frac{E_\xn(0) + A_\xn(0) + \cdot ZP_\xn}{P_\xn(0) - \left(1+\rho^{RG}\right)\cdot A^{(RG)}_\xn(0)\cdot \left(1+\rho\right)} \cdot \left(1+\rho\right)
ZP_\xn &= \frac{BW^L_\xn(0) + \left(1+\rho^{RG}\right) \cdot A^{(RG)}_\xn(0) \cdot ZP_\xn}{P_\xn(0)} \cdot \left(1+\rho\right)\\
ZP_\xn &= \frac{BW^L_\xn(0)}{P_\xn(0) - \left(1+\rho^{RG}\right)\cdot A^{(RG)}_\xn(0)\cdot \left(1+\rho\right)} \cdot \left(1+\rho\right)
\end{align*}
\end{itemize}
......@@ -632,7 +653,7 @@ ZP_\xn &= \frac{E_\xn(0) + A_\xn(0) + \cdot ZP_\xn}{P_\xn(0) - \left(1+\rho^{RG
\begin{align*}
BP_\xn &= \frac%
{
\left(E_\xn(0) + A_\xn(0)\right)\cdot\left(1+\rho\right) +
BW^L_\xn(0)\cdot\left(1+\rho\right) +
\left( AK^{(VS)}_\xn(0) + IK^{(VS)}_\xn(0) + VK^{(VS)}_\xn(0) \right)
}%
{
......@@ -654,13 +675,15 @@ Für die Berechnung der Prämien können die Koeffizienten der jeweiligen Barwer
\begin{sidewaystable}
\centering
\newenvironment{benarray}{\big(\begin{array}{*4{C{3.4em}}C{12em}}}{\end{array}\big)}
% \newenvironment{benarray}{\big(\begin{array}{*4{C{3.4em}}C{12em}}}{\end{array}\big)}
\newenvironment{benarray}{\big(\begin{array}{C{4em}C{5em}C{12em}}}{\end{array}\big)}
\newenvironment{costarray}{\left(\begin{array}{*3{C{4.7em}}}}{\end{array}\right)}
% TODO: laufende alpha-Kosten
\begin{tabular}{||ll|c|c||}\hline\hline
& & Leistungen & Kosten \\ \hline\hline
Terme & &
$\begin{benarray}P_\xn(t) & E^{Gar}_\xn(t) & E_\xn(t) & A_\xn(t) & A_\xn^{(RG)}(t)\end{benarray}$
% $\begin{benarray}P_\xn(t) & E^{Gar}_\xn(t) & E_\xn(t) & A_\xn(t) & A_\xn^{(RG)}(t)\end{benarray}$
$\begin{benarray}P_\xn(t) & BW^L_\xn(t) & A_\xn^{(RG)}(t)\end{benarray}$
&
$\begin{costarray}
AK^{(VS)}_\xn(t) & AK^{(PS)}_\xn(t) & AK^{(BP)}_\xn(t) \\
......@@ -673,18 +696,18 @@ VK^{frei}_\xn(t) & - & -\\
Nettoprämie & Zähler &
$\begin{benarray}0 & 1+\rho & 1+\rho & 1+\rho & \left(1+\rho^{RG}\right)\cdot BP_\xn \cdot \left(1+\rho\right)\end{benarray}$
$\begin{benarray}0 & 1+\rho & \left(1+\rho^{RG}\right)\cdot BP_\xn \cdot \left(1+\rho\right)\end{benarray}$
& -
\\
& Nenner &
$\begin{benarray} 1 & 0 & 0 & 0 & 0\end{benarray}$
$\begin{benarray} 1 & 0 & 0 \end{benarray}$
& -
\\\hline
Zillmerprämie & Zähler &
$\begin{benarray}0 & 1+\rho & 1+\rho & 1+\rho & \left(1+\rho^{RG}\right)\cdot BP_\xn \cdot \left(1+\rho\right)\end{benarray}$
$\begin{benarray}0 & 1+\rho & \left(1+\rho^{RG}\right)\cdot BP_\xn \cdot \left(1+\rho\right)\end{benarray}$
&
$\begin{costarray}
0 & 0 & 0 \\
......@@ -696,13 +719,13 @@ Zillmerprämie & Zähler &
\\
& Nenner &
$\begin{benarray} 1 & 0 & 0 & 0 & 0\end{benarray}$
$\begin{benarray} 1 & 0 & 0\end{benarray}$
&
-
\\\hline
Bruttoprämie & Zähler &
$\begin{benarray}0 & 1+\rho & 1+\rho & 1+\rho & 0\end{benarray}$
$\begin{benarray}0 & 1+\rho & 0\end{benarray}$
&
$\begin{costarray}
1 & 0 & 0 \\
......@@ -714,7 +737,7 @@ Bruttoprämie & Zähler &
\\
& Nenner &
$\begin{benarray}1 & 0 & 0 & 0 & -(1+\rho)\cdot(1+\rho^{RG}) \end{benarray}$
$\begin{benarray}1 & 0 & -(1+\rho)\cdot(1+\rho^{RG}) \end{benarray}$
&
$\begin{costarray}
0 & -PS & -1 \\
......
calculatePVSurvival = function(q, advance, arrears=c(0), ..., m=1, mCorrection = list(alpha=1, beta=0), v=1) {
# Caution: px is not neccessarily 1-qx, because we might also have dread diseases so that px=1-qx-ix! However, the ix is not used for the survival present value
calculatePVSurvival = function(px=1-qx, qx=1-px, advance, arrears=c(0), ..., m=1, mCorrection = list(alpha=1, beta=0), v=1) {
# assuming advance and arrears have the same dimensions...
init = advance[1]*0;
l = max(length(q), length(advance), length(arrears));
q = pad0(q, l, value=1);
l = max(length(qx), length(advance), length(arrears));
q = pad0(qx, l, value=1);
p = pad0(px, l, value=0);
advance = pad0(advance, l, value=init);
arrears = pad0(arrears, l, value=init);
......@@ -11,11 +13,10 @@ calculatePVSurvival = function(q, advance, arrears=c(0), ..., m=1, mCorrection =
res = rep(0, l+1);
for (i in l:1) {
# coefficients for the payemtns(including corrections for payments during the year (using the alpha(m) and beta(m)):
p = (1-q[i]);
advcoeff = mCorrection$alpha - mCorrection$beta*(1-p*v);
arrcoeff = mCorrection$alpha - (mCorrection$beta + 1/m)*(1-p*v);
advcoeff = mCorrection$alpha - mCorrection$beta*(1-p[i]*v);
arrcoeff = mCorrection$alpha - (mCorrection$beta + 1/m)*(1-p[i]*v);
# The actual recursion:
res[i] = advance[i]*advcoeff + arrears[i]*arrcoeff + v*(1-q[i])*res[i+1];
res[i] = advance[i]*advcoeff + arrears[i]*arrcoeff + v*p[i]*res[i+1];
}
res[1:l]
}
......@@ -23,9 +24,9 @@ calculatePVSurvival = function(q, advance, arrears=c(0), ..., m=1, mCorrection =
# TODO: So far, we are assuming, the costs array has sufficient time steps and does not need to be padded!
calculatePVCosts = function(q, costs, ..., v=1) {
l = max(length(q), dim(costs)[1]);
q = pad0(q, l, value=1);
calculatePVCosts = function(px=1-qx, qx=1-px, costs, ..., v=1) {
l = max(length(qx), dim(costs)[1]);
p = pad0(px, l, value=0);
costs = costs[1:l,,];
# Take the array structure from the cash flow array and initialize it with 0
......@@ -34,27 +35,48 @@ calculatePVCosts = function(q, costs, ..., v=1) {
# Backward recursion starting from the last time:
for (i in l:1) {
# cat("values at iteration ", i, ": ", v, q[i], costs[i,,], prev);
res[i,,] = costs[i,,] + v*(1-q[i])*prev;
res[i,,] = costs[i,,] + v*p[i]*prev;
prev=res[i,,];
}
res
}
calculatePVDeath = function(q, benefits, ..., v=1) {
calculatePVDeath = function(px, qx, benefits, ..., v=1) {
init = benefits[1]*0; # Preserve the possible array structure of the benefits -> vectorized calculations possible!
l = max(length(qx), length(benefits));
q = pad0(qx, l, value=1);
p = pad0(px, l, value=0);
benefits = pad0(benefits, l, value=init);
# TODO: Make this work for matrices (i.e. currently benefits are assumed to be one-dimensional vectors)
# TODO: Replace loop by better way (using Reduce?)
res = rep(init, l+1);
for (i in l:1) {
# Caution: p_x is not neccessarily 1-q_x, because we might also have dread diseases, so that px=1-qx-ix!
res[i] = v*q[i]*benefits[i] + v*p[i]*res[i+1];
}
res[1:l]
}
calculatePVDisease = function(px=1-qx-ix, qx=1-ix-px, ix=1-px-qx, benefits, ..., v=1) {
init = benefits[1]*0;
l = max(length(q), length(benefits));
q = pad0(q, l, value=1);
l = min(length(ix), length(qx), length(benefits));
qx = pad0(qx, l, value=1);
ix = pad0(ix, l, value=0);
px = pad0(px, l, value=0);
benefits = pad0(benefits, l, value=init);
# TODO: Make this work for matrices (i.e. currently benefits are assumed to be one-dimensional vectors)
# TODO: Replace loop by better way (using Reduce?)
res = rep(init, l+1);
for (i in l:1) {
res[i] = v*q[i]*benefits[i] + v*(1-q[i])*res[i+1];
res[i] = v*ix[i]*benefits[i] + v*px[i]*res[i+1];
}
res[1:l]
}
getSavingsPremium = function(reserves, v=1) {
pad0(reserves[-1], length(reserves))*v - reserves
}
......
......@@ -3,7 +3,7 @@ library(lifecontingencies)
library(objectProperties)
library(foreach)
TariffTypeEnum = setSingleEnum("TariffType", levels = c("annuity", "wholelife", "endowment", "pureendowment", "terme-fix"))
TariffTypeEnum = setSingleEnum("TariffType", levels = c("annuity", "wholelife", "endowment", "pureendowment", "terme-fix", "dread-disease"))
PaymentTimeEnum = setSingleEnum("PaymentTime", levels = c("in advance", "in arrears"))
#PaymentCountEnum = setSingleEnum(PaymentCount, levels = c(1,2,3))
......@@ -39,6 +39,7 @@ InsuranceTarif = R6Class(
states = c("alive", "dead"),
mortalityTable = NULL,
invalidityTable = NULL,
i = 0, # guaranteed interest rate
v = 1, # discount factor
tariffType = TariffTypeEnum("wholelife"), # possible values: annuity, wholelife, endowment, pureendowment, terme-fix
......@@ -74,7 +75,7 @@ InsuranceTarif = R6Class(
),
initialize = function(name = NULL, mortalityTable = NULL, i = NULL, type = "wholelife", ..., features = list(), premiumPeriod = NULL, premiumFrequencyOrder = 0, benefitFrequencyOrder = 0, costs, surrenderValueCalculation) {
initialize = function(name = NULL, mortalityTable = NULL, i = NULL, type = "wholelife", ..., invalidityTable=NULL, features = list(), premiumPeriod = NULL, premiumFrequencyOrder = 0, benefitFrequencyOrder = 0, costs, surrenderValueCalculation) {
if (!missing(name)) self$name = name;
if (!missing(mortalityTable)) self$mortalityTable = mortalityTable;
if (!missing(i)) self$i = i;
......@@ -86,11 +87,18 @@ InsuranceTarif = R6Class(
if (!missing(premiumPeriod)) self$defaultPremiumPeriod = premiumPeriod;
if (!missing(features)) self$features = c(features, self$features);
if (!missing(surrenderValueCalculation)) self$surrenderValueCalculation = surrenderValueCalculation;
if (!missing(invalidityTable)) self$invalidityTable = invalidityTable;
self$v = 1/(1+self$i);
cat(paste0("Initializing Insurance Tarif ", self$name, "...\n"));
},
# Merge a possibly passed loadings override with this tariff's default loadings:
getLoadings = function(..., loadings=list()) {
c(loadings, self$loadings)
},
getAges = function(age, ..., YOB = 2000) {
ages = ages(self$mortalityTable, YOB = YOB);
if (age > 0) {
......@@ -104,7 +112,16 @@ InsuranceTarif = R6Class(
if (age > 0) {
q = q[-age:-1];
}
df = data.frame(age=ages, q=q, p=1-q, row.names = ages-age)
if (!is.null(self$invalidityTable)) {
i = deathProbabilities(self$invalidityTable, YOB=YOB);
if (age > 0) {
i = i[-age:-1];
}
} else {
i = rep(0, length(q));
}
i = pad0(i, length(q));
df = data.frame(age=ages, q=q, i=i, p=1-q-i, row.names = ages-age)
df
},
getBasicCashFlows = function(age, ..., guaranteed = 0, policyPeriod = inf, deferral = 0, maxAge = getOmega(self$mortalityTable)) {
......@@ -112,7 +129,8 @@ InsuranceTarif = R6Class(
cf = list(
guaranteed = rep(0, maxlen+1),
survival = rep(0, maxlen+1),
death = rep(0, maxlen+1)
death = rep(0, maxlen+1),
disease = rep(0, maxlen+1)
);
if (self$tariffType == "annuity") {
# guaranteed payments exist only with annuities (first n years of the payment)
......@@ -120,6 +138,8 @@ InsuranceTarif = R6Class(
cf$survival = c(rep(0, deferral + guaranteed), rep(1, max(0, maxlen - deferral - guaranteed)), 0)
} else if (self$tariffType == "terme-fix") {
cf$guaranteed = c(rep(0, policyPeriod), 1);
} else if (self$tariffType == "dread-disease") {
cf$disease = c(rep(0, deferral), rep(1, maxlen - deferral), 0);
} else {
if (self$tariffType == "endowment" || self$tariffType == "pureendowment") {
cf$survival = c(rep(0, policyPeriod), 1);
......@@ -147,6 +167,7 @@ InsuranceTarif = R6Class(
survival_advance = zeroes,
survival_arrears = zeroes,
death_SumInsured = zeroes,
disease_SumInsured = zeroes,
death_GrossPremium = zeroes,
death_Refund_past = zeroes,
death_PremiumFree = zeroes,
......@@ -172,6 +193,7 @@ InsuranceTarif = R6Class(
# Death Benefits
cf$death_SumInsured = pad0(basicCashFlows$death, cflen);
cf$disease_SumInsured = pad0(basicCashFlows$disease, cflen);
cf$death_PremiumFree = cf$death_SumInsured;
# premium refund
if (self$premiumRefund != 0) {
......@@ -212,23 +234,27 @@ InsuranceTarif = R6Class(
presentValueCashFlows = function(cashflows, age, ..., premiumFrequency = 1, benefitFrequency = 1, maxAge = getOmega(self$mortalityTable)) {
len = length(cashflows$premiums_advance);
qq = self$getTransitionProbabilities (age, ...);
q = pad0(qq$q, len);
qx = pad0(qq$q, len);
ix = pad0(qq$i, len);
px = pad0(qq$p, len);
benefitFrequencyCorrection = correctionPaymentFrequency(m = benefitFrequency, i = self$i, order = self$benefitFrequencyOrder);
premiumFrequencyCorrection = correctionPaymentFrequency(m = premiumFrequency, i = self$i, order = self$premiumFrequencyOrder);
pvRefund = calculatePVDeath (q, cashflows$death_GrossPremium, v=self$v);
pvRefundPast = calculatePVDeath (q, cashflows$death_Refund_past, v=self$v) * (cashflows[,"death_GrossPremium"]-cashflows[,"premiums_advance"]);
pvRefund = calculatePVDeath (px, qx, cashflows$death_GrossPremium, v=self$v);
pvRefundPast = calculatePVDeath (px, qx, cashflows$death_Refund_past, v=self$v) * (cashflows[,"death_GrossPremium"]-cashflows[,"premiums_advance"]);
pv = cbind(
premiums = calculatePVSurvival (q, cashflows$premiums_advance, cashflows$premiums_arrears, m=premiumFrequency, mCorrection=premiumFrequencyCorrection, v=self$v),
guaranteed = calculatePVSurvival (q*0, cashflows$guaranteed_advance, cashflows$guaranteed_arrears, m=benefitFrequency, mCorrection=benefitFrequencyCorrection, v=self$v),
survival = calculatePVSurvival (q, cashflows$survival_advance, cashflows$survival_arrears, m=benefitFrequency, mCorrection=benefitFrequencyCorrection, v=self$v),
death_SumInsured = calculatePVDeath (q, cashflows$death_SumInsured, v=self$v),
premiums = calculatePVSurvival (px, qx, cashflows$premiums_advance, cashflows$premiums_arrears, m=premiumFrequency, mCorrection=premiumFrequencyCorrection, v=self$v),
guaranteed = calculatePVSurvival (px/px, qx*0, cashflows$guaranteed_advance, cashflows$guaranteed_arrears, m=benefitFrequency, mCorrection=benefitFrequencyCorrection, v=self$v),
survival = calculatePVSurvival (px, qx, cashflows$survival_advance, cashflows$survival_arrears, m=benefitFrequency, mCorrection=benefitFrequencyCorrection, v=self$v),
death_SumInsured = calculatePVDeath (px, qx, cashflows$death_SumInsured, v=self$v),
disease_SumInsured = calculatePVDisease(px, qx, ix, cashflows$disease_SumInsured, v=self$v),
death_GrossPremium = pvRefund,
death_Refund_past = pvRefundPast,
death_Refund_future = pvRefund - pvRefundPast,
death_PremiumFree = calculatePVDeath (q, cashflows$death_PremiumFree, v=self$v)
death_PremiumFree = calculatePVDeath (px, qx, cashflows$death_PremiumFree, v=self$v)
);
rownames(pv) <- pad0(rownames(qq), len);
pv
},
......@@ -236,9 +262,10 @@ InsuranceTarif = R6Class(
presentValueCashFlowsCosts = function(cashflows, age, ..., maxAge = getOmega(self$mortalityTable)) {
len = dim(cashflows)[1];
q = self$getTransitionProbabilities (age, ...);
q = pad0(q$q, len);
qx = pad0(q$q, len);
px = pad0(q$p, len);
pvc = calculatePVCosts(q, cashflows, v=self$v);
pvc = calculatePVCosts(px, qx, cashflows, v=self$v);
pvc
},
......@@ -257,10 +284,11 @@ InsuranceTarif = R6Class(
getAbsCashFlows = function(cashflows, cashflowsCosts, premiums, sumInsured=1, premiumSum=0, ...) {
refundAddon = self$premiumRefundLoading;
# TODO: Set up a nice list with coefficients for each type of cashflow, rather than multiplying each item manually (this also mitigates the risk of forgetting a dimension, because then the dimensions would not match, while here it's easy to overlook a multiplication)
# Multiply each CF column by the corresponding basis
cashflows[,c("premiums_advance", "premiums_arrears")] = cashflows[,c("premiums_advance", "premiums_arrears")] * premiums[["gross"]];
cashflows[,c("guaranteed_advance", "guaranteed_arrears", "survival_advance", "survival_arrears", "death_SumInsured", "death_PremiumFree")] =
cashflows[,c("guaranteed_advance", "guaranteed_arrears", "survival_advance", "survival_arrears", "death_SumInsured", "death_PremiumFree")] * sumInsured;
cashflows[,c("guaranteed_advance", "guaranteed_arrears", "survival_advance", "survival_arrears", "death_SumInsured", "death_PremiumFree", "disease_SumInsured")] =
cashflows[,c("guaranteed_advance", "guaranteed_arrears", "survival_advance", "survival_arrears", "death_SumInsured", "death_PremiumFree", "disease_SumInsured")] * sumInsured;
cashflows[,c("death_GrossPremium", "death_Refund_past")] = cashflows[,c("death_GrossPremium","death_Refund_past")] * premiums[["gross"]] * (1+refundAddon);
# Sum all death-related payments to "death" and remove the death_GrossPremium column
......@@ -284,8 +312,8 @@ InsuranceTarif = R6Class(
# Multiply each CF column by the corresponding basis
pv[,"premiums"] = pv[,"premiums"] * premiums[["gross"]];
pv[,c("guaranteed", "survival", "death_SumInsured", "death_PremiumFree")] =
pv[,c("guaranteed", "survival", "death_SumInsured", "death_PremiumFree")] * sumInsured;
pv[,c("guaranteed", "survival", "death_SumInsured", "disease_SumInsured", "death_PremiumFree")] =
pv[,c("guaranteed", "survival", "death_SumInsured", "disease_SumInsured", "death_PremiumFree")] * sumInsured;
pv[,c("death_GrossPremium", "death_Refund_past", "death_Refund_future")] = pv[,c("death_GrossPremium", "death_Refund_past", "death_Refund_future")] * premiums[["gross"]] * (1+refundAddon);
pv[,c("benefits", "benefitsAndRefund", "alpha", "Zillmer", "beta", "gamma", "gamma_nopremiums")] =
pv[,c("benefits", "benefitsAndRefund", "alpha", "Zillmer", "beta", "gamma", "gamma_nopremiums")] * sumInsured;
......@@ -301,8 +329,8 @@ InsuranceTarif = R6Class(
presentValueBenefits = function(presentValues, presentValuesCosts, premiums, sumInsured=1, premiumSum=0, ...) {
refundAddon = self$premiumRefundLoading;
# TODO: Here we don't use the securityLoading parameter => Shall it be used or are these values to be understood without additional security loading?
benefits = presentValues[,"survival"] + presentValues[,"death_SumInsured"];
allBenefits = presentValues[,"survival"] + presentValues[,"death_SumInsured"] + presentValues[,"death_GrossPremium"] * premiums[["unit.gross"]] * (1+refundAddon);
benefits = presentValues[,"survival"] + presentValues[,"death_SumInsured"] + presentValues[,"disease_SumInsured"];
allBenefits = presentValues[,"survival"] + presentValues[,"death_SumInsured"] + presentValues[,"disease_SumInsured"] + presentValues[,"death_GrossPremium"] * premiums[["unit.gross"]] * (1+refundAddon);
benefitsCosts = presentValuesCosts[,,"SumInsured"] +
presentValuesCosts[,,"SumPremiums"] * premiumSum * premiums[["unit.gross"]] +
......@@ -331,6 +359,8 @@ InsuranceTarif = R6Class(
coeff[["SumInsured"]][["benefits"]][["guaranteed"]] = 1+securityLoading;
coeff[["SumInsured"]][["benefits"]][["survival"]] = 1+securityLoading;
coeff[["SumInsured"]][["benefits"]][["death_SumInsured"]] = 1+securityLoading;
coeff[["SumInsured"]][["benefits"]][["disease_SumInsured"]] = 1+securityLoading;
# Premium refund is handled differently for gross and net premiums, because it is proportional to the gross premium
if (type == "gross") {
coeff[["Premium"]][["benefits"]][["death_GrossPremium"]] = -(1+refundAddon) * (1+securityLoading);
......@@ -496,7 +526,8 @@ InsuranceTarif = R6Class(
l = dim(reserves)[[1]];
premium.savings = getSavingsPremium(reserves[,"Zillmer"], self$v) + getSavingsPremium(reserves[,"gamma"], self$v);
# TODO: Switch to use the Ziller or net or adequate reserve!
premium.risk = self$v * (cashflows[,"death"] - c(reserves[,"Zillmer"][-1], 0)) * pad0(q$q, l);
premium.risk = self$v * (cashflows[,"death"] - c(reserves[,"Zillmer"][-1], 0)) * pad0(q$q, l) +
self$v * (cashflows[,"disease_SumInsured"] - c(reserves[,"Zillmer"][-1], 0)) * pad0(q$i, l);
# premium.risk = self$v * (cashflows[,"death"] - c(reserves[,"Zillmer"][-1], 0)) * q$q;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment