Dr Patrick J. Laub @ IME, München
Université Lyon 1
Stochastic Models (2019), 34(4), 1-12.
Can read on https://arxiv.org/pdf/1803.00273.pdf
Guaranteed Minimum Death Benefit
High Water Death Benefit
The customer lives for years,
Equity is an exponential jump diffusion,
Use fixed-point approximation
Markov chain State space
Markov chain State space
As meaningless mathematical artefacts
Choose number of phases to balance accuracy and over-fitting
As states which reflect some part of reality
Choose number of phases to match reality
X.S. Lin & X. Liu (2007) Markov aging process and phase-type law of mortality.
N. Amer. Act J. 11, pp. 92-109
M. Govorun, G. Latouche, & S. Loisel (2015). Phase-type aging modeling for health dependent costs. Insurance: Mathematics and Economics, 62, pp. 173-183.
Matrix exponential
Density and tail
Moments
Laplace transform
S. Asmussen (2003), Applied Probability and Queues, 2nd Edition, Springer
Closure under addition, minimum, maximum
... and under conditioning
Can make a phase-type look like a constant value
Payout occurs at death or after fixed duration T, whichever first
Assume:
Then and are independent and exponentially distributed with rates
Doesn't work for non-random time
Traditionally, using EM algorithm
Bladt, M., Gonzalez, A. and Lauritzen, S. L. (2003), ‘The estimation of Phase-type related functionals using Markov chain Monte Carlo methods’, Scandinavian Actuarial Journal
Also, not easy to tell if any parameters produce a valid distribution
Bowers et al (1997), Actuarial Mathematics, 2nd Edition
"E" step has a bazillion matrix exponential calculations
void rungekutta(int p, double *avector, double *gvector, double *bvector,
double **cmatrix, double dt, double h, double **T, double *t,
double **ka, double **kg, double **kb, double ***kc)
{
int i, j, k, m;
double eps, h2, sum;
i = dt/h;
h2 = dt/(i+1);
init_matrix(ka, 4, p);
init_matrix(kb, 4, p);
init_3dimmatrix(kc, 4, p, p);
if (kg != NULL)
init_matrix(kg, 4, p);
...
for (i=0; i < p; i++) {
avector[i] += (ka[0][i]+2*ka[1][i]+2*ka[2][i]+ka[3][i])/6;
bvector[i] += (kb[0][i]+2*kb[1][i]+2*kb[2][i]+kb[3][i])/6;
for (j=0; j < p; j++)
cmatrix[i][j] +=(kc[0][i][j]+2*kc[1][i][j]+2*kc[2][i][j]+kc[3][i][j])/6;
}
}
}
This function: 116 lines of C, built-in to Julia
Whole program: 1700 lines of C, 300 lines of Julia
# Run the ODE solver.
u0 = zeros(p*p)
pf = ParameterizedFunction(ode_observations!, fit)
prob = ODEProblem(pf, u0, (0.0, maximum(s.obs)))
sol = solve(prob, OwrenZen5())
https://github.com/Pat-Laub/EMpht.jl
# Run the ODE solver.
u0 = zeros(p*p)
pf = ParameterizedFunction(ode_observations!, fit)
prob = ODEProblem(pf, u0, (0.0, maximum(s.obs)))
sol = solve(prob, OwrenZen5())
...
u = sol(s.obs[k])
C = reshape(u, p, p)
if minimum(C) < 0
(C,err) = hquadrature(p*p, (x,v) -> c_integrand(x, v, fit, s.obs[k]),
0, s.obs[k], reltol=1e-1, maxevals=500)
C = reshape(C, p, p)
end
Canonical form 1
using Pkg; Pkg.add("EMpht")
using EMpht
lt = EMpht.parse_settings("life_table.json")[1]
phCF200 = empht(lt, p=200, ph_structure="CanonicalForm1")
Remember to try Julia
Thanks for listening!