spedygiorgio / lifecontingencies Goto Github PK
View Code? Open in Web Editor NEWFinancial and Actuarial Mathematics for Life Contingencies
License: Other
Financial and Actuarial Mathematics for Life Contingencies
License: Other
require(lifecontingencies)
data("demoGermany")
lifetableMale = probs2lifetable(probs= demoGermany$qxMale, radix = 10000, type = "qx", name= "DE 1994 Male")
actuarialTable = new("actuarialtable",x=lifetableMale@x, lx=lifetableMale@lx, interest=0.02, name="German Male '94 actuarialtable")
age = 109
limit = 111
payout = 2000
payout * axn(actuarialtable = actuarialTable,
x = age,
n = limit,
i = actuarialTable@interest,
k = 1)
results in: 4762.061
As does
payout * axn(actuarialtable = actuarialTable,
x = age,
n = limit,
i = actuarialTable@interest,
m = 0,
k = 1)
Annuity immediate / due should be fixed in temrinology and possibly in parameters definitions / calculations
It appears that R requires "native routine" to be defined. See this GitHub page for more details GitHub
Since we only support R 4.1, 4.2 on Conda Forge right now, I patched the latest release to R >= 4.1
and everything appears to build without issue and all the tests pass on all platforms. Is there something problematic I should be looking for? What was the motivation for declaring this package incompatible with earlier R versions?
I’m trying to reproduce the example given under the heading
Insurance and annuities on two heads in your Introduction to lifecontingencies Package, page 22, with my own data.
However, I get 2 different values:
axn(ActMannTables[[1]], x=100) + axn(ActFrauTables[[1]], x=102) - axyn(ActMannTables[[1]], ActFrauTables[[1]], x=100, y=102, status="joint", m=0)
#5.928079849
axyzn(list(ActMannTables[[1]], ActFrauTables[[1]]), x=c(100, 102), status="last", m=0)
#5.860986613
Shouldn’t they be the same?
Attached is the script. (10 different actuarial tables are created, but you can ignore that. Only the 2 actuarial tables for male and female with i=0.04 are used.)
The difference gets smaller if I reduce the age of x and y.
Kind regards from Hannover, Germany
Wolfgang Abele
options(digits=10)
library(lifecontingencies)
male <- read.table(textConnection("Männer qx
0 0.000113
1 0.000113
2 0.000113
3 0.000113
4 0.000113
5 0.000113
6 0.000113
7 0.000113
8 0.000113
9 0.000113
10 0.000113
11 0.000113
12 0.000113
13 0.000114
14 0.000133
15 0.000175
16 0.000235
17 0.000309
18 0.000385
19 0.000447
20 0.000511
21 0.000617
22 0.000777
23 0.000786
24 0.000795
25 0.000804
26 0.000813
27 0.000814
28 0.000832
29 0.000863
30 0.000894
31 0.000934
32 0.000994
33 0.001063
34 0.001109
35 0.001112
36 0.001115
37 0.001118
38 0.001121
39 0.001145
40 0.001198
41 0.00128
42 0.001394
43 0.001521
44 0.001676
45 0.001864
46 0.002039
47 0.002201
48 0.002356
49 0.002516
50 0.002677
51 0.002831
52 0.003016
53 0.003258
54 0.003555
55 0.0039
56 0.004274
57 0.004676
58 0.005065
59 0.005422
60 0.005755
61 0.006102
62 0.006496
63 0.006971
64 0.007557
65 0.008293
66 0.009178
67 0.010137
68 0.011123
69 0.012169
70 0.013316
71 0.014649
72 0.016198
73 0.018056
74 0.020216
75 0.022646
76 0.025415
77 0.028511
78 0.031762
79 0.03547
80 0.03977
81 0.044321
82 0.04923
83 0.05454
84 0.060227
85 0.066281
86 0.072418
87 0.078658
88 0.085141
89 0.091502
90 0.098056
91 0.104216
92 0.11001
93 0.115695
94 0.121466
95 0.127386
96 0.133438
97 0.13958
98 0.145758
99 0.151914
100 0.158012
101 0.164479
102 0.170732
103 0.17674
104 0.182474
105 0.187907
106 0.193017
107 0.197785
108 0.202193
109 0.206228
110 0.209878
111 1"), as.is=TRUE, header=TRUE)
female <- read.table(textConnection("Frauen qy
0 0.000059
1 0.000059
2 0.000059
3 0.000059
4 0.000059
5 0.000059
6 0.000059
7 0.000059
8 0.000059
9 0.000059
10 0.000059
11 0.000059
12 0.000059
13 0.000059
14 0.000059
15 0.000068
16 0.000085
17 0.00011
18 0.00011
19 0.00011
20 0.000111
21 0.000111
22 0.000111
23 0.000112
24 0.000112
25 0.000112
26 0.000112
27 0.000113
28 0.000118
29 0.000143
30 0.000202
31 0.000297
32 0.000357
33 0.000386
34 0.000404
35 0.000425
36 0.000449
37 0.000475
38 0.000507
39 0.000553
40 0.000622
41 0.000713
42 0.00079
43 0.000857
44 0.000929
45 0.001018
46 0.001117
47 0.001177
48 0.001202
49 0.001212
50 0.001231
51 0.001266
52 0.001324
53 0.001403
54 0.001491
55 0.001581
56 0.00167
57 0.001766
58 0.001866
59 0.001958
60 0.00206
61 0.002199
62 0.002383
63 0.002605
64 0.002885
65 0.003237
66 0.003661
67 0.004141
68 0.004637
69 0.005146
70 0.005698
71 0.006302
72 0.006994
73 0.007848
74 0.00889
75 0.010096
76 0.011504
77 0.0132
78 0.015135
79 0.017388
80 0.020117
81 0.023237
82 0.02674
83 0.030737
84 0.035271
85 0.040263
86 0.045997
87 0.052428
88 0.059507
89 0.067171
90 0.075313
91 0.083869
92 0.092315
93 0.100693
94 0.1089
95 0.116909
96 0.124725
97 0.132466
98 0.140118
99 0.147629
100 0.154934
101 0.163311
102 0.171514
103 0.179486
104 0.187179
105 0.194544
106 0.20154
107 0.208129
108 0.214281
109 0.219967
110 0.225167
111 1"), as.is=TRUE, header=TRUE)
Mann <- probs2lifetable(probs=male$qx, radix=100000, type="qx", name="Sterbetafel DAV 1994 R Männer")
Frau <- probs2lifetable(probs=female$qy, radix=100000, type="qx", name="Sterbetafel DAV 1994 R Männer")
i.rates <- c(0.04, 0.0325, 0.0275, 0.0225, 0.0175)
ActMannTables <- vector("list", 5)
ActFrauTables <- vector("list", 5)
for(i in seq_along(i.rates)) {
ActMannTables[i] <- new("actuarialtable", x=Mann@x, lx=Mann@lx, interest=i.rates[i], name=paste0("Mann ", i-1))
ActFrauTables[i] <- new("actuarialtable", x=Frau@x, lx=Frau@lx, interest=i.rates[i], name=paste0("Frau ", i-1))
}
axn(ActMannTables[[1]], x=100) + axn(ActFrauTables[[1]], x=102) - axyn(ActMannTables[[1]], ActFrauTables[[1]], x=100, y=102, status="joint", m=0)
#5.928079849
axyzn(list(ActMannTables[[1]], ActFrauTables[[1]]), x=c(100, 102), status="last", m=0)
#5.860986613
Annuities in Rcpp should be implemented
With reference to this source : https://www.investopedia.com/exam-guide/cfa-level-1/fixed-income-investments/effective-modified-macaulay-duration.asp
Current duratiion function in v1.3.2
function (cashFlows, timeIds, i, k = 1, macaulay = TRUE)
{
out = 0
if (missing(timeIds)) {
warning("Warning: missing time vector")
timeIds = 1
}
if (!(length(cashFlows) == length(timeIds)))
stop("Error! check dimensionality of cash flow and time ids vectors")
interestRates = rep(i/k, length.out = length(timeIds))
ts = timeIds * k
v = (1 + interestRates)^-(ts)
pv = sum((cashFlows * v))
weightedTime = sum((cashFlows * v * ts))
out = weightedTime/pv
if (macaulay == FALSE)
out = out
else out = out/(1 + i/k)
return(out)
}
Instead it should be
if (macaulay == TRUE)
out = out
else out = out/(1 + i/k)
return(out)
"Else" part in fact refers to Modified Duration, Not Effective Duration like documentation states (Although in some cases, Modified and Effective duration are the same)
#SUGGESTION:
1/Fixed the modified and effective duration in function and their documentation accordingly
2/Add another option of effective duration calculation.
I have been working with your package. I had a issue, and it is depending of the multiple decrements table the probability of survival turns to be negative. I couldn't replicate this until now, but to take care of it.
Hello,
Is there any way to calculate axn and azyzn with geometrically increasing?
Thanks
The new vignette appears to generate an issue in the package compilation. It breaks package compilation
Errore: processing vignette 'mortality_projection.Rnw' failed with diagnostics:
chunk 2 (label = load)
Error in library(demography) : there is no package called 'demography'
Inoltre: Warning message:
In tools::buildVignettes(dir = ".", tangle = TRUE) :
Files named as vignettes but with no recognized vignette engine:
'vignettes/PensionPlanVal.Rmd'
(Is a VignetteBuilder field missing
```?)
Old R actuarial functions should be moved to backup file to ease maintenance.
Unuseful comments should be removed from R code and put in man files (by roxygen)
Actuarialtable and lifetable initialization procedures have many duplicated code... Optimization, should be performed having a look to s4 classes best practices (callNextMethods...)
In my attempt to regenerate AM92 table (with duration 0, 1, 2+/ultimate) , I reckon that current version will not provide a correct result. I manually crossed-check with IFoA 's Formulae and Tables for Examination.
The reason is obvious : after 2 years, the mortality will eventually becomes "ultimate".
Example :
tp[x] = l_([x]+t)/l_[x]
for t>=2, l_([x]+t) = l_(x+t)
N_[x] = summation(D_y) for y = [x] to infinity
= D_[x] + D_([x] + 1) + D_([x] + 2) + D_([x] + 3) + ...
= v^x*l_[x] + v^(x+1)*l_([x]+1) + v^(x+2)*l_([x]+2) + v^(x+3)l_([x]+3) + ...
= v^xl_[x] + v^(x+1)*l_([x]+1) + v^(x+2)*l_([x]+2) + v^(x+3)l_([x]+3) + ...
= v^xl_[x] + v^(x+1)*l_([x]+1) + N_(x+2)
Similarly for exn or any commutation formulas involving summation over an extending period of time. There will be a jump of reference between duration 0, duration 1 and duration2/ultimate.
Hence the current approach of lifetable and actuarialtable class with an input of a single series of lx will not solve the problem. (most of function pxt, qxt exn, axn or Axn now will no longer gives a correct result)
(1) I have an approach for a single specific case. Example : entry age 45 >>> create a unique vector {q_[45], q_([45]+1), q_47, q_48,.... } >>> create lifetable/acfuarialtable accordingly. However the table is only applicable for entry age 45. Assuming I am trying to valuate 1000 policies. To generate tables for every single entry age is not efficient in my limited opinion.
(2) I believe this enhancement suggestion is important because selected mortality is a part of actuarial student curriculum. To bring the package closer to students like myself, we need to make sure that students can easily apply them to solve their problems at school.
(3) In my own attempting to adjust the current codes, I changed an entire definition of those two classes but I am curently not aware of its overall impact to the packages ( as I am still in the learning process. )
Thank you and I find the package really fascinating.
The new markdown bibliography should be integrated by bibliography correctly set out using markdown. See the vignette as amended by me (I have added the first two entries, @IvanWilli should finish the remaining). This is related to #28
See Valdez code
Hello,
first at all, thank you for the package.
I am testing a whole life annuity in arrears with k = 12, x = 60 and i = 0.04. I am using my own table that I attach with the lx.
The result in R is as follows:
axn(table, x=60, i = 0.04, k=12, payment = "arrears")
[1] 10.82216
Using an Excel (attached) the result is:
10.8272718556912
I am triying to understand the difference after second decimal.
life.xlsx
Thanks a lot,
A recent release of roxygen2 makes latin1 encoding not working anymore (see from r-lib/roxygen2#787). Thus latin1 encoding should be removed
The compilation is currently not working due to issues on recreating NAMESPACE with roxygen2
Dear Giorgo,
With respect to the second bug, I suggest these changes in the code of the functions pxt and Axn.
The reason for the pxt function is that if I use it with a lifetable that has the last probability px greater than zero, the result is incorrect, but if I use a vector of qx's that has the last probability equal to one, and if I convert it to a lifetable with the probs2lifetable function, the result is correct.
Axn
function (actuarialtable, x, n, i = actuarialtable@interest, m, k = 1, type = "EV", power = 1)
{
[...]
if (missing(n))
n = getOmega(actuarialtable) - x - m + 1
[...]
}
pxt
function (object, x, t, fractional = "linear", decrement)
{
[...]
if((tabla@lx[omega]>0) && (x + t) == (omega+1) )
{out <- 1/object@lx[which(object@x == x)]}
else {
if ((x + t) > omega)
out <- 0
[...]
}
When compiling to resubmit the package on CRAN I found this Warning...
It seems the constructor to have been altered since last commit
Porting parallelized simulations into RcppParallel
package ‘lifecontingencies’ is not available (for R version 3.3.1)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.