Gaspatchio¶
Gaspatchio is a Python actuarial modelling framework. You build your projection vectors — survival, account values, cashflows, reserves — as columns on an ActuarialFrame. The whole projection runs across every policy together, and every output traces back to the inputs and steps that produced it.

What makes it different¶
You write the projection, not the loop. Assignments like af.qx = mortality.lookup(...) or af.survival = af.qx.projection.cumulative_survival() return a vector across the projection — automatically, per policy. The same line of model code works for one policy or a million.
Closed-form cumulative for most things, rollforward for the rest. Survival probabilities, discount factors, account values with pre-computable charges — closed-form cumulative operations on list columns. COI on net amount at risk, IUL floor/cap, GMDB ratchet, multi-state products — a rollforward() state machine that reads like the within-period product spec.
Fast on the laptop you've already got. The model code is Python; the execution is Rust. A 100,000-policy run with monthly projections over 30 years — mortality lookups, survival, cashflows, account values — finishes in seconds on a workstation, not overnight on a cluster. A million-policy run is minutes, not hours. Edit the model, run it, see the numbers — no batch queue, no IT ticket, no separate environment for "the real run".
Auditable end-to-end. Every output column traces back to inputs and intermediate steps. Schedules, assumption tables, curves, mortality tables, and compiled rollforwards each carry a source_sha(), and that identity rolls up into the rollforward's overall version stamp — so quarter-over-quarter drift is visible the moment it appears, not on page seventeen of an experience study.
A short example¶
Three policies, five-year projection. Look up monthly mortality rates against per-policy attained-age vectors, convert to cumulative survival, and produce an expected-claim vector per policy — all in one composed plan:
import polars as pl
from gaspatchio_core import ActuarialFrame
from gaspatchio_core.assumptions import Table
af = ActuarialFrame(
pl.DataFrame(
{
"policy_id": ["P001", "P002", "P003"],
"sum_assured": [100_000.0, 250_000.0, 500_000.0],
"attained_age": [
[35, 36, 37, 38, 39],
[42, 43, 44, 45, 46],
[55, 56, 57, 58, 59],
],
}
)
)
mortality = Table(
name="qx_demo",
source=pl.DataFrame(
{
"age": list(range(30, 76)),
"qx": [0.001 + (a - 30) * 0.0008 for a in range(30, 76)],
}
),
dimensions={"age": "age"},
value="qx",
)
# Vector lookup against the attained-age vector — one rate vector per policy
af.qx = mortality.lookup(age=af.attained_age)
# Closed-form cumulative survival — replaces the recursive ₜpₓ loop
af.survival = af.qx.projection.cumulative_survival()
# Expected claims per policy per year, as a vector
af.expected_claims = af.survival * af.qx * af.sum_assured
print(af.select("policy_id", "survival", "expected_claims").collect())
shape: (3, 3)
┌───────────┬───────────────────────────┬─────────────────────────────────┐
│ policy_id ┆ survival ┆ expected_claims │
│ --- ┆ --- ┆ --- │
│ str ┆ list[f64] ┆ list[f64] │
╞═══════════╪═══════════════════════════╪═════════════════════════════════╡
│ P001 ┆ [1.0, 0.995, … 0.975428] ┆ [500.0, 577.1, … 799.851049] │
│ P002 ┆ [1.0, 0.9894, … 0.953627] ┆ [2650.0, 2819.79, … 3290.01427… │
│ P003 ┆ [1.0, 0.979, … 0.914112] ┆ [10500.0, 10671.1, … 11060.755… │
└───────────┴───────────────────────────┴─────────────────────────────────┘
mortality.lookup returns a five-element vector per policy, aligned to that policy's attained-age vector. projection.cumulative_survival() walks each vector once. expected_claims broadcasts the scalar sum_assured against the survival and qx vectors. Nothing in the model code mentions "time step" or "iteration" — and the plan runs across every policy together when .collect() is called.
Where to go next¶
- Tutorials — build a model on the four-level ladder, from a first projection through a reconciled production model.
- Concepts — understand how the framework thinks. Start with the Intro, then Schedules, Projections, Assumptions, and Rollforward.
- API Reference — full surface:
ActuarialFrame,Schedule,Table,MortalityTable,Curve,rollforward,accumulate, scenarios, and the Excel/finance/date function namespaces.