Skip to content

[FEAT] Support CaseOutstanding medial averages - #1560

Draft
priyam0k wants to merge 2 commits into
mainfrom
feature/issue-1512-medial-averages
Draft

priyam0k wants to merge 2 commits into
mainfrom
feature/issue-1512-medial-averages

Conversation

@priyam0k

@priyam0k priyam0k commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Summary of Changes

Routes selection weights in CaseOutstanding through TriangleWeight, bringing full parameter parity with Development (medial averages, drop high/low, drop valuation, preserve) across paid and case ratios. Also adds symmetric shorthand aliases and ensures diagnostic ratio properties retain unweighted historical values.

Related GitHub Issue(s)

Closes #1512

AI/LLM Usage

Used basic model for initial unit test drafting.

Additional Context for Reviewers

Includes test coverage in test_outstanding.py reconciling 5-year medial (5x1) selections against Friedland Chapter 12 Exhibit I and validating scikit-learn clone compatibility.

Submitter's Checklist

  • I have reviewed and am adhering to the standards outlined in the project Governing Doc.
  • The PR subject title summarizes the changes, with one proper prefix ([FIX], [FEAT], [DOCS], [TST], [CHORE], or [BRK]).
  • I am a human (not a bot), and this PR form is written by a human.

Reviewer's Checklist

  • The implementation addresses the associated issue(s).
  • The implementation is appropriate, maintainable, and follows ARCHITECTURE.md.
  • PR subject title has the proper prefix and the subject is appropriate.
  • Relevant issue(s) are linked.
  • AI/LLM usage is disclosed and appropriate.
  • Documentation and tests are appropriate.
  • CI tests passed, or any failures are acceptable.
  • Leave a comment with the final recommendation (e.g. approve as is, request a secondary review, or flag an area for more review).

Note

Medium Risk
Changes core loss-development weighting and ratio math in CaseOutstanding and broadens warning suppression on Triangle aggregates; well covered by tests but affects actuarial outputs.

Overview
CaseOutstanding gains Development-parity selection via TriangleWeight: paid/case medial averages, drop high/low, origin/dev drops, valuation drops, thresholds, and shorthand aliases (n_periods, drop_high, etc.). Fitting builds weighted paid_ldf_/case_ldf_ from origin-level ratios, keeps diagnostic *_to_prior_case_ unweighted, and treats zero case runoff as 0.0 instead of defaulting to 1.0. Ratio properties are reworked to respect valuation cutoffs and zero denominators.

Triangle aggregation now always suppresses empty/All-NaN slice RuntimeWarnings during reduce, not only on partially developed index/column aggregations.

Tests add Friedland 5×1 medial benchmarks, sklearn clone, drop/valuation alignment with Development, and zero-reserve/warning cases.

Reviewed by Cursor Bugbot for commit 7d360d3. Bugbot is set up for automated code reviews on this repo. Configure here.

@priyam0k priyam0k changed the title Support CaseOutstanding medial averages [FEAT] Support CaseOutstanding medial averages Nov 9, 2026
@github-actions

github-actions Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

Pyright Type Completeness

View the full pyright --verifytypes output for this commit

Project (full chainladder package, at this PR's head): 16.4% of exported symbols fully typed (265 / 1611)

Known Ambiguous Unknown Total
Project (head) 265 107 1239 1611

Other symbols referenced but not exported by chainladder: 24

Known Ambiguous Unknown Total
Other (head) 11 1 12 24

Symbols without documentation:

  • Functions without docstring: 326
  • Functions without default param: 0
  • Classes without docstring: 10

Patch (exported symbols added or changed by this PR): 0.0% fully typed (0 / 25)

Known Ambiguous Unknown Total
Patch 0 6 19 25
Patch symbol details
Symbol Status Change
chainladder.development.outstanding.CaseOutstanding.case_drop ❌ unknown new
chainladder.development.outstanding.CaseOutstanding.case_drop_above ⚠️ ambiguous new
chainladder.development.outstanding.CaseOutstanding.case_drop_below ⚠️ ambiguous new
chainladder.development.outstanding.CaseOutstanding.case_drop_high ❌ unknown new
chainladder.development.outstanding.CaseOutstanding.case_drop_low ❌ unknown new
chainladder.development.outstanding.CaseOutstanding.case_drop_valuation ❌ unknown new
chainladder.development.outstanding.CaseOutstanding.case_preserve ⚠️ ambiguous new
chainladder.development.outstanding.CaseOutstanding.drop ❌ unknown new
chainladder.development.outstanding.CaseOutstanding.drop_high ❌ unknown new
chainladder.development.outstanding.CaseOutstanding.drop_low ❌ unknown new
chainladder.development.outstanding.CaseOutstanding.drop_valuation ❌ unknown new
chainladder.development.outstanding.CaseOutstanding.n_periods ❌ unknown new
chainladder.development.outstanding.CaseOutstanding.paid_drop ❌ unknown new
chainladder.development.outstanding.CaseOutstanding.paid_drop_above ⚠️ ambiguous new
chainladder.development.outstanding.CaseOutstanding.paid_drop_below ⚠️ ambiguous new
chainladder.development.outstanding.CaseOutstanding.paid_drop_high ❌ unknown new
chainladder.development.outstanding.CaseOutstanding.paid_drop_low ❌ unknown new
chainladder.development.outstanding.CaseOutstanding.paid_drop_valuation ❌ unknown new
chainladder.development.outstanding.CaseOutstanding.paid_preserve ⚠️ ambiguous new
chainladder.development.outstanding.CaseOutstanding.preserve ❌ unknown new
chainladder.development.tests.test_outstanding.test_case_outstanding_clone_and_sklearn_compatibility ❌ unknown new
chainladder.development.tests.test_outstanding.test_case_outstanding_drop_and_valuation_convention ❌ unknown new
chainladder.development.tests.test_outstanding.test_case_outstanding_medial_averages ❌ unknown new
chainladder.development.tests.test_outstanding.test_case_outstanding_zero_case_reserve_warning ❌ unknown new
chainladder.development.tests.test_outstanding.test_case_outstanding_zero_runoff_preserved ❌ unknown new

@codecov

codecov Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.40230% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.58%. Comparing base (8e2e53c) to head (7d360d3).

Files with missing lines Patch % Lines
chainladder/development/outstanding.py 95.23% 2 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1560      +/-   ##
==========================================
- Coverage   94.59%   94.58%   -0.01%     
==========================================
  Files          98       98              
  Lines        6233     6302      +69     
  Branches      799      800       +1     
==========================================
+ Hits         5896     5961      +65     
- Misses        216      218       +2     
- Partials      121      123       +2     
Flag Coverage Δ
unittests 94.58% <95.40%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread chainladder/development/outstanding.py Resolved
Comment thread chainladder/development/outstanding.py Resolved

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 7d360d3. Configure here.

xp = out.get_array_module()
den = xp.copy(case_sliced[..., :-1])
den[den == 0] = xp.nan
out.values = num / den

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ratio assignment ignores dropped developments

Medium Severity

case_to_prior_case_ and paid_to_prior_case_ valuation-filter the incurred template first, then write num / den from origin-prefix slices of the unfiltered arrays. That filter can drop trailing development periods (single-origin triangles or empty last lags), so the assigned values no longer match out.values and fitting raises a shape error. link_ratio avoids this by computing ratios first, then filtering.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 7d360d3. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ENH] Support medial averages in CaseOutstanding

1 participant