Variable annuity: lifetime withdrawal guarantee
PricingLab by Raganel Consulting, powered by MatLogica AADC
What it values
A variable annuity is a savings policy invested in a stock fund, sold with a promise from the insurer: whatever the fund does, the policyholder can keep withdrawing a fixed amount every year for life (a guaranteed minimum withdrawal benefit, GMWB). If the fund runs dry, the insurer pays those withdrawals from its own money. This model puts a price on that promise for one policy. It returns the present value, at issue, of everything the insurer expects to pay out of its own pocket under the guarantee. It also returns how that value moves with the fund value (delta), with market volatility (vega) and with interest rates (rho).
Who uses this kind of number
Life insurers that write or hold these guarantees, and the people around them: hedging desks, which buy and sell market instruments to offset the guarantee’s market risk and need delta, vega and rho to do it; actuaries who set reserves and price new business; and reinsurers and buyers pricing a block of guarantees in a transfer deal.
Inputs
| Name | Unit | Default | Meaning |
|---|---|---|---|
initial_premium | USD | 100,000 | Single premium paid in; also the starting account value |
rider_charge_rate | fraction/yr | 0.012 | Annual guarantee fee on the account value |
management_fee_rate | fraction/yr | 0.013 | Annual fund management fee on the account value |
withdrawal_rate | fraction/yr | 0.05 | Guaranteed annual withdrawal as a fraction of the benefit base |
utilization_rate | fraction | 0.85 | Share of the guaranteed withdrawal policyholders actually take |
rollup_rate | fraction/yr | 0.05 | Annual roll-up of the benefit base for up to 10 years before withdrawals |
initial_age | years | 55 | Policyholder age at issue |
withdrawal_start_age | years | 65 | Age at which withdrawals start |
base_lapse_rate | fraction/yr | 0.05 | Base annual lapse rate before the in-the-money adjustment |
vol | fraction/yr | 0.20 | Equity volatility (risk-neutral) |
rate | fraction/yr | 0.04 | Risk-free rate, continuously compounded |
div | fraction/yr | 0.0 | Dividend yield |
n_paths | count | 4,096 | Monte Carlo paths (4,096 at most on the free hosted service) |
Every input has a supported range; describe_model lists it. Any input you leave out takes its default.
Outputs
- Value: the guarantee liability in USD, present value at issue.
- delta: change in the liability per 1 USD change in the account value.
- vega: change in the liability per 1.00 change in volatility (so per 0.01, divide by 100).
- rho: change in the liability per 1.00 change in the interest rate (per 0.01, divide by 100).
- Timing of the calculation in milliseconds.
The model also offers one extra calculation, nested, described below.
How the sensitivities are computed
The model simulates thousands of possible paths for the fund. On each path it steps through the contract month by month: fees, roll-ups, ratchets, withdrawals, deaths and lapses. Delta, vega and rho all come out of that same run, in one forward pass and one backward pass over the calculation (adjoint algorithmic differentiation). The usual alternative is to re-run the whole model with each input nudged up and down, once per sensitivity.
How they are checked
Every sensitivity can be recomputed the slow way (bump-and-revalue): nudge the input up and down, re-run the model on exactly the same random paths, and take the difference. The check_against_bumping tool does this on demand and reports each gap and both timings.
Measured on 5 November 2026 at the default inputs, 4,096 paths, on two cores of an Intel Xeon 8280L:
| Sensitivity | One pass | Bump-and-revalue | Gap (relative to the bumped value) |
|---|---|---|---|
| delta | −0.102377 | −0.102372 | 0.005% |
| vega | 100,502 | 99,763 | 0.74% |
| rho | −639,498 | −636,332 | 0.50% |
All three agree within the 2% tolerance the check applies. The one-pass calculation took 318 ms; bump-and-revalue needed 7 valuations and took 1,266 ms.
What the model includes
- One policy, projected monthly for 40 years (480 months), from issue age to age 95 at the defaults.
- The account is invested in one equity fund that follows a lognormal market model (Black–Scholes) with constant volatility, interest rate and dividend yield.
- Guarantee fee and fund management fee taken monthly from the account.
- Roll-up: the benefit base grows at the roll-up rate each year, for up to 10 years, until withdrawals begin.
- Ratchet: on each policy anniversary the benefit base steps up to the account value if the account has grown past it. The benefit base never goes down.
- Withdrawals from the start age: the guaranteed amount is the benefit base times the withdrawal rate, of which policyholders take the utilisation share. Once the account is empty, the insurer pays them.
- A death benefit: on death the insurer tops the account up to the death-benefit base.
- Mortality from a Gompertz table (annual death probability 0.1% at age 50, multiplied by about 1.083 for each further year of age).
- Lapses that depend on how valuable the guarantee is: policyholders lapse less when the guarantee is in the money.
- The contract’s sharp edges (account exhausted, ratchet triggered) are smoothed slightly, so every sensitivity is well defined.
It is designed to value and risk-manage a single representative contract quickly, with every sensitivity checkable on the spot.
Worked example (default inputs)
Run on 5 November 2026 with every input at its default and 4,096 paths:
| Output | Result |
|---|---|
| Guarantee liability | USD 17,621 |
| delta | −0.1024 |
| vega | 100,502 per 1.00 of volatility (about USD 1,005 per volatility point) |
| rho | −639,498 per 1.00 of rate (about −USD 6,395 per percentage point) |
Reading it: on a USD 100,000 policy, the insurer expects to pay about USD 17,600, in today’s money, out of its own funds under the guarantee. If the fund rises by USD 1,000, that amount falls by about USD 102. Higher volatility makes it more expensive; higher interest rates make it cheaper.
Scenarios within scenarios: nested
Insurers also need to know what the guarantee will be worth, and what hedge it will need, in the years ahead. nested simulates realistic future markets (outer paths), and at every 12th month for 10 years it revalues the guarantee from wherever each path has got to, with fresh market-consistent paths (inner paths). It reports the average liability, the 95th percentile, the average delta at each date and the worst case. Outer paths use a 5.5% expected equity return, 18% equity volatility and a randomly moving short rate.
Run on 5 November 2026 with 50 outer and 50 inner paths (the limit on the free hosted service; the local install has no such cap): 550 revaluations in 1,028 ms. The average liability rises from USD 17,610 today to USD 90,661 at year 10, with a 95th percentile of USD 173,969 at year 10 and a worst case of USD 224,495. The average delta moves from −0.106 to −0.618. The liability grows because the ratchet locks rising markets into the guarantee. Each figure is in that future year’s money.
Three ways to use it
1. From an AI tool, through the hosted MCP endpoint. In any MCP client, add a remote server with this address and no authentication:
https://mypricinglab.com/lab/mcp
Then ask, for example: “Price the variable annuity model at its defaults and check the sensitivities against bumping.” The tools are list_models, describe_model, price_model, check_against_bumping and run_model_function. The hosted service is free, needs no login, and runs on made-up contracts with capped sizes.
2. In Excel. Install the PricingLab add-in and open the workbook PricingLab_VariableAnnuity.xlsx. Instructions and downloads: https://mypricinglab.com/excel
3. On your own machine. The local install runs the same tools with no size caps, and your inputs never leave your machine. It is sent on request (Linux x86-64 today; ask about Mac and Windows): write to info@mypricinglab.com. Once installed:
pricinglab mcp # MCP server for a local MCP client
pricinglab serve # local web server for the Excel workbook
Details: https://mypricinglab.com/install
With login
A private hosted service, with your own contracts and larger runs, is available. Contact us.
Contact
PricingLab by Raganel Consulting, powered by MatLogica AADC. To run this on your own book, inside your own network, write to info@mypricinglab.com.