Skip to main content

 Commit activity Documentation Status Latest version  Supported Python versions Downloads Github stars Github forks  License Zenodo DOI


aggregate: working with actuarial compound distributions

Purpose

aggregate builds essentially exact compound (aggregate) probability distributions quickly and accurately. It can be used to solve insurance, risk management, and actuarial problems using realistic models that reflect underlying frequency and severity. It delivers the speed and accuracy of parametric distributions to situations that usually require simulation, making it as easy to work with an aggregate (compound) probability distribution as the lognormal. aggregate includes an expressive language called DecL to describe aggregate distributions and is implemented in Python under an open source BSD-license.

Version 1.0

Version 1.0 represents a substantial extension over the prior 0.30.1 release. It was written in collaboration with Claude Code and adds:

  • The ability to model positive and negative amounts, opening the way for a PnL profit-and-loss class supporting price quoting and evaluation.
  • Automated generation of incremental gross–ceded–net views across multi-layer occurrence and aggregate programs.
  • FFT calculations performed in a support window that need not include the origin, providing more efficient discretization.
  • Bivariate distributions, including bivariate severity, clash, ceded–net, gross-cede, and gross–net models.
  • Standard reinsurance variable features: swings, slides, profit commissions, reinstatements, and loss corridors, as well as loss-sensitive retro rating used in large accounts.

Aggregate White Paper

Aggregate: fast, accurate, and flexible approximation of compound probability distributions describes the Aggregate class within aggregate. This paper has been published in the peer reviewed journal Annals of Actuarial Science's Actuarial Software series. The paper describes the purpose, implementation, and use Aggregate, showing how it can be used to create and manipulate compound frequency-severity distributions.

Changelog

See CHANGELOG.md for the full version history.

API stability

Almost everything is stable. Aggregate, Portfolio, PnL, Severity, Frequency, Distortion, BivariateAggregate, Underwriter, build, qd and the DecL grammar carry the usual promise: from 1.0 onward a documented name keeps its meaning, and a breaking change waits for a major release after a deprecation period.

Two modules are provisional, in the sense of PEP 411: aggregate.charts and aggregate.exhibits. They are not part of the 1.0 API contract and may change in a minor release with no deprecation period. They are additive side projects to the release, they import from the core and the core does not import them, so nothing in them can reach the stable surface. They are public on purpose: use them and report what does not fit, which is how a provisional module graduates to stable.

The full statement, including exactly what "provisional" covers in each, is in the API Stability page of the documentation.

Documentation

https://aggregate.readthedocs.io/

Where to get it

https://github.com/mynl/aggregate

Installation

aggregate requires Python 3.12 or later. The strongly recommended way to install and manage it is with uv, Astral's fast Python package and project manager — follow the uv installation guide to get it.

Once uv is installed, add aggregate to a uv-managed project:

uv init myproject      # or cd into an existing uv project
cd myproject
uv add aggregate       # resolves, locks, and installs into .venv

uv add records the dependency in your pyproject.toml and syncs the project environment; from then on uv sync recreates that exact, locked environment on any machine. Optional extras add capabilities:

uv add "aggregate[numba]"     # numba-compiled TVaR paths
uv add "aggregate[viz]"       # interactive bivariate exploration: holoviews, datashader, bokeh
uv add "aggregate[massive]"   # disk-backed bivariate grids via zarr
uv add "aggregate[notebook]"  # JupyterLab, widgets
uv add "aggregate[dev]"       # documentation build and test tooling
uv add "aggregate[all]"       # all of the above except dev

Run anything inside the managed environment with uv run, for example uv run python or uv run jupyter lab. All the code examples have been tested in such an environment and the documentation builds in it.

If you already have an environment and simply want the package dropped into it, install it directly — with uv:

uv pip install aggregate

or with plain pip:

pip install aggregate

Getting started

To get started, import build. It provides easy access to all functionality. The function qd is a quick display helper, printing germane information.

Here is a model of the sum of three dice rolls. Running qd(a) prints the mean, SD, CV, skewness, and 1st, 50th and 99th percentiles for the frequency, severity, and aggregate components. Common statistical functions like the cdf and quantile function are built-in. The whole probability distribution is available in a.density_df.

from aggregate import build, qd
a = build('agg Dice dfreq [3] dsev [1:6]')
qd(a)

>>> Aggregate object: Dice. Frequency distribution empirical. Severity
    dhistogram, [1, 6], bounded; atoms [1 2 3 4 5 6]. Updated with bucket
    size 1 and log2 = 5. Validation: not unreasonable.

>>>       Mean     SD      CV Skew P01 Median P99
>>> X
>>> Freq     3      0       0
>>> Sev    3.5 1.7078 0.48795    0   1      3   6
>>> Agg   10.5  2.958 0.28172    0   4     10  17

print(f'\nProbability sum < 12 = {a.cdf(12):.3f}\nMedian = {a.q(0.5):.0f}')

>>> Probability sum < 12 = 0.741
>>> Median = 10

aggregate can use any scipy.stats continuous random variable as a severity, and supports all common frequency distributions. Here is a compound-Poisson with lognormal severity, mean 50 and cv 2.

a = build('agg Example 10 claims sev lognorm 50 cv 2 poisson')
qd(a)

>>> Aggregate object: Example. Frequency distribution poisson. Severity lognorm,
    [0, inf), subexponential right tail. Updated with bucket size 2 and log2 =
    16. Validation: not unreasonable.

>>>       Mean     SD      CV    Skew P01 Median  P99
>>> X
>>> Freq    10 3.1623 0.31623 0.31623
>>> Sev     50    100       2  13.981   2     22  428
>>> Agg    500 353.56 0.70711  3.5312  68    422 1736

See the documentation for more examples.

In JupyterLab: the %%agg cell magic

In a notebook the DecL does not have to live inside a Python string. Load the magic once per kernel:

%load_ext aggregate.magics

and write the program as the cell:

%%agg
agg Dice dfreq [3] dsev [1:6]

which is exactly a = build('agg Dice dfreq [3] dsev [1:6]') followed by qd(a), with two conveniences: the program is not in quotes, so your editor still highlights it as DecL, and the object is bound to its declared name as well as to a, giving both a and Dice.

Full descriptions are in the documentation.

Dependencies

See pyproject.toml.

Running the tests

The pytest suite lives in tests/:

uv run pytest                             # fast suite (multi-minute cases deselected)
uv run pytest -m "slow or not slow"       # everything, including the slow bivariate cases
uv run pytest tests/test_decl_parser.py   # one file; add -k "pattern" to filter by name

Pricing Insurance Risk Examples

aggregate was used to create all of the examples, figures, and tables in Pricing Insurance Risk. Those exhibits can still be re-created using version 0.30.1 (the Baseline release). However, much of the needed functionality was removed in version 1.0, because it was not core to the go-forward purpose of the package: it compared recommended (spectral) methods with (not recommended) legacy methods. The blog post describes how to create PIR exhibits for a custom portfolio, again using the Baseline release.

License

BSD 3 license.

Contributions

All contributions, bug reports, bug fixes, documentation improvements, enhancements and ideas are welcome. Create a pull request on github and/or email me.

Social media: https://www.reddit.com/r/AggregateDistribution/.

Blog: https://blog.mynl.com

Metadata

Release files for aggregate 1.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aggregate 1.0.1
File Size Uploaded
aggregate-1.0.1.tar.gz 1.7 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for aggregate 1.0.1
File Interpreter ABI Platform
aggregate-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 3.0 MB

Release files / aggregate-1.0.1.tar.gz

Download URL aggregate-1.0.1.tar.gz
Size 1.7 MB
Tags Source
SHA-256 checksum
How to use checksums
0a03fdd6ad1d82af950870a1b8a77b45f49bf5e69ed44b120c384bff228135ab
BLAKE2b-256 checksum
How to use checksums
31188574f1fd7fc15d58a0d7ad8a2d0d933521d2125fb5fb8d2a559c8b770c44
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / aggregate-1.0.1-py3-none-any.whl

Download URL aggregate-1.0.1-py3-none-any.whl
Size 1.2 MB
Tags Python 3
SHA-256 checksum
How to use checksums
5fd348bb9ace31fc05ba0cc61cf64d663851535b823951270db168892d7b5800
BLAKE2b-256 checksum
How to use checksums
692f519e23ae30ae2b439b58c9133e3bac37f8a4e0c72c4ad4e26968203ad75d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

1.2.0

2 release files

This release

1.0.1 This release

2 release files

0.30.1

1 release file

0.30.0

2 release files

0.24.2

2 release files

0.24.0

2 release files

0.22.0

2 release files

0.21.2

2 release files

0.21.1

2 release files

0.20.0

2 release files

0.16.0

2 release files

0.12.0

2 release files

0.11.7

2 release files

0.11.4

2 release files

0.11.3

2 release files

0.11.2

2 release files

0.11.1

2 release files

0.11.0

2 release files

0.10.7

2 release files

0.10.6

2 release files

0.10.5

2 release files

0.10.4

2 release files

0.10.3

2 release files

0.10.2

2 release files

0.10.1

2 release files

0.10.0

2 release files

0.9.6

2 release files

0.9.5

1 release file

0.9.3

1 release file

0.9.2

1 release file

0.9.1

2 release files

0.7.10

2 release files

0.7.9

2 release files

0.7.8

2 release files

0.7.7

2 release files

0.7.6

2 release files

0.7.5

2 release files

0.7.4

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6

2 release files

0.5

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page