Skip to content

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

Open
priyam0k wants to merge 36 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 36 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 (202 / 1355)

Known Ambiguous Unknown Total
Project (head) 202 111 1042 1355

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: 323
  • 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.31%. Comparing base (bd0d539) to head (52bdd7a).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1197   +/-   ##
=======================================
  Coverage   91.31%   91.31%           
=======================================
  Files          91       91           
  Lines        5434     5434           
  Branches      700      700           
=======================================
  Hits         4962     4962           
  Misses        336      336           
  Partials      136      136           
Flag Coverage Δ
unittests 91.31% <ø> (ø)

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
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

@henrydingliu

Copy link
Copy Markdown
Member

FYI Chapter 7 is in.

@priyam0k

Copy link
Copy Markdown
Collaborator Author

yep, i'll update ch9 to load the persisted estimators..

@priyam0k

priyam0k commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator Author

i think there's also scope to add this in ch10 (capecod) too in a follow-up pr and make it more consistent like ch9..

Comment thread docs/friedland/chapter_9.ipynb Outdated
Comment thread docs/friedland/chapter_9.ipynb Outdated
Comment thread docs/friedland/chapter_9.ipynb Outdated
@priyam0k
priyam0k force-pushed the friedland/chapter-9-exhibit-iv branch from ebb6ca8 to ce60441 Compare August 19, 2026 20:00
Comment thread docs/friedland/chapter_9.ipynb

@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 2 potential issues.

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 e1d23b3. Configure here.

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

Copy link
Copy Markdown
Collaborator Author

while working on Chapter 9 Exhibit I, I came across another small rounding nuance and was wondering if this is worth adding to the error tracking list #1215 ? . I can find similar in other exhibits also:

Location Error Correction / Implementation Note
Actual page 168 (Printed page 162) Exhibit I, Sheet 1 Column Notes (7) & (8) state (7) = [(2) x (5)] and (8) = [(2) x (6)] using printed 3-decimal emergence percentages. Printed table values in (7) & (8) were computed using full unrounded CDF precision (2) x (1.0 - 1.0 / (3)). Multiplying by printed 3-decimal % (5) introduces rounding error per row and distorts the total.

@kennethshsu

Copy link
Copy Markdown
Member

Column 7 and 8 doesn't actually say they are using the rounded numbers though? Where do you see this?

@priyam0k

Copy link
Copy Markdown
Collaborator Author

You're right that the column notes don't explicitly say to round (5) before multiplying.

the reason i brought this up is because column (5) in the exhibit table is displayed as 22.6% (0.226). if someone calculates (7) = (2) x (5) using that displayed 3-decimal percentage (0.226), it gives a noticeable dollar difference vs friedland's printed table in (7).

image image

friedland's printed table values in (7) actually come from using full unrounded cdf precision (2) x (1 - 1 / (3)):

accident year expected claims (2) cdf (3) printed table (7) method 1: unrounded (2) x (1 - 1/(3)) m1 diff vs book method 2: display mult (2) x round((5), 3) m2 diff vs book
1998 51,430,657 1.000 0 0 $0 0 $0
1999 51,408,736 1.000 0 0 $0 0 $0
2000 51,680,983 1.001 51,629 51,629 $0 51,681 +$52
2001 54,408,716 1.003 162,738 162,738 $0 163,226 +$488
2002 59,421,665 1.006 354,404 354,404 $0 356,530 +$2,126
2003 56,318,302 1.011 612,761 612,761 $0 619,501 +$6,740
2004 59,646,290 1.023 1,341,021 1,341,021 $0 1,312,218 -$28,803
2005 61,174,953 1.051 2,968,528 2,968,528 $0 2,997,573 +$29,045
2006 61,926,981 1.110 6,136,908 6,136,908 $0 6,130,771 -$6,137
2007 61,864,556 1.292 13,981,773 13,981,773 $0 13,981,390 -$383
total 569,281,839 25,609,761 25,609,761 $0 25,612,890 +$3,129

I'm also quite confused where this belongs,

@henrydingliu

Copy link
Copy Markdown
Member

@priyam0k we are trying to use chainladder constructs to fill out these exhibits. doesn't mean we need to follow the column notes exxactly. i would use ibnr_ to fill in column 7. it doesn't matter that ibnr_ is a property that depends on ultimate_ being available.

@kennethshsu

Copy link
Copy Markdown
Member

Ya unfortunately when the text is printed we lose all this info. I think if it's a typical usage of round/non-round number, we just document in the recreation work and it won't need to go on #1215. Now, if the numbers aren't tying with either rounded nor non-rounded numbers, then we should let the author know.

My point is if we include this specific example, we would be including a bunch of instances and will clog up "real errors".

@priyam0k

Copy link
Copy Markdown
Collaborator Author

i would use ibnr_ to fill in column 7

Got it @henrydingliu . Will use native chainladder properties

I think if it's a typical usage of round/non-round number, we just document in the recreation work and it won't need to go on #1215

Yes i agree, keeping #1215 issue strictly for real textbook errors and keep rounding notes inline in the notebook.

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