P&C Reserving Model
Published on August 24, 2025
this started out as an end-to-end chain-ladder model on a clean development triangle, working through LDFs, CDFs and IBNR/reserves with python visualizations. from there it turned into ongoing open-source contributions to chainladder-python, the main python library for actuarial reserving (maintained by the CAS).
the work has grown past documentation. it now covers the API reference rendering, the public API surface itself, and deprecating stale array backends so the library is leaner and easier to maintain.
so far i’ve had 12 pull requests merged. the early docs work started on an experimental branch, which has since been squashed and merged into main, so everything below now lives on the main line.
documentation and API reference
the goal here was simple: make the core reserving methods readable from the docs alone, without digging through source. if you land on a method, you should see what it does, its signature, and a worked example you can copy.
- #722 - tail constant examples (issue #704) - added worked doctest examples for
TailConstant, so the tail-factor workflow is shown end to end instead of described in the abstract. - #836 - BootstrapODPSample doctest examples - runnable examples for the bootstrap ODP sampler, the method most people reach for when they want a distribution of reserves rather than a point estimate.
- #844 - doctest examples for correlation classes - examples for the development and valuation correlation tests, the diagnostics you run to check whether the chain-ladder assumptions actually hold.
- #848 - README documenting docs build sources and outputs - a contributor-facing README explaining how the docs are built, where the sources live and what each output is, so the next person doesn’t have to reverse-engineer the pipeline.
- #879 - remove autosummary-generated API stubs - cleaned out the auto-generated stub pages that were cluttering the API reference and going stale.
- #885 - render API methods inline via custom autosummary templates - custom sphinx templates so methods render inline on the class page, instead of every method spawning its own thin stub page.
- #900 - bring autosummary templates to parity (issue #847) - brought the remaining templates up to the same standard so the whole API reference renders consistently.
core API
these touch the public surface of the library, the bits users actually import and call, so they were the ones with the most review back-and-forth.
- #901 - add
emptyattribute to Triangle for pandas consistency - gaveTrianglean.emptyattribute that behaves like pandas, so the object feels familiar to anyone already used to dataframes. - #912 - make API exports explicit (issue #876) - made the package exports explicit instead of relying on implicit star-imports, which makes the public API clearer and tooling (autocomplete, linters, type checkers) behave properly.
backend deprecation and cleanup
chainladder carried optional gpu and distributed backends that were mostly unused and hard to maintain. removing them cleanly, behind deprecation warnings rather than sudden breakage, keeps the library lighter without surprising existing users.
- #881 - deprecate cupy array backend (issue #843) - started the deprecation of the cupy (gpu) array backend, with warnings so current users get a heads-up before it’s removed.
- #937 - deprecate dask array backend (issue #842) - same treatment for the dask array backend.
- #1008 - deprecate dask parallel-compute (bag) paths (issue #842) - finished the dask deprecation by removing the parallel-compute (bag) code paths, closing out that cleanup.
what i took from it
the docs work taught me the library inside out, which is what made the later core-API and deprecation work possible. reading and reviewing a mature reserving codebase, then changing it in a way maintainers will accept, is a different skill from writing your own model from scratch, and that’s the part i value most here.
moving forward
i’m keeping at it, working toward a more complete, production-ready chainladder-python. that means more test coverage across the reserving methods, finishing the backend cleanup, and getting deeper into the modelling internals rather than the edges.

