Quickstart
using ActuaryUtilities
cfs = [5, 5, 105]
times = [1, 2, 3]
discount_rate = 0.03
present_value(discount_rate, cfs, times) # 105.66
duration(Macaulay(), discount_rate, cfs, times) # 2.86
duration(discount_rate, cfs, times) # 2.78
convexity(discount_rate, cfs, times) # 10.6310.625805482685935Features
A collection of common functions/manipulations used in Actuarial Calculations.
Financial Maths
duration:- Calculate the
Macaulay,Modified, or signedDV01durations for a set of cashflows - Calculate
IR01/CS01andEffective/Spreadrisk for curves, contracts, and portfolios - Decompose risk by tenor with
KeyRates(tenors)
- Calculate the
convexityfor price sensitivity- Flexible interest rate models via the
FinanceModels.jlpackage. internal_rate_of_returnorirrto calculate the IRR given cashflows (including at timepoints like Excel'sXIRR)breakevento calculate the breakeven time for a set of cashflowsaccum_offsetto calculate accumulations like survivorship from a mortality vectorspreadwill calculate the spread needed between two yield curves to equate a set of cashflows
Key-Rate Sensitivities
Compute key-rate durations, DV01s and convexities for any FinanceModels.jl yield model, without bump-and-reprice. Fixed cashflows use analytic derivatives; valuation callbacks use ForwardDiff.
using ActuaryUtilities, FinanceModels
rates = [0.03, 0.03, 0.03, 0.03, 0.03]
tenors = [1.0, 2.0, 3.0, 4.0, 5.0]
zrc = ZeroRateCurve(rates, tenors)
cfs = [5.0, 5.0, 5.0, 5.0, 105.0]
# Value, key-rate durations, DV01s and convexities in one call
result = sensitivities(SecondOrder(), KeyRates(tenors), zrc, cfs, tenors)
result.value # present value
result.duration # key-rate durations (vector)
result.dv01 # key-rate DV01s (vector)
result.convexity # key-rate convexity matrix
result.dollar_convexity # second derivatives without dividing by valuesensitivities: value, durations and DV01s in one call, and withSecondOrder()convexity and dollar convexity; parallel withoutKeyRates, per tenor with it- Dollar risk:
duration(DV01(), ...)andconvexity(DollarConvexity(), ...)are defined at zero value and add across positions - Two-curve decomposition: separate
IR01(risk-free) andCS01(credit spread) sensitivities - Contracts and portfolios:
duration(Effective(), curve, contract; index),Spread(), andsensitivities(curve, contract; index)with the discount and index exposures - Do-block syntax: custom valuation functions for rate-dependent instruments (callable bonds, floaters, caps/floors)
- Hull–White stochastic model: key-rate sensitivities of Monte Carlo expected values, differentiating through the full simulation pipeline
using FinanceModels: ShortRate
using Random: Xoshiro
hw = ShortRate.HullWhite(0.1, 0.01, zrc)
hw_result = sensitivities(KeyRates(tenors), Scenarios(hw; horizon=6.0, n_scenarios=1000, rng=Xoshiro(42)), cfs, tenors)
hw_result.duration # key-rate durations under stochastic dynamicsSee the Interest-Rate Sensitivities documentation for details.
Risk Measures
- Calculate risk measures for a given vector of risks:
CTEfor the Conditional Tail ExpectationVaRfor the percentile/Value at RiskWangTransformfor the Wang TransformationProportionalHazardfor proportional hazardsDualPowerfor dual power measure
Insurance mechanics
policy_duration: the policy duration given an issue date and a date
Typed Rates
- functions which return a rate/yield will return a
FinanceCore.Rateobject. E.g.irr(cashflows)will return aRate(0.05,Periodic(1))instead of just a0.05(float64) to convey the compounding frequency. These values are accepted by the supported valuation APIs across the JuliaActuary ecosystem. Userate(r)when an API needs the scalar value, and preserve the compounding convention separately.
A couple of other notes:
rate(...)will return the scalar rate value from aRatestruct:
julia> r = Rate(0.05,Periodic(1));
julia> rate(r) ≈ 0.05
true- You can still pass a simple floating point rate to various methods. E.g. these two are the same (the default compounding convention is periodic once per period):
discount(0.05, 3)
r = Rate(0.05,Periodic(1));
discount(r, 3)- convert between rates with:
r = Rate(0.05,Periodic(1));
convert(Periodic(2), r) # convert to compounded twice per timestep
convert(Continuous(), r) # convert to continuous compoundingFor more on Rates, see FinanceCore.jl. FinanceModels.jl also provides a rich and flexible set of yield models to use.
Documentation
Full documentation is available here.
Examples
Interactive, basic cashflow analysis
See JuliaActuary.org for instructions on running this example.
Useful tips
Arguments come in this order: a valuation callback (if any), an order marker for sensitivities (FirstOrder() or SecondOrder()), a measure marker such as DV01() or KeyRates(tenors), the rate or curve, then the cashflows and times or a contract. A contract's index curve is the keyword index, which defaults to the curve.
