Skip to content

[ENH]/[BRK] Add ultimate alias #1345

Description

@genedan

Chainladder sets some far away date/development age to indicate ultimate values:

Image

While this allows the development dimension to contain values of the same data type, I don't think this will fly when it comes to executive presentations, IBNR meetings, etc. This presents a "last mile" type problem where the user is all like, "man, I want to relabel that value, I guess it's time to paste everything in Excel."

Secondly, the placeholder values are unlikely to be indexed directly as the user would have to look up the "2262-01-01" value as it's not easy to remember.

I propose that we allow the user to relabel the value with an alias of their choosing, such as "ULT", "Ultimate", "Ultimate Loss", "Ultimate Cheeseburgers", etc. This would allow them a little bit more flexibility and convenience and more of an incentive to stay within Chainladder. The numeric value (2262...or 9999) can be maintained internally if needed for calculations.

Activity

  1. added this to the v0.11.0 milestone on Sep 11, 2026
  2. added theissue type on Sep 11, 2026
  3. updated Effort Medium and Scope Both on Sep 11, 2026
  4. Abhayindia commented on Sep 13, 2026

    @Abhayindia
    Contributor

    happy to take this. there's already a ULT_VAL option in _config/options.py, so an ULT_LABEL alongside it applied at display time would keep the 2262/9999 sentinels intact for calcs.
    should the alias be global via set_option, or settable per-triangle?

  5. genedan commented on Sep 13, 2026

    @genedan
    MemberAuthor

    should the alias be global via set_option, or settable per-triangle?

    It should be both. There should be a global option, but if a user wants to have a label for a specific triangle, it should be possible, with the triangle-specific setting overriding the global option.

  6. henrydingliu commented on Sep 13, 2026

    @henrydingliu
    Member

    from a use case standpoint, i strongly disagree with the need for this enhancement. i am one of the very few actuaries in the history of the profession who's presented P&C actuarial results to fortune 5 (not 500) execs. a triangle is not remotely close to appearing on a presentation of that level.

    from a product management standpoint, a user who can't deal with a column label will find a million other quirks with our package. that user is a strawman, and not someone for whom we should be writing our package. i cannot stress this enough. chainladder is meant to get to the ultimate. it's not an actuary's pandas. it's an actuary's xgboost. besides, we already have to_frame.

    from an engineering roadmap standpoint, this would need to wait for both #1304 to land and for #1049 to resolve.

  7. Abhayindia commented on Sep 14, 2026

    @Abhayindia
    Contributor

    @genedan #1351 is up and green if you want it, but i'm not going to push it past henry's concerns - how would you like to play it?
    worth noting it defaults to off, so nothing changes for anyone who doesn't set it. happy to close it instead if the team would rather not carry the option.

  8. genedan commented on Sep 15, 2026

    @genedan
    MemberAuthor

    @Abhayindia, we can postpone until we're able to find some consensus.

    @henrydingliu, this proposal isn't going to be doing something the users can't already do, for example:

    raa = cl.load_sample('raa')
    full = cl.Chainladder().fit(raa).full_triangle_
    full.ddims = full.ddims.astype(object)
    full.ddims[-1] = "foo"
    print(full)

    Would just be a more verbose and inconvenient way to achieve the desired result, and this ticket just offers to... make it less verbose and more convenient.

    One thing I was concerned about was whether this would interfere with any of the mathematics of the package. Does setting the ultimate development to something else (such as 1234, "blah" or False) lead to any destructive changes? If so, that's a problem but also a loophole that should be closed in a new issue if discovered. But if not, what's the harm? It's also offed as an option, so if a user still wants 9999 displayed, they can.

    it's not an actuary's pandas

    Historically, we've been advertising that this package is the actuary's pandas. It's on the homepage, in the readme, and has been presented as such to the public.

  9. henrydingliu commented on Sep 15, 2026

    @henrydingliu
    Member

    @henrydingliu, this proposal isn't going to be doing something the users can't already do,

    i'm not against the enhancement. my point is that use case is miniscule.

    also i'm resentful that you forgot about your own #1049.

    Historically, we've been advertising that this package is the actuary's pandas. It's on the homepage, in the readme, and has been presented as such to the public.

    and we are paying for that lack of focus every single day. there is a mountain of new methods we want to get to. yet we are stuck doing devops enhancements and basic bug fixes. we haven't implemented a single new method in years (disposalrate doesn't count; it's mostly repackaging existing code). things like sparse support cost us so much bandwidth, all because we are stuck thinking about triangle as our pandas. for the long term survival of this package, we need to evolve our thinking and start treating triangle as backend acceleration, rather than a whole frontend. xgboost doesn't force you to understand how its trees work. it's pandas in, and pandas out. same as pytorch and TF.

  10. Abhayindia commented on Sep 15, 2026

    @Abhayindia
    Contributor

    @genedan on your destructive-changes question, i tested it: setting ddims[-1] by hand does break things. with 1234, "blah" or False on raa's full_triangle_, latest_diagonal, dev_to_val and link_ratio all raise (UFuncTypeError, or TypeError for the string), while print/to_frame/sum/arithmetic still work. so the loophole you suspected is real and worth its own issue regardless of what happens here.
    #1351 doesn't hit it because it never touches ddims - it only swaps the label at display time, so with ult_label set all eight of those operations still pass and ddims[-1] stays 9999. no view from me on the wider direction question, that's yours to settle.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Fields

    Priority

    Low

    Effort

    Medium

    Scope

    Both

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions