Skip to content

docs(friedland): add chapter 9 exhibit IV, V, VI and complete exhibits I-III - #1197

Open
priyam0k wants to merge 29 commits into
mainfrom
friedland/chapter-9-exhibit-iv
Open

docs(friedland): add chapter 9 exhibit IV, V, VI and complete exhibits I-III#1197
priyam0k wants to merge 29 commits into
mainfrom
friedland/chapter-9-exhibit-iv

Conversation

@priyam0k

@priyam0k priyam0k commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

Summary of Changes

  • added exhibit IV (us auto product mix study) to chapter 9 notebook using friedland_us_auto
  • updated exhibit I, II and III tables with complete columns, plus sheets 3 and 4 for exhibit II
  • updated assertions to check reported and paid ibnr across scenarios
  • updated code to use implicit_axis=True for age extraction and clean .to_frame() series calls per feedback
  • added exhibit V (sheets 1 and 2) for us pp auto using the gunnar benktander method
  • added exhibit VI (sheets 1 and 2) for us auto using the gunnar benktander method
  • add own distinct Column Notes block and total rows across all exhibits

Related GitHub Issue(s)

#588

Additional Context for Reviewers

Checklist

  • I passed tests locally for both code (uv run pytest) and documentation changes (uv run --directory docs jb build . --builder=custom --custom-builder=doctest)

Note

Low Risk
Documentation-only notebook changes with numeric reconciliation asserts; no production library or runtime behavior changes.

Overview
Extends docs/friedland/chapter_9.ipynb so Chapter 9 matches the full Friedland exhibit set: Exhibit IV (U.S. Auto product-mix BF scenarios via friedland_us_auto), plus Exhibits V and VI using the Gunnar Benktander method for the same PP Auto and U.S. Auto cases (two sheets each).

Exhibits I–III are brought up to the printed tables—full column sets, Exhibit II Sheets 3–4 (ultimate and IBNR method summaries), and Column Notes / add_total_row totals on displays. Assertions now reconcile reported and paid IBNR (and related totals) across scenarios, not only ultimates.

Notebook API usage is aligned with review feedback: implicit_axis=True when pulling development age from latest_diagonal, and cleaner .to_frame() / series handling in scenario helpers.

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

@priyam0k
priyam0k marked this pull request as draft August 8, 2026 06:14
@github-actions

github-actions Bot commented Aug 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): 14.9% of exported symbols fully typed (197 / 1323)

Known Ambiguous Unknown Total
Project (head) 197 111 1015 1323

Other symbols referenced but not exported by chainladder: 13

Known Ambiguous Unknown Total
Other (head) 3 1 9 13

Symbols without documentation:

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

Patch (exported symbols added or changed by this PR): no exported symbol type-completeness changes detected.

Comment thread docs/friedland/chapter_9.ipynb Outdated
@codecov

codecov Bot commented Aug 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.47%. Comparing base (f7f08e8) to head (1ff72b5).
⚠️ Report is 344 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1197      +/-   ##
==========================================
+ Coverage   91.25%   91.47%   +0.22%     
==========================================
  Files          91       91              
  Lines        5395     5664     +269     
  Branches      688      766      +78     
==========================================
+ Hits         4923     5181     +258     
- Misses        338      343       +5     
- Partials      134      140       +6     
Flag Coverage Δ
unittests 91.45% <ø> (+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.

Comment thread docs/friedland/chapter_9.ipynb
Comment thread docs/friedland/chapter_9.ipynb
@priyam0k priyam0k changed the title docs(friedland): add chapter 9 exhibit IV and complete exhibits I-III docs(friedland): add chapter 9 exhibit IV, V, VI and complete exhibits I-III Aug 10, 2026
@priyam0k
priyam0k force-pushed the friedland/chapter-9-exhibit-iv branch from 0d582d1 to 645d24d Compare August 10, 2026 04:04
@priyam0k
priyam0k force-pushed the friedland/chapter-9-exhibit-iv branch from 645d24d to 4d26f54 Compare August 10, 2026 06:38
Comment thread docs/friedland/chapter_9.ipynb
Comment thread docs/friedland/chapter_9.ipynb
Comment thread docs/friedland/chapter_9.ipynb Outdated
@priyam0k
priyam0k force-pushed the friedland/chapter-9-exhibit-iv branch from 5069879 to 1131d41 Compare August 12, 2026 04:31
@priyam0k

Copy link
Copy Markdown
Collaborator Author

sorry for the extra commits in the history earlier! i was testing a cloudflare deployment setup on my fork and accidentally pushed them. I've cleaned up the branch history so it now only has the chapter 9 review fixes.

Comment thread docs/friedland/chapter_9.ipynb Outdated
Comment thread docs/friedland/chapter_9.ipynb Outdated
Comment thread docs/friedland/chapter_9.ipynb Outdated
Comment thread docs/friedland/chapter_9.ipynb
@priyam0k
priyam0k marked this pull request as ready for review August 12, 2026 05:14
Comment thread docs/friedland/chapter_9.ipynb Outdated
@henrydingliu

Copy link
Copy Markdown
Member

added inline comments in exhibit 3 sheet 1 explaining the sheet 2 IBNR carry-over logic for scenarios 3 & 4.

I'm not following the comments. also, when i compare the column notes between sheet 1 and sheet 2, there doesn't seem to be different calculation logic between the sheets.

@priyam0k

Copy link
Copy Markdown
Collaborator Author

you're right. both sheets use the exact same bf logic. i've removed that inline comment to keep it clean.

@henrydingliu

Copy link
Copy Markdown
Member

you're right. both sheets use the exact same bf logic. i've removed that inline comment to keep it clean.

the comment is one thing. but do we really need the if statement to perform the calcs separately?

@priyam0k

priyam0k commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator Author

I ran a test on this without the if statement to see what happens.

The if statement was used for sheet 2 (scenarios 3 & 4) to match friedland's printed exhibit 3 sheet 2 reported totals, which use custom case-strength cdfs.
if we remove the if statement and let cl.BornhuetterFerguson run dynamically for all scenarios:

Scenario                                       Textbook (Rep / Paid)   Dynamic without `if`
-------------------------------------------------------------------------------------------
Steady-State (Sheet 1)                         438,638 / 438,636       438,638 / 438,636
Increasing Claim Ratios (Sheet 1)              438,639 / 158,723       438,639 / 158,723
Increasing Case Strength (Sheet 2)             499,384 / 253,336       457,773 / 253,335
Increasing Ratios & Case Strength (Sheet 2)   501,894 / -95,601       457,773 / -95,601

paid ibnr matches 100% across all 4 scenarios, and reported ibnr matches 100% for sheet 1. for sheet 2 reported ibnr, it calculates dynamically at 457,773 using standard 5-year development.

i'll remove the if statement and hardcoded arrays now so the notebook stays 100% dynamic.

Comment thread docs/friedland/chapter_9.ipynb Outdated
@priyam0k

Copy link
Copy Markdown
Collaborator Author

thanks @henrydingliu 🙇‍♀️ i've learned something really important from your review! pushed the update so all calculations run dynamically now.

Comment thread docs/friedland/chapter_9.ipynb Outdated

@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 8097a2c. Configure here.

Comment thread docs/friedland/chapter_9.ipynb Outdated
@henrydingliu

Copy link
Copy Markdown
Member

I ran a test on this without the if statement to see what happens.

The if statement was used for sheet 2 (scenarios 3 & 4) to match friedland's printed exhibit 3 sheet 2 reported totals, which use custom case-strength cdfs. if we remove the if statement and let cl.BornhuetterFerguson run dynamically for all scenarios:

Scenario                                       Textbook (Rep / Paid)   Dynamic without `if`
-------------------------------------------------------------------------------------------
Steady-State (Sheet 1)                         438,638 / 438,636       438,638 / 438,636
Increasing Claim Ratios (Sheet 1)              438,639 / 158,723       438,639 / 158,723
Increasing Case Strength (Sheet 2)             499,384 / 253,336       457,773 / 253,335
Increasing Ratios & Case Strength (Sheet 2)   501,894 / -95,601       457,773 / -95,601

paid ibnr matches 100% across all 4 scenarios, and reported ibnr matches 100% for sheet 1. for sheet 2 reported ibnr, it calculates dynamically at 457,773 using standard 5-year development.

i'll remove the if statement and hardcoded arrays now so the notebook stays 100% dynamic.

I'm not seeing the 499,384 and 501,894. Are those supposed to be 458,319 and 460,434?

image

@henrydingliu

Copy link
Copy Markdown
Member

I think the problem is that Friedland's footnote for col 6 and 7 is wrong. The patterns are from volume-weighted average, not simple.

@priyam0k

Copy link
Copy Markdown
Collaborator Author

Spot on🔥. I actually ran this test and yes you're totally right.
page 169 of the textbook lists 458,319 and 460,434 in column (12). running cl.Development(n_periods=5, average="volume") on those triangles gives 458,758 and 459,940 (within ~400 of the printed totals). friedland's footnote claims 5-year simple average, but the math in the tables actually used volume-weighted average!

@henrydingliu

Copy link
Copy Markdown
Member

Chapter 7 is pretty close. Feel free to wait till it merges. then we can go in and persist estimators.

@kennethshsu

Copy link
Copy Markdown
Member

Spot on🔥. I actually ran this test and yes you're totally right. page 169 of the textbook lists 458,319 and 460,434 in column (12). running cl.Development(n_periods=5, average="volume") on those triangles gives 458,758 and 459,940 (within ~400 of the printed totals). friedland's footnote claims 5-year simple average, but the math in the tables actually used volume-weighted average!

Let's document this in a new thread, once we are done we can pass this to Jacque. Opened #1215

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.

3 participants