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.pyexamples/aggregate_layer.pyexamples/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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file risksim-0.1.0.tar.gz.
File metadata
- Download URL: risksim-0.1.0.tar.gz
- Upload date:
- Size: 13.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fb1969d767440ce44674164129f5d12510060590526518ad1b8a92b8b8bad5dc
|
|
| MD5 |
da9f9aab680cce122d25ad66eed31ca0
|
|
| BLAKE2b-256 |
f93072084340f8b00daf8d44e217461b5827c156861b13ef1f762119d358cb71
|
File details
Details for the file risksim-0.1.0-py3-none-any.whl.
File metadata
- Download URL: risksim-0.1.0-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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7f375435a48711912955bb8e4d47c407cbc746c9d4eb7962d0aff65cc1b91ff3
|
|
| MD5 |
dd41cbc6f2c69ae65fa1b48b96f7f245
|
|
| BLAKE2b-256 |
cfbaa226cae07cb5210b5627d30345d44dc8476c1dcb0ff594d35e1cc0aa0a72
|