Computes the actuarial present value of a discrete annuity contingent on two independent lives, using compact actuarial notation.
Arguments
- lt
A life table, a list of two life tables
list(lt_x, lt_y), or atidyact_life_contractobject created bylife_contract. Each life table must contain columnsxandlx.- x
Integer actuarial age for the first life.
- y
Integer actuarial age for the second life.
- i
Numeric scalar. Annual interest-rate input.
- i_type
Character string indicating the interest-rate type. Allowed values are
"effective","nominal_interest","nominal_discount", and"force".- m
Positive integer. Conversion frequency for nominal rates. Ignored for
i_type = "effective"andi_type = "force".- status
Character string. Use
"joint"for joint-life payments while both lives are alive, or"last"for last-survivor payments while at least one life is alive. Ignored whenbenefitis supplied.- benefit
Optional list with numeric scalar weights
both,x_only, andy_only. These weights define the payment rate according to the survival state of the two lives. Weights may be signed; an expected payment is then a benefit weight, not necessarily a probability.- n
Term in years. Use
Inffor the maximum horizon allowed by the life tables. For exact k-thly valuation (woolhouse = "none"), fractional terms are allowed whenn * kis an integer. Woolhouse approximations require an integer number of years.- h
Nonnegative integer deferment period in years.
- k
Positive integer. Number of payments per year. The annuity is normalized to an annual payment rate of 1, so each individual payment has amount
1 / k.- timing
Payment timing. Use
"immediate"or"due".- woolhouse
Woolhouse approximation for
k > 1:"none","first", or"second".- frac
Fractional-age assumption for exact k-thly computation:
"UDD","CF","CML", or"Balducci".- tidy
Logical scalar. If
FALSE, returns a numeric APV. IfTRUE, returns a one-row tibble.- ...
Transitional compatibility for older calls using
mortality_table,age_x,age_y,rate,rate_type,cohort,term_years,deferment_years,payments_per_year, andoutput.
Value
If tidy = FALSE, a numeric scalar.
If tidy = TRUE, a one-row tibble with input values, standardized
interest rate, term used, and APV.
Details
The function supports joint-life, last-survivor, and state-based reversionary-style payments. The life table input may be either one common table for both lives or a list of two life tables, one for each life.
This function follows the compact actuarial notation used throughout
tidyactuarial: lt is the life table input, x and
y are the two actuarial ages, i is the interest-rate input,
i_type is the interest-rate type, m is the conversion
frequency for nominal rates, n is the term, h is the
deferment period, and k is the payment frequency.
The function assumes independent future lifetimes. For state-based benefits, the expected payment at time \(t\) is $$ b_{\text{both}}\,{}_tp_x{}_tp_y + b_{x\text{ only}}\,{}_tp_x(1-{}_tp_y) + b_{y\text{ only}}\,{}_tp_y(1-{}_tp_x). $$
When benefit = NULL, status = "joint" uses
benefit = list(both = 1, x_only = 0, y_only = 0), while
status = "last" uses
benefit = list(both = 1, x_only = 1, y_only = 1).
For k-thly payments, the function values a payment rate of 1 per year,
so each payment has size \(1/k\). For exact valuation, a fractional term
is admissible whenever it contains a whole number of payments:
$$nk \in \mathbb{N}.$$
Both lives are alive at issue; both, x_only and y_only refer to occupation at each payment date, without restarting both lives after a death. A designated reversion to y uses both=0, x_only=0, y_only=1; this differs from payments to either sole survivor and from a joint-and-survivor annuity paying while both are alive as well.
Exact valuation sums signed state payments on dates h+j/k, with each payment equal to its state rate divided by k. Cumulative death probabilities use direct survivor-count decrements and fractional interval masses, avoiding cancellation in 1-S. Original log interest, probabilities and monetary weights are combined before exponentiating when necessary.
Woolhouse approximations apply only to standard joint-life/last-survivor statuses. Put F(t)=exp(-g*t)w(t), where w is the status survival from issue and g is the input rate's annual log accumulation. First order subtracts (1-1/k)(F(h)-F(h+n))/2 from the annual due annuity. Second order also subtracts (1-1/k^2)((g+eta(h))F(h)-(g+eta(h+n))F(h+n))/12, with eta(t)=-log(w(t+1)/w(t)), a forward annual estimate, not an exact instantaneous force. Second order requires positive supported weights and the following year at both borders; otherwise use none or first. Immediate subtracts (F(h)-F(h+n))/k from the due approximation. A negative approximation is reported with a warning, without clipping.
Tables must satisfy the annual consistency requirements of t_pxy;
issue ages must have positive lx for nonempty valuations. Payment grids
must be finite, representable and no larger than R's integer range.
One call values one contract; benefit vectors describe states, not scenarios.
The existing table-horizon convention is retained: each marginal survival
becomes zero beyond its last recorded age. On open tables this is truncation,
not evidence of death, and may affect last-survivor or reversionary weights
after the shorter horizon. Extend the tables for those interpretations.
Infinite n means available horizon, not extrapolated lifetime coverage.
See also
annuity_x, insurance_xy,
premium_xy, t_pxy, t_px
Other life-contingencies:
add_insurance(),
add_premium_schedule(),
annuity_multi(),
annuity_x(),
insurance_variable_k(),
insurance_x(),
insurance_xy(),
life_contract(),
premium_gross(),
premium_x(),
premium_xy(),
reserve_x(),
reserve_xy(),
simulate_annuity_x(),
simulate_insurance_x()
Examples
lt <- data.frame(
x = 60:66,
lx = c(100000, 99000, 97500, 95500, 93000, 90000, 86000)
)
# Joint-life annuity-due
annuity_xy(
lt = lt,
x = 60,
y = 62,
i = 0.05,
status = "joint",
timing = "due"
)
#> [1] 3.52856
# Last-survivor annuity-due
annuity_xy(
lt = lt,
x = 60,
y = 62,
i = 0.05,
status = "last",
timing = "due"
)
#> [1] 5.240099
# Different life tables for the two lives
lt_m <- lt
lt_f <- data.frame(
x = 60:66,
lx = c(100000, 99200, 98100, 96500, 94500, 92000, 89000)
)
annuity_xy(
lt = list(lt_m, lt_f),
x = 60,
y = 62,
i = 0.05,
status = "joint",
timing = "due"
)
#> [1] 3.553047
# State-based reversionary-style payments
annuity_xy(
lt = list(lt_m, lt_f),
x = 60,
y = 62,
i = 0.05,
benefit = list(both = 0, x_only = 1, y_only = 0),
timing = "due"
)
#> [1] 0.8752761