Skip to main content

Portfolio-level loss simulation and aggregate treaty modeling in Python

Project description

risksim

risksim is a Python package for portfolio-level loss simulation and aggregate treaty modeling.

It is designed to sit on top of stochastic loss models that expose a .sample(size) method. In particular, it pairs naturally with lossmodels, where lossmodels handles loss-model generation and risksim handles portfolio composition, aggregate contracts, and simulation summaries.

Features

  • combine multiple simulated loss components into a portfolio
  • apply aggregate annual layers
  • build simple multi-layer aggregate contract programs
  • summarize gross, ceded, and retained loss
  • compute simulation-based risk measures such as mean, VaR, and TVaR

Installation

From PyPI

pip install risksim

From source

git clone https://github.com/michaelabryant/risksim.git
cd risksim
pip install -e .

Optional companion package

risksim works with any model that implements:

sample(size: int = 1) -> np.ndarray

Many of the examples below use lossmodels, which provides aggregate actuarial loss models that integrate naturally with risksim.

If you want to run the lossmodels examples locally, install lossmodels as well.

Quick start

Any object with a .sample(size) method can be used inside a Portfolio.

import numpy as np

from risksim import AggregateLayer, Portfolio, PortfolioItem


class ConstantModel:
    def __init__(self, value: float) -> None:
        self.value = float(value)

    def sample(self, size: int = 1) -> np.ndarray:
        return np.full(size, self.value, dtype=float)

    def mean(self) -> float:
        return self.value

    def variance(self) -> float:
        return 0.0


medical = ConstantModel(200.0)
rx = ConstantModel(50.0)

portfolio = Portfolio(
    [
        PortfolioItem("medical", medical),
        PortfolioItem("rx", rx),
    ]
)

contract = AggregateLayer(
    attachment=100.0,
    limit=75.0,
    share=1.0,
    name="aggregate_xol",
)

result = portfolio.simulate(size=10_000, contract=contract)

print("net mean:", result.mean())
print("gross mean:", result.gross_mean())
print("ceded mean:", result.ceded_mean())
print("VaR 99%:", result.var(0.99))
print("TVaR 99%:", result.tvar(0.99))
print(result.summary())

Using lossmodels

A common workflow is to build aggregate loss models with lossmodels and then combine them with risksim.

from lossmodels.aggregate import CollectiveRiskModel
from lossmodels.frequency import Poisson
from lossmodels.severity import Lognormal

from risksim import AggregateLayer, Portfolio, PortfolioItem

medical = CollectiveRiskModel(
    Poisson(lam=2.0),
    Lognormal(mu=2.0, sigma=0.3),
)

rx = CollectiveRiskModel(
    Poisson(lam=1.0),
    Lognormal(mu=1.5, sigma=0.2),
)

portfolio = Portfolio(
    [
        PortfolioItem("medical", medical),
        PortfolioItem("rx", rx),
    ]
)

contract = AggregateLayer(
    attachment=50.0,
    limit=100.0,
    name="agg_xol",
)

result = portfolio.simulate(size=50_000, contract=contract)
print(result.summary())

Contract programs

risksim also supports simple multi-layer aggregate contract programs.

from lossmodels.aggregate import CollectiveRiskModel
from lossmodels.frequency import Poisson
from lossmodels.severity import Lognormal

from risksim import AggregateLayer, ContractProgram, Portfolio, PortfolioItem

line = CollectiveRiskModel(
    Poisson(lam=4.0),
    Lognormal(mu=3.5, sigma=0.7),
)

portfolio = Portfolio([PortfolioItem("line", line)])

program = ContractProgram(
    [
        AggregateLayer(attachment=50.0, limit=50.0, name="layer_1"),
        AggregateLayer(attachment=100.0, limit=100.0, name="layer_2"),
    ],
    name="two_layer_tower",
)

result = portfolio.simulate(size=20_000, contract=program)

print("gross mean:", result.gross_mean())
print("ceded mean:", result.ceded_mean())
print("retained mean:", result.retained_mean())
print("layer means:", result.layer_means())

Public API

from risksim import AggregateLayer, ContractProgram, Portfolio, PortfolioItem, SimulationResult

Core concepts

PortfolioItem

Wraps one simulated component with a name and optional weight.

Portfolio

Combines multiple simulated components into a total portfolio loss.

AggregateLayer

Applies a single aggregate annual contract to simulated gross losses.

For annual gross loss S, ceded loss is:

share * min(max(S - attachment, 0), limit)

with no cap if limit=None.

ContractProgram

Combines multiple aggregate layers applied to the same gross loss.

SimulationResult

Stores simulation outputs and provides convenience methods such as:

  • mean()
  • variance()
  • std()
  • var(q)
  • tvar(q)
  • prob_exceeding(threshold)
  • summary()

If retained losses are present, the primary losses view is net/retained loss. Otherwise it is gross loss.

Example scripts

The examples/ directory contains runnable scripts:

  • examples/basic_portfolio.py
  • examples/aggregate_layer.py
  • examples/contract_program.py

Run them with:

python examples/basic_portfolio.py
python examples/aggregate_layer.py
python examples/contract_program.py

Project scope

The current version focuses on:

  • portfolio-level simulation from component loss models
  • aggregate annual treaty application
  • simple non-overlapping multi-layer programs
  • simulation-based portfolio summaries

It does not yet model:

  • dependence between components
  • occurrence-based contracts requiring claim-level paths
  • reinstatements
  • capital allocation
  • premium or pricing workflows beyond simulated summaries

Development

Run the test suite with:

python -m pytest -q

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

risksim-0.1.1.tar.gz (13.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

risksim-0.1.1-py3-none-any.whl (9.8 kB view details)

Uploaded Python 3

File details

Details for the file risksim-0.1.1.tar.gz.

File metadata

  • Download URL: risksim-0.1.1.tar.gz
  • Upload date:
  • Size: 13.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for risksim-0.1.1.tar.gz
Algorithm Hash digest
SHA256 fd23aef0aae7f6f4e9251eb4eee11d7dc128f4abb17dfcc770387b1b2dc6d724
MD5 acedc9f325b374bf5a4b5be4c2cd652b
BLAKE2b-256 4eb39672c9b242bd9943218f0df112f315a6bd7771c36485fac7f5fa5a648465

See more details on using hashes here.

File details

Details for the file risksim-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: risksim-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 9.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for risksim-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 001c9dce7e07b9c7a0427b9b47faa7dfdc9c06d355308783f57d152d81fe4c6a
MD5 91b8503db25ed482e0ba0ee560d77579
BLAKE2b-256 d4137f778dc6de47bb55b2950e3a0591f251073f014a4cb887a10422cb514d0f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page