Abstract
Les contingences de vie constituent un enjeu majeur en actuariat, notamment pour la tarification des assurances vie et des rentes viagères. Ce projet vise à modéliser ces contingences en utilisant des approches mathématiques et des outils de programmation. Nous nous appuierons sur des bases de données actuarielles, incluant les tables de mortalité et les taux d’intérêt, pour implémenter et analyser différents modèles actuariels. L’étude combinera une approche théorique, incluant les probabilités de survie et les calculs de provisions mathématiques, avec une approche pratique basée sur la programmation pour tester et calibrer ces modèles. Les résultats obtenus permettront d’évaluer l’impact des hypothèses actuarielles sur la gestion des risques et d’optimiser les décisions en matière d’assurance.L’étude des contingences de vie constitue un pilier fondamental de la science actuarielle, en particulier dans le domaine de l’assurance vie. Ce projet a pour objectif d’explorer les principaux concepts liés à la modélisation des risques de durée de vie humaine, en s’appuyant sur les outils mathématiques et statistiques adaptés. Il s’articule autour de plusieurs axes essentiels : l’analyse de tables de mortalité, le calcul des fonctions de commutation, la tarification de produits d’assurance vie, ainsi que l’évaluation des réserves mathématiques.
L’ensemble des travaux repose sur le langage R, et notamment sur le
package lifecontingencies, qui permet de manipuler
efficacement les données actuarielle. Enfin, une approche de simulation
de portefeuilles d’assurance vie sera présentée, afin d’illustrer
concrètement la dynamique des flux de primes et de prestations dans un
cadre réaliste.
Ce projet vise ainsi à fournir une compréhension approfondie des mécanismes techniques et financiers de l’assurance vie, tout en développant des compétences pratiques en programmation actuarielle.
L’analyse des risques liés à la vie, important pour l’assureur lors de la souscription d’un contrat d’assurance-vie, commence par la modélisation de la durée de vie d’un individu. Ces modèles doivent ensuite être calibrés à partir de données de mortalité réelles et pertinentes.
Ainsi, dans cette première partie nous présentons d’abord différents types de données qui décrivent les durées de vie et la mortalité d’une certaine population.
Nous introduisons ensuite le cadre conventionnel de la modélisation des durées de vie, en particulier en présentant le concept de variable aléatoire de durée de vie future \(T_x\) et ses propriétés. Nous explorons ensuite différentes approches pour spécifier et estimer sa distribution. Nous abordons ici les modèles actuariels traditionnels des durées de vie, tels que les lois analytiques de mortalité et les tables de mortalité, mais nous présentons également des modèles prédictifs conditionnels qui caractérisent la distribution des durées de vie en fonction d’un ensemble de covariables ou de caractéristiques.
Pour une réponse approximative sur la durée de vie d’un individu, on peut se référer aux statistiques démographiques publiques. Nous allons nous référer aux statistiques françaises présentes dans la Human Mortality Database (HMD) .
On présente dans le tableau 1.1. la table de vie de 1816 à 2022 :
# On importe la table
table <- read.table("~/Downloads/FRATNP/STATS/bltper_1x1.txt", header = TRUE, sep = "", stringsAsFactors = FALSE, fill = TRUE)
# Et on la visualise
kable(head(table, 15), format = "html", align = "r", caption="Table 1.1 : Table de vie, France, 1816 - 2022, HMD")%>%
kable_styling(bootstrap_options = c("striped", "hover", "bordered", "condensed"), full_width = FALSE)
| Year | Age | mx | qx | ax | lx | dx | Lx | Tx | ex |
|---|---|---|---|---|---|---|---|---|---|
| 1816 | 0 | 0.20534 | 0.17972 | 0.31 | 100000 | 17972 | 87524 | 4009912 | 40.10 |
| 1816 | 1 | 0.04669 | 0.04562 | 0.50 | 82028 | 3742 | 80156 | 3922388 | 47.82 |
| 1816 | 2 | 0.03412 | 0.03355 | 0.50 | 78285 | 2626 | 76972 | 3842232 | 49.08 |
| 1816 | 3 | 0.02304 | 0.02277 | 0.50 | 75659 | 1723 | 74798 | 3765260 | 49.77 |
| 1816 | 4 | 0.01604 | 0.01591 | 0.50 | 73936 | 1176 | 73348 | 3690462 | 49.91 |
| 1816 | 5 | 0.01373 | 0.01364 | 0.50 | 72760 | 992 | 72264 | 3617114 | 49.71 |
| 1816 | 6 | 0.01186 | 0.01179 | 0.50 | 71768 | 846 | 71344 | 3544850 | 49.39 |
| 1816 | 7 | 0.01016 | 0.01011 | 0.50 | 70921 | 717 | 70563 | 3473506 | 48.98 |
| 1816 | 8 | 0.00864 | 0.00860 | 0.50 | 70204 | 604 | 69902 | 3402943 | 48.47 |
| 1816 | 9 | 0.00734 | 0.00732 | 0.50 | 69601 | 509 | 69346 | 3333041 | 47.89 |
| 1816 | 10 | 0.00615 | 0.00613 | 0.50 | 69091 | 423 | 68880 | 3263695 | 47.24 |
| 1816 | 11 | 0.00529 | 0.00528 | 0.50 | 68668 | 362 | 68487 | 3194815 | 46.53 |
| 1816 | 12 | 0.00478 | 0.00476 | 0.50 | 68306 | 325 | 68143 | 3126328 | 45.77 |
| 1816 | 13 | 0.00464 | 0.00463 | 0.50 | 67980 | 315 | 67823 | 3058186 | 44.99 |
| 1816 | 14 | 0.00488 | 0.00486 | 0.50 | 67666 | 329 | 67501 | 2990363 | 44.19 |
Comme on peut le voir dans ce tableau, les données contiennent les colonnes \(m_x\) ,\(q_x\) ,\(l_x\) , \(e_x\) utiles pour l’analyse démographique :
| Colonne | Description |
|---|---|
| \(m_x\) | Taux de mortalité |
| \(q_x\) | Probabilité de décéder entre l’âge \(x\) et \(x+1\) |
| \(l_x\) | Nombre de survivants à l’âge \(x\) |
| \(d_x\) | Nombre de décès entre les âges \(x\) et \(x+1\) (\(d_x = l_x \times q_x\)) |
| \(e_x\) | Espérance de vie restante à l’âge \(x\) |
Ces variables sont essentielles pour construire des tables de mortalité, visualiser les dynamiques de survie, et calculer des indicateurs démographiques différents âges.
Faisons une petite analyse exploratoire des données. Commençons par-exemple par filtrer seulement l’année 2018 :
# Filtrage pour une seule année (2018)
data_2018 <- subset(table, Year == 2018)
data_2018$Age <- as.numeric(data_2018$Age)
## Warning: NAs introduced by coercion
#On enlève la colonne année qui devient obsolète
data_2018$Year <- NULL
#Affichage des premières valeurs
kable(head(data_2018, 30), align = "r", caption="Table 1.2 : Table de vie de l'année 2018", row.names = FALSE)%>%
kable_styling(bootstrap_options = c("striped", "hover", "bordered", "condensed"), full_width = FALSE)
| Age | mx | qx | ax | lx | dx | Lx | Tx | ex |
|---|---|---|---|---|---|---|---|---|
| 0 | 0.00382 | 0.00380 | 0.14 | 100000 | 380 | 99673 | 8256738 | 82.57 |
| 1 | 0.00025 | 0.00025 | 0.50 | 99620 | 25 | 99607 | 8157065 | 81.88 |
| 2 | 0.00016 | 0.00016 | 0.50 | 99594 | 16 | 99586 | 8057458 | 80.90 |
| 3 | 0.00012 | 0.00012 | 0.50 | 99578 | 12 | 99572 | 7957872 | 79.92 |
| 4 | 0.00011 | 0.00011 | 0.50 | 99566 | 11 | 99561 | 7858300 | 78.93 |
| 5 | 0.00008 | 0.00008 | 0.50 | 99556 | 8 | 99552 | 7758739 | 77.93 |
| 6 | 0.00008 | 0.00008 | 0.50 | 99548 | 8 | 99544 | 7659187 | 76.94 |
| 7 | 0.00006 | 0.00006 | 0.50 | 99540 | 6 | 99537 | 7559643 | 75.95 |
| 8 | 0.00007 | 0.00007 | 0.50 | 99534 | 7 | 99531 | 7460106 | 74.95 |
| 9 | 0.00007 | 0.00007 | 0.50 | 99527 | 7 | 99524 | 7360576 | 73.96 |
| 10 | 0.00007 | 0.00007 | 0.50 | 99521 | 7 | 99517 | 7261052 | 72.96 |
| 11 | 0.00007 | 0.00007 | 0.50 | 99513 | 7 | 99510 | 7161535 | 71.97 |
| 12 | 0.00009 | 0.00009 | 0.50 | 99507 | 9 | 99502 | 7062025 | 70.97 |
| 13 | 0.00009 | 0.00009 | 0.50 | 99498 | 9 | 99494 | 6962523 | 69.98 |
| 14 | 0.00011 | 0.00011 | 0.50 | 99489 | 11 | 99484 | 6863029 | 68.98 |
| 15 | 0.00015 | 0.00015 | 0.50 | 99478 | 15 | 99471 | 6763546 | 67.99 |
| 16 | 0.00018 | 0.00018 | 0.50 | 99463 | 18 | 99454 | 6664075 | 67.00 |
| 17 | 0.00020 | 0.00020 | 0.50 | 99445 | 20 | 99435 | 6564621 | 66.01 |
| 18 | 0.00027 | 0.00027 | 0.50 | 99425 | 27 | 99412 | 6465187 | 65.03 |
| 19 | 0.00034 | 0.00034 | 0.50 | 99398 | 34 | 99381 | 6365775 | 64.04 |
| 20 | 0.00035 | 0.00035 | 0.50 | 99364 | 35 | 99347 | 6266394 | 63.06 |
| 21 | 0.00043 | 0.00043 | 0.50 | 99329 | 43 | 99308 | 6167047 | 62.09 |
| 22 | 0.00038 | 0.00038 | 0.50 | 99287 | 38 | 99268 | 6067739 | 61.11 |
| 23 | 0.00040 | 0.00040 | 0.50 | 99249 | 40 | 99229 | 5968471 | 60.14 |
| 24 | 0.00043 | 0.00043 | 0.50 | 99209 | 42 | 99188 | 5869242 | 59.16 |
| 25 | 0.00046 | 0.00046 | 0.50 | 99167 | 45 | 99144 | 5770055 | 58.19 |
| 26 | 0.00043 | 0.00043 | 0.50 | 99121 | 43 | 99100 | 5670911 | 57.21 |
| 27 | 0.00041 | 0.00041 | 0.50 | 99079 | 41 | 99058 | 5571811 | 56.24 |
| 28 | 0.00044 | 0.00044 | 0.50 | 99038 | 44 | 99016 | 5472752 | 55.26 |
| 29 | 0.00056 | 0.00056 | 0.50 | 98994 | 56 | 98966 | 5373736 | 54.28 |
Pour avoir un aperçu plus clair, traçons le plot du taux de mortalité par-rapport à l’âge pour cette année :
#Tracer mx en fonction de l'âge
plot(data_2018$Age, data_2018$mx, type = "l", xlab = "Âge", ylab = "Taux de mortalité (mx)", main = "Figure 1.1 : Taux de mortalité pour l'année 2018")
On peut ajouter lx le nombre d’individus d’âge x :
La figure 1.2 illustre clairement la dynamique du taux de mortalité pour la cohorte née en 2018. On constate une mortalité un peu plus élevée à la naissance, le taux diminuant fortement durant l’enfance, se stabilisant à l’âge adulte, puis augmente progressivement à partir de 60 ans, traduisant les effets du vieillissement.
Actuellement, dans les pays développés et dans les pays en voie de développement, les gens vivent plus longtemps comparativement aux années précédentes. Voyons si les données le confirment :
data <- table
# Nettoyage : supprimer les lignes "110+"
data <- subset(data, Age != "110+")
# Conversion d'Age en numérique
data$Age <- as.numeric(data$Age)
# Filtrer l'espérance de vie à la naissance pour 1816 et 2022
ex_birth <- subset(data, Age == 0 & Year %in% c(1816, 2022), select = c("Year", "ex"))
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
L’espérance de vie à la naissance a donc plus que doublé depuis 1816 !
Il y a plusieurs facteurs qui contribuent à l’allongement de la durée de vie : les conditions de vie s’améliorent, le travail est moins pénible et la médecine moderne permets de lutter contre les maladies.
Le taux de mortalité infantile est le nombre d’enfants qui meurent durant la première année de leur vie.
On peut constater une baisse significative du taux de mortalité infantile en France au cours de deux derniers siècles. Cette baisse s’explique non seulement par le succès remporté par la vaccination contre la variole, l’une des grandes causes de décès d’enfants au 18e siècle, mais aussi par l’amélioration des méthodes d’accouchement et des premiers soins donnés au nouveau-né.
Cependant, le nombre de décès infantiles a augmenté lors de certaines années, comme durant les épidémies de choléra, de la grippe espagnole, ou durant les deux guerres mondiales. Le pic durant l’épidémie du covid n’est pas significatif.
D’un point de vue actuariel, une question pertinente pourrait être de savoir comment modéliser les données de mortalité. En d’autres termes, existe-t-il un modèle paramétrique simple qui pourrait décrire l’évolution de l’espérance de vie en fonction de l’âge, du moins dans le contexte d’une population particulière ? Nous reviendrons sur cette question dans le cadre de nos modèles de mortalité, notamment à la section 2.3.
Nous prenons maintenant en considération l’exposition au risque des populations observées au fil du temps, disponible dans la Human Mortality Database (HMD) pour un grand nombre de pays.
Nous allons importer la table d’exposition au risque, c’est-à-dire le nombre de personnes effectivement à risque d’un événement (ici, le décès) durant chaque année.
table_risque <- read.table("~/Downloads/exposures/Exposures_1x1/FRATNP.Exposures_1x1.txt", header = TRUE, sep = "", stringsAsFactors = FALSE, fill = TRUE)
kable(head(table_risque, 15), format = "html", align = "r", caption="Table 1.3 : Table d'exposition au risque, France, 1816 - 2022, HMD")%>%
kable_styling(bootstrap_options = c("striped", "hover", "bordered", "condensed"), full_width = FALSE)
| Year | Age | Female | Male | Total |
|---|---|---|---|---|
| 1816 | 0 | 408224.2 | 426130.4 | 834354.6 |
| 1816 | 1 | 382452.1 | 399821.1 | 782273.2 |
| 1816 | 2 | 351454.0 | 363400.9 | 714854.9 |
| 1816 | 3 | 337733.1 | 349089.9 | 686823.1 |
| 1816 | 4 | 331575.9 | 342626.6 | 674202.5 |
| 1816 | 5 | 313554.0 | 326521.4 | 640075.4 |
| 1816 | 6 | 306853.2 | 323499.7 | 630352.9 |
| 1816 | 7 | 301860.4 | 318097.4 | 619957.8 |
| 1816 | 8 | 296638.6 | 312456.8 | 609095.5 |
| 1816 | 9 | 289057.3 | 304312.7 | 593370.0 |
| 1816 | 10 | 289241.7 | 297433.9 | 586675.6 |
| 1816 | 11 | 288732.0 | 290416.9 | 579148.9 |
| 1816 | 12 | 286347.7 | 287943.6 | 574291.4 |
| 1816 | 13 | 284360.2 | 285914.9 | 570275.1 |
| 1816 | 14 | 283227.9 | 284839.9 | 568067.8 |
Importons également la table de morts de la population française :
table_mort <- read.table("~/Downloads/FRATNP/STATS/Deaths_1x1.txt", header = TRUE, sep = "", stringsAsFactors = FALSE, fill = TRUE)
kable(head(table_mort, 15), format = "html", align = "r", caption="Table 1.4 : Table de morts, France, 1816 - 2022, HMD")%>%
kable_styling(bootstrap_options = c("striped", "hover", "bordered", "condensed"), full_width = FALSE)
| Year | Age | Female | Male | Total |
|---|---|---|---|---|
| 1816 | 0 | 76332.26 | 94997.54 | 171329.80 |
| 1816 | 1 | 17861.24 | 18659.46 | 36520.70 |
| 1816 | 2 | 11924.14 | 12466.99 | 24391.13 |
| 1816 | 3 | 7738.20 | 8083.03 | 15821.23 |
| 1816 | 4 | 5303.44 | 5507.60 | 10811.04 |
| 1816 | 5 | 4337.85 | 4452.23 | 8790.08 |
| 1816 | 6 | 3713.46 | 3763.08 | 7476.54 |
| 1816 | 7 | 3148.26 | 3151.67 | 6299.93 |
| 1816 | 8 | 2642.28 | 2618.03 | 5260.31 |
| 1816 | 9 | 2195.49 | 2162.13 | 4357.62 |
| 1816 | 10 | 1818.15 | 1788.04 | 3606.19 |
| 1816 | 11 | 1551.24 | 1511.93 | 3063.17 |
| 1816 | 12 | 1404.98 | 1337.84 | 2742.82 |
| 1816 | 13 | 1379.41 | 1265.77 | 2645.18 |
| 1816 | 14 | 1474.51 | 1295.73 | 2770.24 |
On peut comparer les graphiques de décès et d’exposition au risque en les mettant côte à côte :
deaths <- table_mort
exposures <- table_risque
# Agrégation annuelle
deaths_agg <- deaths %>%
group_by(Year) %>%
summarise(Deaths = sum(Total, na.rm = TRUE))
exposures_agg <- exposures %>%
group_by(Year) %>%
summarise(Exposures = sum(Total, na.rm = TRUE))
# 1. Graphique des décès
p <-ggplot(deaths_agg, aes(x = Year, y = Deaths)) +
geom_line(color = "firebrick", size = 1.2) +
labs(
title = "Figure 1.7 : Décès",
subtitle = "France (1816–2022)",
x = "Année",
y = "Nombre de décès"
) +
scale_y_continuous(labels = scales::comma) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold"),
plot.subtitle = element_text(color = "gray30"),
plot.caption = element_text(color = "gray40")
)
# 2. Graphique de l’exposition
q <- ggplot(exposures_agg, aes(x = Year, y = Exposures)) +
geom_line(color = "steelblue", size = 1.2) +
labs(
title = "Exposition au risque",
x = "Année",
y = "Personnes exposées",
caption = "Source : Human Mortality Database"
) +
scale_y_continuous(labels = scales::comma) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold"),
plot.subtitle = element_text(color = "gray30"),
plot.caption = element_text(color = "gray40")
)
p+q
On a déjà expliqué les pics de mortalité et la baisse générale du nombre de décès. On observe bien ici un pic de mortalité à cause du COVID, contrairement aux mortalités infantiles, car ce dernier a plus affecté la population générale que celle des nouveaux-nés. Le nombre de personnes exposées au risques augmente car il reflète l’augmentation de la population française et a explosé en \(1945\) à cause du baby-boom et du redémarrage économique. Depuis les années 1990–2000, la croissance ralentit, voire se stabilise par moments. Cela peut refléter les dynamiques actuelles de fécondité, de vieillissement, et d’immigration.
On peut également par-exemple tracer l’évolution du taux de mortalité pour une femme de \(70\) ans :
# Filtrer pour l'âge 70 et sexe "f" (femme)
deaths_f70 <- deaths %>%
filter(Age == 70) %>%
select(Year, Deaths = Female)
expo_f70 <- exposures %>%
filter(Age == 70) %>%
select(Year, Exposure = Female)
# Fusion et calcul du taux de mortalité
mortality_f70 <- left_join(deaths_f70, expo_f70, by = "Year") %>%
mutate(mx = Deaths / Exposure)
# Tracer le taux de mortalité
ggplot(mortality_f70, aes(x = Year, y = mx)) +
geom_line(color = "darkred", size = 1.2) +
labs(
title = "Figure 1.8 : Evolution du taux de mortalité ",
subtitle = "Femmes de 70 ans",
x = "Année",
y = "Taux de mortalité",
caption = "Source : Human Mortality Database"
) +
scale_y_continuous(labels = scales::percent_format(accuracy = 0.1)) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold"),
plot.subtitle = element_text(color = "gray30"),
plot.caption = element_text(color = "gray40")
)
La probabilité de mourir pour une femme de \(70\) ans est passé sous la barre symbolique des \(2\%\) dans les années \(70\) : la population assurable est donc de plus en plus importante.
On peut également observer le taux de mortalité suivant l’âge au cours de l’année \(2010\):
# Lecture des fichiers à largeur fixe
colspecs <- fwf_cols(
Year = c(1, 6),
Age = c(7, 17),
Female = c(18, 33),
Male = c(34, 49),
Total = c(50, 65)
)
# Sélection année 2010
deaths_2010 <- deaths[deaths$Year == 2010, ]
expo_2010 <- exposures[exposures$Year == 2010, ]
# Calcul du taux de mortalité
mx_fem_2010 <- deaths_2010$Female / expo_2010$Female
# Tracer
plot(mx_fem_2010,
type = "l",
lwd = 3,
col = "darkblue",
main = "Figure 1.9 :Taux de mortalité par âge",
xlab = "Age",
ylab = "Taux de mortalité",
ylim = c(0,0.8))
# Ajouter ligne rouge à 2%
abline(h = 0.02, col = "red", lty = 2, lwd = 2)
text(x = length(mx_fem_2010) - 7, y = 0.05, labels = "2% de mortalité", col = "red", cex = 0.8)
# Ajouter sous-titre et caption
mtext("Source : Human Mortality Database (France, données 5x1)", side = 1, line = 6, cex = 0.8, adj = 0)
mtext("Femmes, 2010, France", side = 3, line = 0.5, cex = 0.9, font = 3)
On observe que le taux de mortalité augmente de manière assez régulière avec l’âge, et que cette croissance semble exponentielle à partir de 80 ans. Cette observation constitue la base du modèle analytique de mortalité le plus célèbre et le plus utilisé, connu sous le nom de loi de Gompertz.
Il convient de noter que les taux de mortalité aux âges élevés, en particulier entre 106 et 110 ans, présentent une variabilité plus importante. Cela s’explique par le fait que le nombre de personnes encore vivantes à ces âges (l’exposition) est relativement faible, ce qui rend les estimations plus incertaines que pour les âges plus jeunes.
Loi de Gompertz
Cette sous-partie explique comment manipuler les \(\textbf{tables de vie}\), à partir desquelles les probabilités nécessaires aux calculs actuariels sont dérivées.
Les tables de vie sont une suite décroissante \(l_x\) pour \(x = 0,1,\ldots,\omega\), où \(l_x\) représente le nombre de survivants à l’âge \(x\), et \(\omega\) est l’âge terminal.
Étant donné que la table donne le nombre de survivants, on peut calculer les probabilités de survie à partir des \(l_x\). Si \(T_x\) désigne la durée de vie résiduelle (aléatoire) d’un individu âgé \(x\), alors la probabilité de survivre jusqu’à l’âge \(x + t\) est :
\[\begin{equation} {}_tp_x = \mathbb{P}(T_x > t) = \frac{l_{x+t}}{l_x} \tag{1.1} \end{equation}\]
et la probabilité de ne pas atteindre cet âge est :
\[ {}_tq_x = 1 - {}_tp_x = \mathbb{P}(T_x \leq t) = \frac{l_x - l_{x+t}}{l_x} \tag{1.2} \]
On peut importer directement une table de vie de travail provenant de la Society of Actuaries grâce au package lifecontingencies :
data("soa08Act")
# Nombre de survivants à l'âge de 65 ans
soa08Act@lx[soa08Act@x==65]
## [1] 75339.63
# Probabilité de mourir avant 85 ans si on a 65 ans
(soa08Act@lx[soa08Act@x==65]-soa08Act@lx[soa08Act@x==85])/
+ soa08Act@lx[soa08Act@x==65]
## [1] 0.6869847
Plus simplement :
qxt(soa08Act, 65,20)
## [1] 0.6869847
Pour avoir la probabilité de survie dans un intervalle fractionné, on peut faire une interpolation :
# Probabilité qu'un assuré de 80,25 ans meurt d'ici 6 mois, en utilisant une interpolation linéaire sur le taux de mortalité
pxt(object=soa08Act,x=80.25,t=0.5, fractional="linear")
## [1] 0.959027
Pour deux individus, on peut définire le temps de vie minimum comme \(T_{\overline{xy}} = \min(T_x, T_y)\) (premier décès) et le temps de vie maximum comme \(T_{xy} = \max(T_x, T_y)\) (dernier décès).
La probabilité de survie jointe sur un horizon \(t\) est :
\[\begin{equation} P(T_{xy} > t \text{ et } T_y > t) = P(T_{xy} > t), \quad \text{noté } p_{txy}. \tag{1.3} \end{equation}\]
Tandis que la probabilité de survie du dernier survivant sur un horizon \(t\) est :
\[\begin{equation} P(T_x > t \text{ ou } T_y > t) = P(T_{\overline{xy}} > t), \quad \text{noté } p_{t\overline{xy}}. \tag{1.4} \end{equation}\]
On peut tracer la courbe de survie jointe ou non d’un couple en utilisant notre table fictive :
# Tables de vie pour l'homme et la femme
maleTable <- soa08Act
femaleTable <- soa08Act
tables <- list(male = maleTable, female = femaleTable)
# Fonctions de survie
projoint <- function(t) pxyzt(tablesList = tables, x = c(65, 60), t = t, status = "joint")
problast <- function(t) pxyzt(tablesList = tables, x = c(65, 60), t = t, status = "last")
# Temps
time <- 0:45
# Créer le data frame pour ggplot
df_surv <- data.frame(
time = time,
joint = sapply(time, projoint),
last = sapply(time, problast)
)
library(tidyr)
df_long <- pivot_longer(df_surv, cols = c("joint", "last"), names_to = "type", values_to = "prob")
# Graphique ggplot
ggplot(df_long, aes(x = time, y = prob, color = type, linetype = type)) +
geom_line(size = 1.2) +
labs(
title = "Figure 1.7 : Probabilités de survie jointe",
x = "Temps (années)",
y = "Probabilité de survie",
color = "",
caption = "Source : Society of Actuaries, table illustrative",
linetype = ""
) +
scale_color_manual(values = c("joint" = "steelblue", "last" = "darkred"),
labels = c("Les deux vivants", "Au moins un vivant")) +
theme_minimal(base_size = 14) +
theme(
plot.title = element_text(face = "bold"),
legend.position = "top",
plot.subtitle = element_text(color = "gray30"),
plot.caption = element_text(color = "gray40")
)
Cette partie vise à montrer comment les calculs standards de mathématiques financières et actuarielles appliqués aux risques viagers peuvent être facilement réalisés à l’aide du package lifecontingencies, Spedicato (2013a).
Les mathématiques financières traitent de la valeur temporelle de l’argent. Une somme \(X\) investie aujourd’hui évoluera après \(t\) années selon la formule :
\[\begin{equation} A(t) = X \cdot (1 + i)^t \tag{2.1} \end{equation}\]
où \(i\) représente le taux d’intérêt effectif. Cela signifie que l’argent investi à un instant donné génère des intérêts, qui sont réinvestis pour produire des intérêts supplémentaires.
Les intérêts peuvent être capitalisés plus fréquemment qu’une fois par période, formant ainsi des périodes de conversion des taux. Souvent, le taux d’intérêt est exprimé en termes nominaux \(i^{(m)}\), soit le taux d’intérêt effectif divisé par \(m\), nombre de périodes de capitalisation :
\[\begin{equation} A(t) = (1 + i)^t = \left(1 + \frac{i^{(m)}}{m} \right)^t \tag{2.2} \end{equation}\]
Le package lifecontingencies propose les fonctions interest2Discount() et nominal2Real() pour obtenir le taux de discount (\(\frac{i}{i+1}\)) et le taux nominal simplement.
La \(\textbf{valeur actuelle nette}\) (Net Present Value - NPV) est un concept clé en mathématiques financières. Elle représente la valeur actuelle des flux de trésorerie futurs, permettant de comparer des investissements :
\[\begin{equation} VAN = \sum_{j=1}^{k} \frac{CF_j}{(1 + i_j)^{t_j}} \tag{2.3} \end{equation}\]
On peut par-exemple calculer la valeur actuelle nette d’un cashflow de \(1000\) payé dans \(6\) ans avec un taux d’intérêt de \(6 \%\) semi-annuel :
annualDiscount = nominal2Real(i=0.06, k=2, type="discount")
i = discount2Interest(annualDiscount)
presentValue(cashFlows=1000, timeIds=6, interestRates=i)
## [1] 693.8424
On calcule en faite \(1000 \times (1 - 0.06/2)^{12}\)
Le taux de rentabilité interne (TRI) est un taux d’actualisation qui annule la valeur actuelle nette d’une série de flux financier. C’est un outil de décision important. Il peut être estimé numériquement en minimisant la VAN.
Les rentes sont une série de paiements effectués à intervalles réguliers, certaines si les paiement sont garantis. Ces derniers peuvent être à la fin de chaque période ou au début (à terme échu).
On calcule une annuité à terme anticipé de \(n\) années avec la formule :
\[\begin{equation} a_{\overline{n}|} = \frac{1 - (1 + i)^{-n}}{i} \tag{2.4} \end{equation}\]
Et avec la fonction annuity() , par-exemple la VAN d’une annuité à terme anticipé de \(100\) payé sur \(5\) ans à \(9\%\) :
100*annuity(i = 0.09, n = 5, type = "immediate")
## [1] 388.9651
On a ensuite la valeur accumulée en capitalisant l’annuité, avec la fonction accumulatedValue() ou avec la formule :
\[\begin{equation} s_{\overline{n}|} = (1 + i)^n \cdot a_{\overline{n}|} = \frac{(1 + i)^n - 1}{i} \tag{2.5} \end{equation}\]
En particulier, une rente viagère (à termes anticipés) est une série annuelle de flux de 1 euro jusqu’au décès de l’individu à commencer d’aujourd’hui. Soit, avec \(v\) le coefficient d’actualisation :
\[ \begin{equation} \ddot{z}_x = \sum_{k=0}^{\infty} v^k 1_{T_x > k} = 1 + v + \cdots + v^n + \dots \tag{2.6} \end{equation} \]
# Points de temps : prime + versements
t_vals <- c(0, 1, 2, 3, 5, 6) # simplification de w - x - 1 = 5 et w - x = 6
labels <- c("t = 0", "t = 1", "t = 2", "t = 3", "t = w - x - 1", "t = w - x")
versements <- c("prime", rep("r si en vie", 5))
# Flèches (direction)
directions <- c("down", rep("up", 5))
# Données pour flèches
df <- data.frame(
t = t_vals,
label = labels,
versement = versements,
direction = directions,
y_start = ifelse(directions == "down", 1, 0),
y_end = ifelse(directions == "down", 0, 1)
)
# Graphique
ggplot(df) +
geom_segment(aes(x = t, xend = t, y = y_start, yend = y_end),
arrow = arrow(length = unit(0.15, "inches")), size = 0.7) +
geom_segment(aes(x = -0.5, xend = 6.5, y = 0, yend = 0), size = 0.5) +
geom_text(aes(x = t, y = 1.05,
label = versement), size = 4.5) +
geom_text(aes(x = t, y = -0.15, label = label), size = 4.5) +
annotate("text", x = 3, y = 1.5,
label = "Figure 2.1 : Rentes viagères à terme échu",
size = 5, fontface = "italic", hjust = 0.5) +
coord_cartesian(ylim = c(-0.3, 1.8)) +
theme_void()
## Warning in geom_segment(aes(x = -0.5, xend = 6.5, y = 0, yend = 0), size = 0.5): All aesthetics have length 1, but the data has 6 rows.
## ℹ Please consider using `annotate()` or provide this layer with data containing
## a single row.
Les contrats liés à l’assurance vie sont des contrats qui promettent un ou plusieurs paiements lors de la survenue d’un événement lié à la durée de vie. Par exemple :
Les contrats d’assurance décès prévoient le versement d’un capital en cas de décès de l’assuré pendant la période définie dans le contrat.
Les contrats de rente viagère versent une somme d’argent au début (ou à la fin) de chaque période, jusqu’à la fin du contrat ou jusqu’au décès de l’assuré, selon ce qui survient en premier.
Les contrats mixtes (endowment) versent un capital à l’échéance du contrat ou au décès de l’assuré, selon le premier événement.
La tarification de ces contrats suit plusieurs étapes :
Définir les hypothèses financières et démographiques : c’est-à-dire le taux d’intérêt utilisé pour actualiser les flux futurs, ainsi que la table de mortalité utilisée pour estimer les probabilités de survie.
Déterminer valeur actuelle actuarielle (VAA) des flux liés au risque de vie, c’est-à-dire le prix théorique des garanties contractuelles, en tenant compte des charges et marges.
Déterminer les primes, en tenant compte du mode de paiement (unique ou périodique).
L’assurance vie et les rentes viagères peuvent être vues comme l’espérance de la valeur actuelle des flux futurs, c’est-à-dire les valeurs actuelles probables (VAP) du contrat. En effet, la VAP représente l’espérance d’une variable aléatoire, qui dépend elle-même de la durée de vie future de l’assuré.
Plus précisément, on doit pondérer la valeur actuelle nette par des probabilités pour modéliser le caractère stochastique des risques liés à la vie. Pour une série de flux connus \(F_0, F_1, \ldots\), une série de conditions de paiements aléatoires \(C_0, C_1, \ldots\) et un facteur d’actualisation \(0 < v < 1\) (hypothèse de constance du taux d’intérêt), la valeur actuelle des flux est :
\[ \begin{equation} VA = \sum_{k=0}^{\infty} F_k v^k 1_{C_k} \tag{2.7} \end{equation} \]
La valeur actuelle probable est alors l’espérance conditionnelle de la valeur actuelle, sachant que l’individu est toujours vivant :
\[ \begin{equation} VAP = \mathbb{E}(VA \mid T_x > 0) = \sum_{k=0}^{\infty} F_k v^k \mathbb{P}(C_k) \tag{2.8} \end{equation} \]
On peut voir un exemple simple graphiquement, en prenant un taux d’intérêt constant de \(3\%\) sur \(20\) périodes, des flux constants de \(100€\)
# Paramètres
v <- 1 / (1 + 0.03) # facteur d’actualisation à 3%
k <- 0:20 # périodes 0 à 20
F_k <- rep(100, length(k)) # flux constants de 100 €
P_Ck <- dnorm(k, mean = 10, sd = 4) # probabilité conditionnelle gaussienne
# Calculs
actualised_flux <- F_k * v^k
expected_values <- actualised_flux * P_Ck
cumulative_VAP <- cumsum(expected_values)
# Tableau de données
df <- data.frame(
k = k,
FluxActualise = actualised_flux,
Proba = P_Ck,
Contribution = expected_values,
VAP_cumulee = cumulative_VAP
)
# Graphique
ggplot(df, aes(x = k)) +
geom_col(aes(y = Contribution), fill = "steelblue", alpha = 0.7) +
geom_line(aes(y = VAP_cumulee), color = "darkred", size = 1.2) +
labs(
title = "Figure 2.2 : Valeur actuelle probable (VAP)",
x = "Période",
y = "Valeur en euros",
caption = "Exemple illustratif",
color = "contribution"
) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold"),
plot.subtitle = element_text(color = "gray30"),
plot.caption = element_text(color = "gray40")
)
Dans cette section, nous utiliserons les notations suivantes :
| Notation | Description |
|---|---|
| \(x\) | Âge de l’assuré au début du contrat |
| \(n\) | Durée du contrat |
| \(m\) | Période de différé avant le début de la couverture |
| \(i\) | Taux d’intérêt utilisé pour actualiser les flux |
| \(k\) | Fréquence des paiements fractionnés |
Tous les exemples de cette section sont basés sur la table de mortalité illustrative de la Society of Actuaries, avec un taux d’intérêt de \(6\%\). De plus, on suppose que les prestations sont versées à la fin de chaque période.
Le contrat standard considéré est une police d’assurance temporaire de \(n\) années versant \(1\$\) au moment du décès de l’assuré \((x)\), si celui-ci survient avant l’échéance du contrat. La valeur actuelle probable du capital au décès de ce contrat est :
\[ \boxed{nA_x = \sum_{k=1}^n \frac{\mathbb{P}(T_x \in [k-1, k))}{(1 + i)^k} = \sum_{k=1}^n \frac{1}{(1 + i)^k} \cdot {}_{k-1}p_x \cdot {}_1q_{x+k-1}} \tag{2.9} \]
# Positions des événements
temps <- data.frame(
time = c(0, 4),
label = c("t = 0", "t = k")
)
# Flèches pour prime (à t=0) et capital en cas de vie (à t=k)
flux <- data.frame(
x = c(0, 4),
xend = c(0, 4),
y = c(1, 0),
yend = c(0, 1),
label = c("prime", "c si en vie")
)
# Graphique
ggplot() +
# Axe du temps
geom_segment(aes(x = -1, xend = 5, y = 0, yend = 0), size = 0.6) +
# Flèches
geom_segment(data = flux, aes(x = x, y = y, xend = xend, yend = yend),
arrow = arrow(length = unit(0.15, "inches")), size = 0.7) +
# Textes des flèches
geom_text(data = flux, aes(x = x, y = 1.15, label = label), size = 5) +
# Marqueurs de temps
geom_text(data = temps, aes(x = time, y = -0.1, label = label), size = 5) +
# Titre du graphique
annotate("text", x = 2, y = 1.5,
label = "Figure 2.3 : Capital décès",
size = 5, fontface = "italic", hjust = 0.5) +
coord_cartesian(ylim = c(-0.2, 1.8))+
theme_void()
Avant l’ère informatique, les assurances vie étaient évaluées à
l’aide de fonctions liées à l’âge des assurés, compilées dans des
tableaux appelés tables actuarielles : les
fonctions de commutation.
Le package lifecontingencies propose des fonctions pour générer automatiquement ces tables de commutation dans R.
Une table actuarielle est similaire à une table de vie, mais elle contient également un taux d’intérêt et des données permettants de calculer des valeurs actuelles :
# Création d'un objet Table actuarielle
data("soaLt") #Table de vie illustrative
soaAct <- new("actuarialtable", x = soaLt$x,
lx = soaLt$Ix, interest = 0.06)
soaActDf <- as(soaAct, "data.frame")
#Affichage
kable(head(soaActDf, 15), format = "html", align = "r", caption="Table 2.1 : Table actuarielle illustrative, SoA")%>%
kable_styling(bootstrap_options = c("striped", "hover", "bordered", "condensed"), full_width = FALSE)
| x | lx | Dx | Nx | Cx | Mx | Rx |
|---|---|---|---|---|---|---|
| 0 | 10000000 | 10000000 | 168358017 | 47263.585 | 470300.9 | 12487975 |
| 1 | 9949901 | 9386699 | 158358017 | 44588.288 | 423037.4 | 12017674 |
| 2 | 9899801 | 8810788 | 148971318 | 42064.422 | 378449.1 | 11594637 |
| 3 | 9849702 | 8270000 | 140160530 | 39683.417 | 336384.6 | 11216188 |
| 4 | 9799602 | 7762203 | 131890531 | 37437.186 | 296701.2 | 10879803 |
| 5 | 9749503 | 7285396 | 124128328 | 6191.668 | 259264.0 | 10583102 |
| 6 | 9740720 | 6866823 | 116842932 | 5841.197 | 253072.4 | 10323838 |
| 7 | 9731937 | 6472294 | 109976109 | 5510.563 | 247231.2 | 10070766 |
| 8 | 9723154 | 6100427 | 103503815 | 5198.644 | 241720.6 | 9823534 |
| 9 | 9714371 | 5749921 | 97403388 | 4904.381 | 236522.0 | 9581814 |
| 10 | 9705588 | 5419550 | 91653466 | 4409.949 | 231617.6 | 9345292 |
| 11 | 9697217 | 5108373 | 86233917 | 4160.329 | 227207.6 | 9113674 |
| 12 | 9688845 | 4815059 | 81125544 | 3924.839 | 223047.3 | 8886467 |
| 13 | 9680474 | 4538584 | 76310485 | 3702.678 | 219122.5 | 8663419 |
| 14 | 9672102 | 4277980 | 71771901 | 3493.093 | 215419.8 | 8444297 |
Avec la signification des colonnes :
| Colonne | Formule | Signification |
|---|---|---|
| \(D_x\) | \(D_x = v^x \cdot l_x\) | Actualisation des survivants |
| \(N_x\) | \(N_x = \sum_{k=x}^{\omega} D_k\) | Valeur actuelle des rentes viagères |
| \(C_x\) | \(C_x = v^{x+1} \cdot d_x\) | Actualisation des décès |
| \(M_x\) | \(M_x = \sum_{k=x}^{\omega} C_k\) | Valeur actuelle des assurances décès |
| \(R_x\) | \(R_x = \frac{M_x}{l_x}\) | Assurance vie entière moyenne |
On a alors toutes les informations nécessaires pour calculer les VAP avec la fonction Axn() :
Soit par-exemple une assurance temporaire de durée \(n = 3\) , assurant un capital de \(100 000\$\) si décès avant \(x + 3\) avec \(x = 36\). En utilisant les formules de commutation, on a la VAP :
\[ \begin{equation} A_{36:\overline{3}|}^{1} = \frac{M_{36} - M_{36+3}}{D_{36}} \tag{2.10} \end{equation} \]
Ce qui se calcule simplement sur R avec :
Axn(actuarialtable=soaAct, x = 36, n = 3) * 100000
## [1] 607.5519
Autrement dit, pour un capital décès de \(100 000\$\) si décès avant \(40\), la compagnie d’assurance devrait constituer une provision actuelle de seulement \(600\$\) . Cela est dû à la très faible probabilité de mourir dans les \(3\) prochaines années pour un assuré de \(36\) ans.
On peut observer graphiquement l’évolution de la VAP du capital décès :
#Table
data(soa08Act)
# Paramètres
ages <- 0:100
n_vals <- c(Inf, 30, 20, 10)
colors <- c("blue", "forestgreen", "orange", "red")
line_types <- c(1, 2, 3, 4)
# Calcul des valeurs actualisées des assurances décès
capital_deces <- sapply(n_vals, function(n) {
sapply(ages, function(x) {
if (is.infinite(n)) {
Axn(soa08Act, x) # Assurance vie entière
} else {
Axn(soa08Act, x, n = n) # Assurance temporaire
}
})
})
# Tracer
matplot(ages, capital_deces, type = "l", lty = line_types, col = colors,
xlab = "Âge", ylab = "capital décès", main = "Figure 2.4 : VAP Capital décès", lwd = 2)
legend("topleft",
legend = c("n = ∞", "n = 30", "n = 20", "n = 10"),
col = colors, lty = line_types, lwd = 2, bty = "n")
On peut également calculer simplement une rente viagère avec les fonctions de commutation : La valeur actuelle probable d’une rente viagère (à termes anticipés) pour un assuré d’âge \(x\) est donnée par :
\[ \begin{equation} \ddot{a}_x = \sum_{k=0}^{\infty} \frac{\mathbb{P}(T_x > k)}{(1 + i)^k} = \sum_{k=0}^{\infty} \frac{1}{(1 + i)^k} \cdot {}_k p_x \tag{2.11} \end{equation} \]
Elle se calcule avec les fonctions de commutation :
\[ \begin{equation} \ddot{a}_x = \frac{N_x}{D_x} \tag{2.12} \end{equation} \]
Pour un assuré de \(65\) ans recevant \(100\$\) en début de chaque période jusqu’à son décès, la VAP se calcule avec la fonction axn() :
axn(actuarialtable = soaAct, x = 65)
## [1] 9.896928
Les VAP des rentes viagères tendent effectivement à être faibles après \(60\) ans, comme on le voit graphiquement :
# Table
data(soa08Act)
# Paramètres
ages <- 0:100
n_vals <- c(Inf, 30, 20, 10)
couleurs <- c("blue", "forestgreen", "orange", "red")
styles <- c(1, 2, 3, 4) # Types de lignes (solide, pointillé, etc.)
# Calcul des rentes
rentes <- sapply(n_vals, function(n) {
sapply(ages, function(x) {
if (is.infinite(n)) {
axn(soa08Act, x)
} else {
axn(soa08Act, x, n = n)
}
})
})
# Tracer le graphique
matplot(ages, rentes, type = "l", lty = styles, col = couleurs,
xlab = "Âge ", ylab = "Rente viagère", main = "Figure 2.5 : VAP des rentes viagères", lwd = 2)
# Ajouter la légende
legend("topright",
legend = c("n = ∞", "n = 30", "n = 20", "n = 10"),
lty = styles, col = couleurs, lwd = 2, bty = "n")
La réserve mathématique d’un contrat d’assurance correspond au montant que la compagnie d’assurance doit avoir mis de côté afin de pouvoir faire face aux prestations futures prévues par le contrat (cf Finan, n.d.).
La réserve mathématique au temps \(t\) est estimée selon deux méthodes, toutes deux supposant que l’assuré est encore en vie à l’instant \(t\) :
Selon la méthode prospective, la réserve est calculée comme la différence entre la VAP des prestations futures du contrat et la VAP des primes futures que versera l’assuré.
Selon la méthode rétrospective, la réserve mathématique est calculée comme la différence entre la valeur accumulée des prestations déjà versées et la valeur accumulée des primes déjà encaissées.
On va se concentrer seulement sur la méthode prospective. La réserve mathématique au temps \(t\), notée \(V_t\) se calcule avec la formule :
\[ \begin{equation} V_t = \text{VAP}_t(\text{Prestations futures}) - \text{VAP}_t(\text{Primes futures}) \tag{2.13} \end{equation} \]
Supposant que l’assuré est vivant, la réserve à l’instant \(t\) pour une assurance vie entière est donnée par :
\[ {}_{t}V_x = A_{x+t} - P \cdot \ddot{a}_{x+t} \tag{2.14} \]
où \(P = \frac{A_x}{\ddot{a}_x}\) est la prime annuelle constante fixée au temps initial.
On peut calculer cette réserve facilement avec les fonctions précédentes : Supposons un assuré âgé de \(60\) ans ayant souscrit une assurance vie entière, les primes sont versées annuellement, on calcule la réserve à l’année \(10\) :
P <- Axn(soa08Act, 60) / axn(soa08Act, 60)
V <- Axn(soa08Act, 60 + 10) - P * axn(soa08Act, 60 + 10)
V
## [1] 0.2311368
La formule de la réserve pour une assurance temporaire \(n\) années est :
\[ {}_{t}V_x = {}_{n-t}A_{x+t} - P \cdot {}_{n-t}\ddot{a}_{x+t} \tag{2.15} \]
où \(P= \frac{{}_{n}A_x}{{}_{n}\ddot{a}_x}\) .
Par-exemple, supposons maintenant un assuré de \(60\) ans ayant souscrit une assurance
temporaire de \(30\) ans.
On souhaite connaître la réserve à l’année \(10\) :
P <- Axn(soa08Act, 60, 30) / axn(soa08Act, 60, 30)
V <- Axn(soa08Act, 60 + 10, 30 - 10) - P * axn(soa08Act, 60 + 10, 30 - 10)
V
## [1] 0.209061
On peut visualiser l’évolution de la réserve mathématique d’année en année :
# Table
data(soa08Act)
# Paramètres
age <- 60
n <- 30 # Durée du contrat temporaire
t_vals <- 0:n # années écoulées
# Prime annuelle constante
P <- Axn(soa08Act, age, n) / axn(soa08Act, age, n)
# Fonction réserve mathématique à l'année t
reserve <- function(t) {
Axn(soa08Act, age + t, n - t) - P * axn(soa08Act, age + t, n - t)
}
# Calcul de la réserve à chaque année
reserve_vals <- sapply(t_vals, reserve)
# Graphe
df <- data.frame(Annee = t_vals, Reserve = reserve_vals)
ggplot(df, aes(x = Annee, y = Reserve)) +
geom_line(color = "darkblue", size = 1.3) +
geom_area(fill = "lightblue", alpha = 0.5) +
labs(
title = "Figure 2.6 : Evolution de la réserve",
x = "Années depuis souscription",
y = "Réserve"
) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold"),
plot.subtitle = element_text(color = "gray30"),
plot.caption = element_text(color = "gray40")
)
L’idée derrière la méthode itérative est de calculer :
\[ \begin{equation} V_t = V_{t+1} - \text{VAP}_t(\text{Primes futures entre } t \text{ et } t+1) + \text{VAP}_t(\text{Prestations futures entre } t \text{ et } t+1) \tag{2.16} \end{equation} \]
Il est donc possible d’utiliser une approche récursive pour calculer la réserve \(V_t\), puisque à \(t = 0\), il n’y a pas encore de réserve.
On peut implémenter dans R la solution de cette équation récursive :
recurrent <- function(a, b, ufinal){
s <- rev(cumprod(c(1, b)))
return((rev(cumsum(s[-1] * rev(a))) + s[1] * ufinal) / rev(s[-1]))
}
On utilise cette fonction avec
$ a_t = A_{x+t} - P, b_t = $
Et on peut obtenir le graphe d’évolution de la réserve avec la méthode itérative :
# Table
data(soa08Act)
# Paramètres
x <- 60
n <- 30
i <- 0.06
v <- 1 / (1 + i)
# Prime annuelle constante
P <- Axn(soa08Act, x, n) / axn(soa08Act, x, n)
# a_t = A_{x+t} - P
Vecta <- Vectorize(function(t) Axn(soa08Act, t, 1))(x + 0:(n - 1)) - P
# b_t = p_{x+t} / (1 + i)
Vectb <- Vectorize(function(t) pxt(soa08Act, t, 1))(x + 0:(n - 1)) / (1 + i)
# Fonction de calcul itératif
recurrent <- function(a, b, ufinal) {
s <- rev(cumprod(c(1, b)))
(rev(cumsum(s[-1] * rev(a))) + s[1] * ufinal) / rev(s[-1])
}
# Calcul de la réserve à chaque année t
Vectv <- c(recurrent(a = Vecta, b = Vectb, ufinal = 0), 0)
df <- data.frame(Annee = 0:n, Reserve = Vectv)
# Tracer avec ggplot
ggplot(df, aes(x = Annee, y = Reserve)) +
geom_line(color = "steelblue", size = 1.3) +
geom_point(color = "darkblue", size = 2) +
geom_area(fill = "lightblue", alpha = 0.3) +
labs(
title = "Figure 2.7 : Evolution de la réserve (méthode itérative)",
x = "Années depuis souscription",
y = "Réserve"
) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold"),
plot.subtitle = element_text(color = "gray30"),
plot.caption = element_text(color = "gray40")
)
Les deux graphes sont similaires.
Dans cette section, nous allons:
Déterminer la distribution de la valeur actuelle d’un contrat d’assurance à l’aide de R
Résumer les moments (espérance, variance, etc.) d’un portefeuille de contrats.
Déterminer la distribution d’un portefeuille de contrats, à la fois par simulation et par approximation normale.
Considérons maintenant un ensemble, ou portefeuille, de plusieurs contrats. Par souci de simplicité, on suppose que tous les contrats sont de type assurance temporaire, tel qu’introduit dans la section 3.2.2. Cependant, on autorise chaque souscripteur à avoir un âge, un sexe, une durée de contrat et un capital assuré différents.
Pour la notation, on utilise l’indice inférieur jjj pour distinguer les contrats individuels, et on note donc les caractéristiques individuelles comme xjx_jxj, où j=1,2,…,Jj = 1, 2, , Jj=1,2,…,J, avec JJJ le nombre total de contrats.
Nous avons construit un portefeuille qui imite ceux que nous avons observés dans la pratique. Nous supposons que les assurés de la dernière année disponible dans les données de la compagnie (c’est-à-dire le mois 780) souscrivent une assurance temporaire, ce qui nous donne J=190J = 190J=190 contrats. À des fins illustratives, nous supposons que la mortalité suit celle décrite dans l’exemple 3.2. Pour cet ensemble de données, on trouve qu’il y a 136 femmes et 54 hommes dans le portefeuille. La Figure 3.14 résume les distributions des âges initiaux, des durées de contrat, et des sommes assurées.
base de données, simulation monte carlo
Plus assurable lorsque la proba de décès dépasse 2 %, calcul de taux de mortalité
Gestion d’un portefeuille avec 500 000 polices ou 1 million, comment optimiser., utilisation des commutations, temps de calcul pas important ( moins de 5 mins)
ajout des dépenses dans le calcule de la prime ? simulations stochastiques d’assurances avec monté carlo