Skip to content

fix(development): preserve unweighted diagnostic ratios in CaseOutstanding (#1511) - #1550

Merged
henrydingliu merged 2 commits into
casact:mainfrom
X6M-Work:fix-case-outstanding-unweighted-ratios-1511
Nov 9, 2026
Merged

henrydingliu merged 2 commits into
casact:mainfrom
X6M-Work:fix-case-outstanding-unweighted-ratios-1511

Conversation

@X6M-Work

@X6M-Work X6M-Work commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

Summary of Changes

Fixes #1511

This pull request ensures that diagnostic properties paid_to_prior_case_ and case_to_prior_case_ in CaseOutstanding preserve unweighted historical ratios across all origin periods, matching the design of Development.link_ratio_.

Root Cause

Previously, case_to_prior_case_ and paid_to_prior_case_ directly multiplied the computed ratios by self.case_w_ and self.paid_w_. When case_n_periods or paid_n_periods were specified, older historical origin periods were masked with 0.0. This prevented inspection and review of historical ratios across the full triangle when tuning window lengths.

Solution

  1. In chainladder/development/outstanding.py:
    • Removed direct multiplication by self.case_w_ from case_to_prior_case_ and by self.paid_w_ from paid_to_prior_case_.
    • In fit(), multiplied the unweighted ratio triangles by self.case_w_ and self.paid_w_ before NaN conversion (num_to_nan) and computing the weighted selection averages case_ldf_ and paid_ldf_.
  2. Verified that fitted factors (case_ldf_, paid_ldf_, and downstream projections) remain identical.
  3. Added unit test test_unweighted_ratios_preserved_when_n_periods_set in chainladder/development/tests/test_outstanding.py verifying that historical periods older than n_periods are not masked with 0.0 and match the unweighted values of the full model.

Verification & Validation

  • Ran uv run pytest chainladder/development/tests/test_outstanding.py: 11/11 tests passed.
  • Ran full development suite uv run pytest chainladder/development/: 140/140 tests passed.

@github-actions

github-actions Bot commented Nov 8, 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.3% of exported symbols fully typed (259 / 1592)

Known Ambiguous Unknown Total
Project (head) 259 104 1229 1592

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: 335
  • Functions without default param: 0
  • Classes without docstring: 10

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

Known Ambiguous Unknown Total
Patch 0 0 1 1
Patch symbol details
Symbol Status Change
chainladder.development.tests.test_outstanding.test_unweighted_ratios_preserved_when_n_periods_set ❌ unknown new

@codecov

codecov Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.59%. Comparing base (b44fedc) to head (a3e4754).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1550      +/-   ##
==========================================
+ Coverage   94.39%   94.59%   +0.20%     
==========================================
  Files          98       98              
  Lines        6222     6233      +11     
  Branches      799      799              
==========================================
+ Hits         5873     5896      +23     
+ Misses        225      216       -9     
+ Partials      124      121       -3     
Flag Coverage Δ
unittests 94.59% <100.00%> (+0.20%) ⬆️

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.

@priyam0k

priyam0k commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Welcome to the repo @X6M-Work

The fix and test look correct, preserves the unweighted diagnostic ratios cleanly without touching downstream selections. LGTM

Just curious,how did you come across this issue or work in actuarial ?

@X6M-Work

X6M-Work commented Nov 9, 2026

Copy link
Copy Markdown
Contributor Author

Welcome to the repo @X6M-Work

The fix and test look correct, preserves the unweighted diagnostic ratios cleanly without touching downstream selections. LGTM

Just curious,how did you come across this issue or work in actuarial ?

Thanks for the review and the welcome, i don’t work in actuarial science. I was looking for well described open bugs in Python projects, and your issue had a clear repro and expected behavior, which made it easy to pick up. I learned a bit about case outstanding development along the way.

@priyam0k

priyam0k commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

Glad the issue was easy to follow

If you're looking for other Python-focused bugs with clear repros to pick up next, check out the Great First Contribution issues list. A couple of clean, self-contained ones open right now are #1481 (cum_to_incr inplace support) and #1477 (dev_to_val / val_to_dev inplace support).

@henrydingliu
henrydingliu merged commit c9feefd into casact:main Nov 9, 2026
11 checks passed
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.

[BUG] Preserve unweighted ratios in CaseOutstanding

3 participants