chainladder-python icon indicating copy to clipboard operation
chainladder-python copied to clipboard

[BUG] Incorrect origin periods in non-standard Quarterly Triangles

Open cmds2k opened this issue 1 year ago • 2 comments

Describe the bug The origin periods are incorrect when creating a quarterly triangle object with non-standard Quarter periods (Feb-Apr, May-Jul, Aug-Oct, Nov-Jan). IN my example below, I have non-standard quarter periods and when I try to create a Triangle object from the data, I get incorrect origin periods. The amounts seem to lagging. Compare the below image with the pandas dataframe.

image

To Reproduce Steps to reproduce the behavior. Code should be self-contained and runnable against publicly available data. For example:

import chainladder as cl
import pandas as pd
data= pd.DataFrame([
    ["5/1/2023", 12, '4/30/2024', 100],
    ["8/1/2023", 9, "4/30/2024", 130],
    ["11/1/2023", 6, "4/30/2024", 160],
    ["2/1/2024", 3, "4/30/2024", 140]], 
    columns = ['origin', 'development', 'valuation', 'EarnedPremium'])
triangle = cl.Triangle(
data, origin='origin', origin_format='%Y-%m-%d', development='valuation', columns='EarnedPremium', trailing=True, cumulative=True
)
data_from_tri = triangle.to_frame(origin_as_datetime=True)

Expected behavior: The periods seem to not match with the original data. The expected result should look something like this: image

Desktop (please complete the following information):

  • Numpy Version 1.26.4
  • Pandas Version 2.2.2
  • Chainladder Version 0.8.20

cmds2k avatar Jun 04 '24 23:06 cmds2k

Fantastic bug report! Thanks for finding this. Will fix in next release.

jbogaardt avatar Jun 05 '24 17:06 jbogaardt

If it helps - I notice this occurs frequently when changing the grain to quarterly with the grain method, with trailing=True. Also the valuations are potentially off as shown below. Sometimes this only occurs when the triangle HTML is displayed but the underlying dataframe is correct. Though in this example, both are incorrect:

import chainladder as cl
import pandas as pd
monthly_triangle = cl.load_sample('prism')['Incurred'].sum()
monthly_triangle = monthly_triangle[monthly_triangle.valuation<pd.to_datetime('2009-06-01')]
print( 'Monthly Triangle')
display(monthly_triangle)
print( 'Quarterly Triangle displayed as triangle object')
quarterly_triangle = monthly_triangle.grain('OQDQ',trailing=True)
display(quarterly_triangle)
display(quarterly_triangle.valuation.unique())
print( 'Quarterly Triangle displayed as dataframe')
display(quarterly_triangle.to_frame())

cdietrich215 avatar Jul 19 '24 14:07 cdietrich215

not reopening due to age of issue. here is a screenshot showing the assertions holding with the fix. also added as test_odd_quarter_end under test_triangle

Image

henrydingliu avatar Oct 27 '25 21:10 henrydingliu