Chapter 8 - Expected Claims Technique#

import pandas as pd
import chainladder as cl
import numpy as np

Page 140#

# Exhibit I Sheet 1, Columns 1-2
auto_bi = cl.load_sample("friedland_auto_bi_insurer")
print(auto_bi["Reported Claims"].latest_diagonal)
            2008
2000  10000000.0
2001   8000000.0
2002   9400000.0
2003  15600000.0
2004  16500000.0
2005  18500000.0
2006  16500000.0
2007  14000000.0
2008   8700000.0
# Exhibit I Sheet 1, Column 3
print(auto_bi["Paid Claims"].latest_diagonal)
            2008
2000   9500000.0
2001   7200000.0
2002   7600000.0
2003   7800000.0
2004  11200000.0
2005  10200000.0
2006   6000000.0
2007   3000000.0
2008    750000.0
# Exhibit I Sheet 1, Columns 4-5
reported_pattern = {
    12: 4,
    24: 2.9,
    36: 1.8,
    48: 1.4,
    60: 1.2,
    72: 1.1,
    84: 1.03,
    96: 1.02,
    108: 1.005,
}
paid_pattern = {
    12: 90,
    24: 15,
    36: 5,
    48: 2.5,
    60: 1.75,
    72: 1.35,
    84: 1.25,
    96: 1.15,
    108: 1.05,
}
# Exhibit I Sheet 1, Column 6
Reported_BI = cl.DevelopmentConstant(
    patterns=reported_pattern, style="cdf"
).fit_transform(auto_bi["Reported Claims"])
reported_ultimate = cl.Chainladder().fit(Reported_BI).ultimate_
print(reported_ultimate)
            2261
2000  10050000.0
2001   8160000.0
2002   9682000.0
2003  17160000.0
2004  19800000.0
2005  25900000.0
2006  29700000.0
2007  40600000.0
2008  34800000.0
# Exhibit I Sheet 1, Column 7
Paid_BI = cl.DevelopmentConstant(patterns=paid_pattern, style="cdf").fit_transform(
    auto_bi["Paid Claims"]
)
paid_ultimate = cl.Chainladder().fit(Paid_BI).ultimate_
print(paid_ultimate)
            2261
2000   9975000.0
2001   8280000.0
2002   9500000.0
2003  10530000.0
2004  19600000.0
2005  25500000.0
2006  30000000.0
2007  45000000.0
2008  67500000.0
# Exhibit I Sheet 1, Column 8
inital_selected_ultiamte_claims = (reported_ultimate + paid_ultimate) / 2
print(inital_selected_ultiamte_claims)
            2261
2000  10012500.0
2001   8220000.0
2002   9591000.0
2003  13845000.0
2004  19700000.0
2005  25700000.0
2006  29850000.0
2007  42800000.0
2008  51150000.0
# Exhibit I Sheet 1, Column 9
print(auto_bi["Earned Premium"].latest_diagonal)
            2008
2000  24000000.0
2001  18000000.0
2002  19000000.0
2003  23000000.0
2004  32000000.0
2005  47000000.0
2006  50000000.0
2007  57000000.0
2008  62000000.0
# Exhibit I Sheet 1, Column 10
trend_factors = np.round(
    cl.Trend(trends=[0.145], dates=[("2008-12-31", "2000-01-01")])
    .fit(auto_bi["Earned Premium"])
    .trend_.latest_diagonal,
    3,
)
print(trend_factors)
       2008
2000  2.954
2001  2.580
2002  2.253
2003  1.968
2004  1.719
2005  1.501
2006  1.311
2007  1.145
2008  1.000
# Exhibit I Sheet 1, Column 11
tort_factors = [0.670, 0.670, 0.670, 0.670, 0.750, 1, 1, 1, 1]
tort_factors
[0.67, 0.67, 0.67, 0.67, 0.75, 1, 1, 1, 1]
# Exhibit I Sheet 1, Column 12
trended_adj_ultimate_claims = np.round(
    (
        trend_factors
        * inital_selected_ultiamte_claims
        * np.array(tort_factors).reshape(1, 1, -1, 1)
    ),
    0,
)
print(trended_adj_ultimate_claims)
            2008
2000  19816540.0
2001  14209092.0
2002  14477710.0
2003  18255463.0
2004  25398225.0
2005  38575700.0
2006  39133350.0
2007  49006000.0
2008  51150000.0
# Exhibit I Sheet 1, Column 13
trended_adjusted_claim_ratio = np.round(
    trended_adj_ultimate_claims / auto_bi["Earned Premium"].latest_diagonal, 2
)
print(trended_adjusted_claim_ratio)
      2008
2000  0.83
2001  0.79
2002  0.76
2003  0.79
2004  0.79
2005  0.82
2006  0.78
2007  0.86
2008  0.82
# Exhibit I Sheet 1, Item 14
print(
    "Average 2000 to 2005:",
    np.round(trended_adjusted_claim_ratio.iloc[:, :, 0:6, :].mean(), 3),
)
loss_ratios_00_05 = trended_adjusted_claim_ratio.iloc[:, :, 0:6, :].values.flatten()
print(
    "Average 2000 to 2005 Ex High Ex Low:",
    np.round(
        (loss_ratios_00_05.sum() - loss_ratios_00_05.max() - loss_ratios_00_05.min())
        / (len(loss_ratios_00_05) - 2),
        3,
    ),
)
print(
    "Average 2001 to 2006:",
    np.round(trended_adjusted_claim_ratio.iloc[:, :, 1:7, :].mean(), 3),
)
loss_ratios_01_06 = trended_adjusted_claim_ratio.iloc[:, :, 1:7, :].values.flatten()
print(
    "Average 2000 to 2005 Ex High Ex Low:",
    np.round(
        (loss_ratios_01_06.sum() - loss_ratios_01_06.max() - loss_ratios_01_06.min())
        / (len(loss_ratios_01_06) - 2),
        3,
    ),
)
Average 2000 to 2005: 0.797
Average 2000 to 2005 Ex High Ex Low: 0.798
Average 2001 to 2006: 0.788
Average 2000 to 2005 Ex High Ex Low: 0.787
# Exhibit I, Sheet 1, Item 15
selected_claim_ratio = 0.80
selected_claim_ratio
0.8
# Exhibit I, Sheet 1, Item 16
earned_premium = auto_bi["Earned Premium"].loc[:, :, "2008", :].latest_diagonal
el_reported = cl.ExpectedLoss(apriori=selected_claim_ratio).fit(
    auto_bi["Reported Claims"],
    sample_weight=auto_bi["Earned Premium"].latest_diagonal,
)
el_paid = cl.ExpectedLoss(apriori=selected_claim_ratio).fit(
    auto_bi["Paid Claims"],
    sample_weight=auto_bi["Earned Premium"].latest_diagonal,
)
expected_claims_2008 = el_reported.ultimate_.loc[:, :, "2008", :]
print(expected_claims_2008.sum())
49600000.0
# Exhibit I, Sheet 1, Item 17
print("Total Unpaid Claims:", el_paid.ibnr_.loc[:, :, "2008", :].sum())
print("Total IBNR:", el_reported.ibnr_.loc[:, :, "2008", :].sum())
Total Unpaid Claims: 48850000.0
Total IBNR: 40900000.0
# Exhibit I Sheet 1 — reconciliation
# Exhibit I Sheet 1, Columns 1-2
assert np.allclose(
    (auto_bi["Reported Claims"].latest_diagonal).values,
    np.array(
        [
            [
                [
                    [10000000],
                    [8000000],
                    [9400000],
                    [15600000],
                    [16500000],
                    [18500000],
                    [16500000],
                    [14000000],
                    [8700000],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit I Sheet 1, Column 3
assert np.allclose(
    (auto_bi["Paid Claims"].latest_diagonal).values,
    np.array(
        [
            [
                [
                    [9500000],
                    [7200000],
                    [7600000],
                    [7800000],
                    [11200000],
                    [10200000],
                    [6000000],
                    [3000000],
                    [750000],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit I Sheet 1, Columns 4-5: omitted

# Exhibit I Sheet 1, Column 6
assert np.allclose(
    (reported_ultimate).values,
    np.array(
        [
            [
                [
                    [10050000],
                    [8160000],
                    [9682000],
                    [17160000],
                    [19800000],
                    [25900000],
                    [29700000],
                    [40600000],
                    [34800000],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit I Sheet 1, Column 7
assert np.allclose(
    (paid_ultimate).values,
    np.array(
        [
            [
                [
                    [9975000],
                    [8280000],
                    [9500000],
                    [10530000],
                    [19600000],
                    [25500000],
                    [30000000],
                    [45000000],
                    [67500000],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit I Sheet 1, Column 8
assert np.allclose(
    (inital_selected_ultiamte_claims).values,
    np.array(
        [
            [
                [
                    [10012500],
                    [8220000],
                    [9591000],
                    [13845000],
                    [19700000],
                    [25700000],
                    [29850000],
                    [42800000],
                    [51150000],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit I Sheet 1, Column 9
assert np.allclose(
    (auto_bi["Earned Premium"].latest_diagonal).values,
    np.array(
        [
            [
                [
                    [24000000],
                    [18000000],
                    [19000000],
                    [23000000],
                    [32000000],
                    [47000000],
                    [50000000],
                    [57000000],
                    [62000000],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit I Sheet 1, Column 10
assert np.allclose(
    (trend_factors).values,
    np.array(
        [
            [
                [
                    [2.954],
                    [2.58],
                    [2.253],
                    [1.968],
                    [1.719],
                    [1.501],
                    [1.311],
                    [1.145],
                    [1],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit I Sheet 1, Column 11: omitted

# Exhibit I Sheet 1, Column 12
assert np.allclose(
    (trended_adj_ultimate_claims).values,
    np.array(
        [
            [
                [
                    [19816540],
                    [14209092],
                    [14477710],
                    [18255463],
                    [25398225],
                    [38575700],
                    [39133350],
                    [49006000],
                    [51150000],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit I Sheet 1, Column 13
assert np.allclose(
    (trended_adjusted_claim_ratio).values,
    np.array(
        [[[[0.83], [0.79], [0.76], [0.79], [0.79], [0.82], [0.78], [0.86], [0.82]]]]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit I Sheet 1, Item 14
assert np.isclose(
    np.round(trended_adjusted_claim_ratio.iloc[:, :, 0:6, :].mean(), 3),
    0.797,
    atol=1e-6,
)

# Exhibit I Sheet 1, Item 14
assert np.isclose(
    np.round(
        (loss_ratios_00_05.sum() - loss_ratios_00_05.max() - loss_ratios_00_05.min())
        / (len(loss_ratios_00_05) - 2),
        3,
    ),
    0.798,
    atol=1e-6,
)

# Exhibit I Sheet 1, Item 14
assert np.isclose(
    np.round(trended_adjusted_claim_ratio.iloc[:, :, 1:7, :].mean(), 3),
    0.788,
    atol=1e-6,
)

# Exhibit I Sheet 1, Item 14
assert np.isclose(
    np.round(
        (loss_ratios_01_06.sum() - loss_ratios_01_06.max() - loss_ratios_01_06.min())
        / (len(loss_ratios_01_06) - 2),
        3,
    ),
    0.788,
    atol=0.001,
)

# Exhibit I, Sheet 1, Item 15: omitted

# Exhibit I, Sheet 1, Item 16
assert np.isclose(expected_claims_2008.sum(), 49600000, atol=1e-6)

# Exhibit I, Sheet 1, Item 17
assert np.isclose(
    el_paid.ibnr_.loc[:, :, "2008", :].sum(),
    48850000,
    atol=1e-6,
)

# Exhibit I, Sheet 1, Item 17
assert np.isclose(
    el_reported.ibnr_.loc[:, :, "2008", :].sum(),
    40900000,
    atol=1e-6,
)

Page 141#

# Exhibit I Sheet 2, columns 1-2
friedland_gl_self_insurer = cl.load_sample("friedland_gl_self_insurer")
print(friedland_gl_self_insurer["Reported Claims"].latest_diagonal)
           2008
1998   900000.0
1999  1200000.0
2000  1300000.0
2001  1800000.0
2002  1450000.0
2003  1400000.0
2004  2400000.0
2005  1800000.0
2006  1500000.0
2007  1200000.0
2008   600000.0
# Exhibit I Sheet 2, column 3
print(friedland_gl_self_insurer["Paid Claims"].latest_diagonal)
           2008
1998   890000.0
1999  1170000.0
2000  1265000.0
2001  1600000.0
2002  1200000.0
2003  1050000.0
2004   900000.0
2005   860000.0
2006   525000.0
2007   750000.0
2008   170000.0
# Exhibit I Sheet 2, Columns 4-5
reported_pattern = {
    12: 3.104,
    24: 1.940,
    36: 1.616,
    48: 1.394,
    60: 1.244,
    72: 1.131,
    84: 1.077,
    96: 1.051,
    108: 1.030,
    120: 1.020,
    132: 1.015,
}
paid_pattern = {
    12: 20.373,
    24: 5.093,
    36: 3.183,
    48: 2.274,
    60: 1.749,
    72: 1.489,
    84: 1.306,
    96: 1.187,
    108: 1.109,
    120: 1.067,
    132: 1.046,
}
# Exhibit I Sheet 2, Columns 6
reported = cl.DevelopmentConstant(patterns=reported_pattern, style="cdf").fit_transform(
    friedland_gl_self_insurer["Reported Claims"]
)
reported_ultimate = cl.Chainladder().fit(reported).ultimate_
print(reported_ultimate)
           2261
1998   913500.0
1999  1224000.0
2000  1339000.0
2001  1891800.0
2002  1561650.0
2003  1583400.0
2004  2985600.0
2005  2509200.0
2006  2424000.0
2007  2328000.0
2008  1862400.0
# Exhibit I Sheet 2, Columns 7
paid = cl.DevelopmentConstant(patterns=paid_pattern, style="cdf").fit_transform(
    friedland_gl_self_insurer["Paid Claims"]
)
paid_ultimate = cl.Chainladder().fit(paid).ultimate_
print(paid_ultimate)
           2261
1998   930940.0
1999  1248390.0
2000  1402885.0
2001  1899200.0
2002  1567200.0
2003  1563450.0
2004  1574100.0
2005  1955640.0
2006  1671075.0
2007  3819750.0
2008  3463410.0
# Exhibit I Sheet 2, Columns 8
selected_ultimate = (reported_ultimate + paid_ultimate) / 2
print(selected_ultimate)
           2261
1998   922220.0
1999  1236195.0
2000  1370942.5
2001  1895500.0
2002  1564425.0
2003  1573425.0
2004  2279850.0
2005  2232420.0
2006  2047537.5
2007  3073875.0
2008  2662905.0
# Exhibit I Sheet 2, Columns 9
population = (
    friedland_gl_self_insurer["Population"].latest_diagonal
)
print(population)
          2008
1998  709000.0
1999  724000.0
2000  736000.0
2001  740000.0
2002  750000.0
2003  760000.0
2004  770000.0
2005  775000.0
2006  780000.0
2007  785000.0
2008  790000.0
# Exhibit I Sheet 2, Column 10
trend_factors = np.round(
    cl.Trend(trends=[0.075], dates=[("2008-12-31", "1998-01-01")])
    .fit(friedland_gl_self_insurer["Population"])
    .trend_.latest_diagonal,
    3,
)
print(trend_factors)
       2008
1998  2.061
1999  1.917
2000  1.783
2001  1.659
2002  1.543
2003  1.436
2004  1.335
2005  1.242
2006  1.156
2007  1.075
2008  1.000
# Exhibit I Sheet 2, Column 11
trended_adj_ultimate_claims = np.round(selected_ultimate * trend_factors, 0)
print(trended_adj_ultimate_claims)
           2261
1998  1900695.0
1999  2369786.0
2000  2444390.0
2001  3144634.0
2002  2413908.0
2003  2259438.0
2004  3043600.0
2005  2772666.0
2006  2366953.0
2007  3304416.0
2008  2662905.0
# Exhibit I Sheet 2, Column 12
trended_pure_premium = np.round(trended_adj_ultimate_claims / population, 2)
print(trended_pure_premium)
      2261
1998  2.68
1999  3.27
2000  3.32
2001  4.25
2002  3.22
2003  2.97
2004  3.95
2005  3.58
2006  3.03
2007  4.21
2008  3.37
# Exhibit I Sheet 2, Item 13
print(
    "Average 2000 to 2005:", np.round(trended_pure_premium.iloc[:, :, 2:8, :].mean(), 2)
)
loss_ratios_00_05 = trended_pure_premium.iloc[:, :, 2:8, :].values.flatten()
print(
    "Average 2000 to 2005 Ex High Ex Low:",
    np.round(
        (loss_ratios_00_05.sum() - loss_ratios_00_05.max() - loss_ratios_00_05.min())
        / (len(loss_ratios_00_05) - 2),
        2,
    ),
)
print(
    "Average 2001 to 2006:", np.round(trended_pure_premium.iloc[:, :, 3:9, :].mean(), 2)
)
loss_ratios_01_06 = trended_pure_premium.iloc[:, :, 3:9, :].values.flatten()
print(
    "Average 2001 to 2006 Ex High Ex Low:",
    np.round(
        (loss_ratios_01_06.sum() - loss_ratios_01_06.max() - loss_ratios_01_06.min())
        / (len(loss_ratios_01_06) - 2),
        2,
    ),
)
Average 2000 to 2005: 3.55
Average 2000 to 2005 Ex High Ex Low: 3.52
Average 2001 to 2006: 3.5
Average 2001 to 2006 Ex High Ex Low: 3.44
# Exhibit I Sheet 2, Item 14
selected_pure_premium = 3.50
selected_pure_premium
3.5
# Exhibit I Sheet 2, Item 15
el_reported = cl.ExpectedLoss(apriori=selected_pure_premium).fit(
    reported,
    sample_weight=population,
)
el_paid = cl.ExpectedLoss(apriori=selected_pure_premium).fit(
    paid,
    sample_weight=population,
)
expected_claims_2008 = el_reported.ultimate_.loc[:, :, "2008", :]
print(expected_claims_2008.sum())
2765000.0
# Exhibit I, Item 16
print("Total Unpaid Claims:", el_paid.ibnr_.loc[:, :, "2008", :].sum())
print("Total IBNR:", el_reported.ibnr_.loc[:, :, "2008", :].sum())
Total Unpaid Claims: 2595000.0
Total IBNR: 2165000.0
# Exhibit I Sheet 2 — reconciliation
# Exhibit I Sheet 2, columns 1-2
assert np.allclose(
    friedland_gl_self_insurer.values,
    np.array(
        [
            [
                [
                    [900000],
                    [1200000],
                    [1300000],
                    [1800000],
                    [1450000],
                    [1400000],
                    [2400000],
                    [1800000],
                    [1500000],
                    [1200000],
                    [600000],
                ],
                [
                    [890000],
                    [1170000],
                    [1265000],
                    [1600000],
                    [1200000],
                    [1050000],
                    [900000],
                    [860000],
                    [525000],
                    [750000],
                    [170000],
                ],
                [
                    [709000],
                    [724000],
                    [736000],
                    [740000],
                    [750000],
                    [760000],
                    [770000],
                    [775000],
                    [780000],
                    [785000],
                    [790000],
                ],
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit I Sheet 2, columns 1-2
assert np.allclose(
    (friedland_gl_self_insurer["Reported Claims"].latest_diagonal).values,
    np.array(
        [
            [
                [
                    [900000],
                    [1200000],
                    [1300000],
                    [1800000],
                    [1450000],
                    [1400000],
                    [2400000],
                    [1800000],
                    [1500000],
                    [1200000],
                    [600000],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit I Sheet 2, column 3
assert np.allclose(
    (friedland_gl_self_insurer["Paid Claims"].latest_diagonal).values,
    np.array(
        [
            [
                [
                    [890000],
                    [1170000],
                    [1265000],
                    [1600000],
                    [1200000],
                    [1050000],
                    [900000],
                    [860000],
                    [525000],
                    [750000],
                    [170000],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit I Sheet 2, Columns 4-5: omitted

# Exhibit I Sheet 2, Columns 6
assert np.allclose(
    reported_ultimate.values,
    np.array(
        [
            [
                [
                    [913500],
                    [1224000],
                    [1339000],
                    [1891800],
                    [1561650],
                    [1583400],
                    [2985600],
                    [2509200],
                    [2424000],
                    [2328000],
                    [1862400],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit I Sheet 2, Columns 7
assert np.allclose(
    paid_ultimate.values,
    np.array(
        [
            [
                [
                    [930940],
                    [1248390],
                    [1402885],
                    [1899200],
                    [1567200],
                    [1563450],
                    [1574100.],
                    [1955640.],
                    [1671075.],
                    [3819750.],
                    [3463410.],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit I Sheet 2, Columns 8
assert np.allclose(
    selected_ultimate.values,
    np.array(
        [
            [
                [
                    [922220],
                    [1236195],
                    [1370943],
                    [1895500],
                    [1564425],
                    [1573425],
                    [2279850],
                    [2232420],
                    [2047538],
                    [3073875],
                    [2662905],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)


# Exhibit I Sheet 2, Columns 9
assert np.allclose(
    population.values,
    np.array(
        [
            [
                [
                    [709000],
                    [724000],
                    [736000],
                    [740000],
                    [750000],
                    [760000],
                    [770000],
                    [775000],
                    [780000],
                    [785000],
                    [790000],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit I Sheet 2, Column 10
assert np.allclose(
    (trend_factors).values,
    np.array(
        [
            [
                [
                    [2.061],
                    [1.917],
                    [1.783],
                    [1.659],
                    [1.543],
                    [1.436],
                    [1.335],
                    [1.242],
                    [1.156],
                    [1.075],
                    [1.000],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit I Sheet 2, Column 11
assert np.allclose(
    (trended_adj_ultimate_claims).values,
    np.array(
        [
            [
                [
                    [1900695],
                    [2369786],
                    [2444390],
                    [3144635],
                    [2413908],
                    [2259438],
                    [3043600],
                    [2772666],
                    [2366953],
                    [3304416],
                    [2662905],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit I Sheet 2, Column 12
assert np.allclose(
    (trended_pure_premium).values,
    np.array(
        [
            [
                [
                    [2.68],
                    [3.27],
                    [3.32],
                    [4.25],
                    [3.22],
                    [2.97],
                    [3.95],
                    [3.58],
                    [3.03],
                    [4.21],
                    [3.37],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit I Sheet 2, Item 13
assert np.isclose(
    np.round(trended_pure_premium.iloc[:, :, 2:8, :].mean(), 2), 3.55, atol=1e-6
)

# Exhibit I Sheet 2, Item 13
assert np.isclose(
    np.round(
        (loss_ratios_00_05.sum() - loss_ratios_00_05.max() - loss_ratios_00_05.min())
        / (len(loss_ratios_00_05) - 2),
        2,
    ),
    3.52,
    atol=1e-6,
)

# Exhibit I Sheet 2, Item 13
assert np.isclose(
    np.round(trended_pure_premium.iloc[:, :, 3:9, :].mean(), 2), 3.50, atol=1e-6
)

# Exhibit I Sheet 2, Item 13
assert np.isclose(
    np.round(
        (loss_ratios_01_06.sum() - loss_ratios_01_06.max() - loss_ratios_01_06.min())
        / (len(loss_ratios_01_06) - 2),
        2,
    ),
    3.45,
    atol=0.011,
)

# Exhibit I Sheet 2, Item 14: omitted

# Exhibit I Sheet 2, Item 15
assert np.isclose(expected_claims_2008.sum(), 2765000, atol=1e-6)

# Exhibit I, Item 16
assert np.isclose(
    el_paid.ibnr_.loc[:, :, "2008", :].sum(),
    2595000,
    atol=1e-6,
)

# Exhibit I, Item 16
assert np.isclose(
    el_reported.ibnr_.loc[:, :, "2008", :].sum(),
    2165000,
    atol=1e-6,
)

Page 142#

# Exhibit II Sheet 1, columns 1-2
friedland_us_industry_auto = cl.load_sample("friedland_us_industry_auto")
print(friedland_us_industry_auto["Reported Claims"].latest_diagonal)
            2007
1998  47742304.0
1999  51185767.0
2000  54837929.0
2001  56299562.0
2002  58592712.0
2003  57565344.0
2004  56976657.0
2005  56786410.0
2006  54641339.0
2007  48853563.0
# Exhibit II Sheet 1, columns 3
print(friedland_us_industry_auto["Paid Claims"].latest_diagonal)
            2007
1998  47644187.0
1999  51000534.0
2000  54533225.0
2001  55878421.0
2002  57807215.0
2003  55930654.0
2004  53774672.0
2005  50644994.0
2006  43606497.0
2007  27229969.0
# Exhibit II Sheet 1, columns 4-5
reported_pattern = {
    12: 1.292,
    24: 1.110,
    36: 1.051,
    48: 1.023,
    60: 1.011,
    72: 1.006,
    84: 1.003,
    96: 1.001,
    108: 1.000,
    120: 1.000,
}
paid_pattern = {
    12: 2.390,
    24: 1.404,
    36: 1.184,
    48: 1.085,
    60: 1.040,
    72: 1.020,
    84: 1.011,
    96: 1.006,
    108: 1.004,
    120: 1.002,
}
# Exhibit II Sheet 1, column 6
reported_ultimate = (
    cl.Chainladder()
    .fit(
        cl.DevelopmentConstant(patterns=reported_pattern, style="cdf").fit_transform(
            friedland_us_industry_auto["Reported Claims"]
        )
    )
    .ultimate_
)
print(reported_ultimate)
              2261
1998  4.774230e+07
1999  5.118577e+07
2000  5.489277e+07
2001  5.646846e+07
2002  5.894427e+07
2003  5.819856e+07
2004  5.828712e+07
2005  5.968252e+07
2006  6.065189e+07
2007  6.311880e+07
# Exhibit II Sheet 1, column 7
paid_ultimate = (
    cl.Chainladder()
    .fit(
        cl.DevelopmentConstant(patterns=paid_pattern, style="cdf").fit_transform(
            friedland_us_industry_auto["Paid Claims"]
        )
    )
    .ultimate_
)
print(paid_ultimate)
              2261
1998  4.773948e+07
1999  5.120454e+07
2000  5.486042e+07
2001  5.649308e+07
2002  5.896336e+07
2003  5.816788e+07
2004  5.834552e+07
2005  5.996367e+07
2006  6.122352e+07
2007  6.507963e+07
# Exhibit II Sheet 1, column 8
selected_ultimate = np.round((reported_ultimate + paid_ultimate) / 2, 0)
print(selected_ultimate)
            2261
1998  47740890.0
1999  51195152.0
2000  54876596.0
2001  56480772.0
2002  58953814.0
2003  58183221.0
2004  58316320.0
2005  59823095.0
2006  60937704.0
2007  64099215.0
# Exhibit II Sheet 1, column 9
earned_premium = friedland_us_industry_auto["Earned Premium"].latest_diagonal
print(earned_premium)
            2007
1998  68574209.0
1999  68544981.0
2000  68907977.0
2001  72544955.0
2002  79228887.0
2003  86643542.0
2004  91763523.0
2005  94115312.0
2006  95272279.0
2007  95176240.0
# Exhibit II Sheet 1, column 10
estimated_claim_ratios = np.round(selected_ultimate / earned_premium, 3)
print(estimated_claim_ratios)
       2261
1998  0.696
1999  0.747
2000  0.796
2001  0.779
2002  0.744
2003  0.672
2004  0.636
2005  0.636
2006  0.640
2007  0.673
# Exhibit II Sheet 1, column 11
selected_claim_ratio = [0.75, 0.75, 0.75, 0.75, 0.75, 0.65, 0.65, 0.65, 0.65, 0.65]
selected_claim_ratio
[0.75, 0.75, 0.75, 0.75, 0.75, 0.65, 0.65, 0.65, 0.65, 0.65]
# Exhibit II Sheet 1, column 12
sample_weight = earned_premium * np.array(selected_claim_ratio).reshape(1, 1, -1, 1)
el_reported = cl.ExpectedLoss(apriori=1).fit(
    friedland_us_industry_auto["Reported Claims"],
    sample_weight=sample_weight,
)
el_paid = cl.ExpectedLoss(apriori=1).fit(
    friedland_us_industry_auto["Paid Claims"],
    sample_weight=sample_weight,
)
expected_claims = np.round(el_reported.ultimate_, 0)
print(expected_claims)
            2261
1998  51430657.0
1999  51408736.0
2000  51680983.0
2001  54408716.0
2002  59421665.0
2003  56318302.0
2004  59646290.0
2005  61174953.0
2006  61926981.0
2007  61864556.0

# Exhibit II Sheet 1 — reconciliation
# Exhibit II Sheet 1, columns 1-2
assert np.allclose(
    (friedland_us_industry_auto["Reported Claims"].latest_diagonal).values,
    np.array(
        [
            [
                [
                    [47742304],
                    [51185767],
                    [54837929],
                    [56299562],
                    [58592712],
                    [57565344],
                    [56976657],
                    [56786410],
                    [54641339],
                    [48853563],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit II Sheet 1, columns 3
assert np.allclose(
    (friedland_us_industry_auto["Paid Claims"].latest_diagonal).values,
    np.array(
        [
            [
                [
                    [47644187],
                    [51000534],
                    [54533225],
                    [55878421],
                    [57807215],
                    [55930654],
                    [53774672],
                    [50644994],
                    [43606497],
                    [27229969],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit II Sheet 1, columns 4-5: omitted

# Exhibit II Sheet 1, column 6
assert np.allclose(
    (reported_ultimate).values,
    np.array(
        [
            [
                [
                    [47742304],
                    [51185767],
                    [54892767],
                    [56468461],
                    [58944268],
                    [58198563],
                    [58287120],
                    [59682517],
                    [60651886],
                    [63118803],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit II Sheet 1, column 7
assert np.allclose(
    (paid_ultimate).values,
    np.array(
        [
            [
                [
                    [47739475],
                    [51204536],
                    [54860424],
                    [56493084],
                    [58963359],
                    [58167880],
                    [58345519],
                    [59963673],
                    [61223522],
                    [65079626],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit II Sheet 1, column 8
assert np.allclose(
    selected_ultimate.values,
    np.array(
        [
            [
                [
                    [47740890],
                    [51195152],
                    [54876596],
                    [56480772],
                    [58953814],
                    [58183221],
                    [58316320],
                    [59823095],
                    [60937704],
                    [64099215],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit II Sheet 1, column 9
assert np.allclose(
    (earned_premium).values,
    np.array(
        [
            [
                [
                    [68574209],
                    [68544981],
                    [68907977],
                    [72544955],
                    [79228887],
                    [86643542],
                    [91763523],
                    [94115312],
                    [95272279],
                    [95176240],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit II Sheet 1, column 10
assert np.allclose(
    estimated_claim_ratios.values,
    np.array(
        [
            [
                [
                    [0.696],
                    [0.747],
                    [0.796],
                    [0.779],
                    [0.744],
                    [0.672],
                    [0.636],
                    [0.636],
                    [0.640],
                    [0.673],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit II Sheet 1, column 11: omitted

# Exhibit II Sheet 1, column 12
assert np.allclose(
    (expected_claims).values,
    np.array(
        [
            [
                [
                    [51430657],
                    [51408736],
                    [51680983],
                    [54408716],
                    [59421665],
                    [56318302],
                    [59646290],
                    [61174953],
                    [61926981],
                    [61864556],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

Page 143#

# Exhibit II Sheet 2, columns 1-2
print(friedland_us_industry_auto["Reported Claims"].latest_diagonal)
print("Total:", friedland_us_industry_auto["Reported Claims"].latest_diagonal.sum())
            2007
1998  47742304.0
1999  51185767.0
2000  54837929.0
2001  56299562.0
2002  58592712.0
2003  57565344.0
2004  56976657.0
2005  56786410.0
2006  54641339.0
2007  48853563.0
Total: 543481587.0
# Exhibit II Sheet 2, column 3
print(friedland_us_industry_auto["Paid Claims"].latest_diagonal)
print("Total:", friedland_us_industry_auto["Paid Claims"].latest_diagonal.sum())
            2007
1998  47644187.0
1999  51000534.0
2000  54533225.0
2001  55878421.0
2002  57807215.0
2003  55930654.0
2004  53774672.0
2005  50644994.0
2006  43606497.0
2007  27229969.0
Total: 498050368.0
# Exhibit II Sheet 2, column 4
print(np.round(expected_claims, 0))
print("Total:", np.round(expected_claims.sum(), 0))
            2261
1998  51430657.0
1999  51408736.0
2000  51680983.0
2001  54408716.0
2002  59421665.0
2003  56318302.0
2004  59646290.0
2005  61174953.0
2006  61926981.0
2007  61864556.0
Total: 569281839.0
# Exhibit II Sheet 2, column 5
case_outstanding = (
    friedland_us_industry_auto["Reported Claims"].latest_diagonal
    - friedland_us_industry_auto["Paid Claims"].latest_diagonal
)
print(case_outstanding)
print("Total:", case_outstanding.sum())
            2007
1998     98117.0
1999    185233.0
2000    304704.0
2001    421141.0
2002    785497.0
2003   1634690.0
2004   3201985.0
2005   6141416.0
2006  11034842.0
2007  21623594.0
Total: 45431219.0
# Exhibit II Sheet 2, column 6
ibnr = np.round(el_reported.ibnr_, 0)
print(ibnr)
print("Total:", ibnr.sum())
            2261
1998   3688353.0
1999    222969.0
2000  -3156946.0
2001  -1890846.0
2002    828953.0
2003  -1247042.0
2004   2669633.0
2005   4388543.0
2006   7285642.0
2007  13010993.0
Total: 25800252.0
# Exhibit II Sheet 2, column 7
total_unpaid = np.round(el_paid.ibnr_, 0)
print(total_unpaid)
print("Total:", total_unpaid.sum())
            2261
1998   3786470.0
1999    408202.0
2000  -2852242.0
2001  -1469705.0
2002   1614450.0
2003    387648.0
2004   5871618.0
2005  10529959.0
2006  18320484.0
2007  34634587.0
Total: 71231471.0
# Exhibit II Sheet 2 — reconciliation
# Exhibit II Sheet 2, columns 1-2
assert np.allclose(
    (friedland_us_industry_auto["Reported Claims"].latest_diagonal).values,
    np.array(
        [
            [
                [
                    [47742304],
                    [51185767],
                    [54837929],
                    [56299562],
                    [58592712],
                    [57565344],
                    [56976657],
                    [56786410],
                    [54641339],
                    [48853563],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit II Sheet 2, columns 1-2
assert np.isclose(
    friedland_us_industry_auto["Reported Claims"].latest_diagonal.sum(),
    543481587,
    atol=1e-6,
)

# Exhibit II Sheet 2, column 3
assert np.allclose(
    (friedland_us_industry_auto["Paid Claims"].latest_diagonal).values,
    np.array(
        [
            [
                [
                    [47644187],
                    [51000534],
                    [54533225],
                    [55878421],
                    [57807215],
                    [55930654],
                    [53774672],
                    [50644994],
                    [43606497],
                    [27229969],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit II Sheet 2, column 3
assert np.isclose(
    friedland_us_industry_auto["Paid Claims"].latest_diagonal.sum(),
    498050368,
    atol=1e-6,
)

# Exhibit II Sheet 2, column 4
assert np.allclose(
    (np.round(expected_claims, 0)).values,
    np.array(
        [
            [
                [
                    [51430657],
                    [51408736],
                    [51680983],
                    [54408716],
                    [59421665],
                    [56318302],
                    [59646290],
                    [61174953],
                    [61926981],
                    [61864556],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit II Sheet 2, column 4
assert np.isclose(np.round(expected_claims.sum(), 0), 569281839, atol=1e-6)

# Exhibit II Sheet 2, column 5
assert np.allclose(
    case_outstanding.values,
    np.array(
        [
            [
                [
                    [98117],
                    [185233],
                    [304704],
                    [421141],
                    [785497],
                    [1634690],
                    [3201985],
                    [6141416],
                    [11034842],
                    [21623594],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit II Sheet 2, column 5
assert np.isclose(case_outstanding.sum(), 45431219, atol=1e-6)

# Exhibit II Sheet 2, column 6
assert np.allclose(
    (ibnr).values,
    np.array(
        [
            [
                [
                    [3688353],
                    [222969],
                    [-3156946],
                    [-1890846],
                    [828953],
                    [-1247042],
                    [2669633],
                    [4388543],
                    [7285642],
                    [13010993],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit II Sheet 2, column 6
assert np.isclose(ibnr.sum(), 25800252, atol=1e-6)

# Exhibit II Sheet 2, column 7
assert np.allclose(
    (total_unpaid).values,
    np.array(
        [
            [
                [
                    [3786470],
                    [408202],
                    [-2852242],
                    [-1469705],
                    [1614450],
                    [387648],
                    [5871618],
                    [10529959],
                    [18320484],
                    [34634587],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit II Sheet 2, column 7
assert np.isclose(total_unpaid.sum(), 71231471, atol=1e-6)

Page 144#

# Exhibit III Sheet 1, columns 1-2
friedland_xyz_auto_bi = cl.load_sample("friedland_xyz_auto_bi")
print(friedland_xyz_auto_bi["Reported Claims"].latest_diagonal)
         2008
1998  15822.0
1999  25107.0
2000  37246.0
2001  38798.0
2002  48169.0
2003  44373.0
2004  70288.0
2005  70655.0
2006  48804.0
2007  31732.0
2008  18632.0
# Exhibit III Sheet 1, column 3
print(friedland_xyz_auto_bi["Paid Claims"].latest_diagonal)
         2008
1998  15822.0
1999  24817.0
2000  36782.0
2001  38519.0
2002  44437.0
2003  39320.0
2004  52811.0
2005  40026.0
2006  22819.0
2007  11865.0
2008   3409.0
# Exhibit III Sheet 1, columns 4-5
# Developed in Chapter 7, Exhibit II, Sheets 1 and 2
reported_pattern = {
    12: 2.551,
    24: 1.512,
    36: 1.196,
    48: 1.085,
    60: 1.064,
    72: 1.013,
    84: 1.003,
    96: 0.992,
    108: 0.992,
    120: 0.999,
    132: 1.000,
}
paid_pattern = {
    12: 21.999,
    24: 6.569,
    36: 3.160,
    48: 2.007,
    60: 1.525,
    72: 1.268,
    84: 1.116,
    96: 1.054,
    108: 1.031,
    120: 1.014,
    132: 1.010,
}
# Exhibit III Sheet 1, column 6
reported_ultimate = np.round((
    cl.Chainladder()
    .fit(
        cl.DevelopmentConstant(patterns=reported_pattern, style="cdf").fit_transform(
            friedland_xyz_auto_bi["Reported Claims"]
        )
    )
    .ultimate_
),0)
print(reported_ultimate)
         2261
1998  15822.0
1999  25082.0
2000  36948.0
2001  38488.0
2002  48314.0
2003  44950.0
2004  74786.0
2005  76661.0
2006  58370.0
2007  47979.0
2008  47530.0
# Exhibit III Sheet 1, column 7
paid_ultimate = np.round((
    cl.Chainladder()
    .fit(
        cl.DevelopmentConstant(patterns=paid_pattern, style="cdf").fit_transform(
            friedland_xyz_auto_bi["Paid Claims"]
        )
    )
    .ultimate_
),0)
print(paid_ultimate)
         2261
1998  15980.0
1999  25164.0
2000  37922.0
2001  40599.0
2002  49592.0
2003  49858.0
2004  80537.0
2005  80332.0
2006  72108.0
2007  77941.0
2008  74995.0
# Exhibit III Sheet 1, column 8
selected_ultimate = (reported_ultimate + paid_ultimate) / 2
print(selected_ultimate)
         2261
1998  15901.0
1999  25123.0
2000  37435.0
2001  39543.5
2002  48953.0
2003  47404.0
2004  77661.5
2005  78496.5
2006  65239.0
2007  62960.0
2008  61262.5
# Exhibit III Sheet 1, column 9
earned_premium = friedland_xyz_auto_bi["Earned Premium"].latest_diagonal
print(earned_premium)
          2008
1998   20000.0
1999   31500.0
2000   45000.0
2001   50000.0
2002   61183.0
2003   69175.0
2004   99322.0
2005  138151.0
2006  107578.0
2007   62438.0
2008   47797.0
# Exhibit III Sheet 1, column 10
estimated_claim_ratios = np.round(selected_ultimate / earned_premium, 3)
print(estimated_claim_ratios)
       2261
1998  0.795
1999  0.798
2000  0.832
2001  0.791
2002  0.800
2003  0.685
2004  0.782
2005  0.568
2006  0.606
2007  1.008
2008  1.282
np.round((selected_ultimate / earned_premium).iloc[:,:,0:6,:].mean(), 3)
np.float64(0.783)
# Exhibit III Sheet 1, column 11
print(np.round((selected_ultimate / earned_premium).iloc[:,:,0:6,:].mean(), 3))

selected_claim_ratio = [
    0.783,
    0.783,
    0.783,
    0.783,
    0.783,
    0.783,
    0.871, # calculation shown in Exhibit III Sheet 2
    0.783, # calculation shown in Exhibit III Sheet 2
    0.658, # calculation shown in Exhibit III Sheet 2
    0.638, # calculation shown in Exhibit III Sheet 2
    0.825, # calculation shown in Exhibit III Sheet 2
]
print(selected_claim_ratio)
0.783
[0.783, 0.783, 0.783, 0.783, 0.783, 0.783, 0.871, 0.783, 0.658, 0.638, 0.825]
# Exhibit III Sheet 1, column 12
sample_weight = earned_premium * np.array(selected_claim_ratio).reshape(1, 1, -1, 1)
el_reported = cl.ExpectedLoss(apriori=1).fit(
    friedland_xyz_auto_bi["Reported Claims"],
    sample_weight=sample_weight,
)
el_paid = cl.ExpectedLoss(apriori=1).fit(
    friedland_xyz_auto_bi["Paid Claims"],
    sample_weight=sample_weight,
)
expected_claims = np.round(el_reported.ultimate_, 0)
print(expected_claims)
          2261
1998   15660.0
1999   24664.0
2000   35235.0
2001   39150.0
2002   47906.0
2003   54164.0
2004   86509.0
2005  108172.0
2006   70786.0
2007   39835.0
2008   39433.0
# Exhibit III Sheet 1 — reconciliation
# Exhibit III Sheet 1, columns 1-2
assert np.allclose(
    (friedland_xyz_auto_bi["Reported Claims"].latest_diagonal).values,
    np.array(
        [
            [
                [
                    [15822],
                    [25107],
                    [37246],
                    [38798],
                    [48169],
                    [44373],
                    [70288],
                    [70655],
                    [48804],
                    [31732],
                    [18632],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit III Sheet 1, column 3
assert np.allclose(
    (friedland_xyz_auto_bi["Paid Claims"].latest_diagonal).values,
    np.array(
        [
            [
                [
                    [15822],
                    [24817],
                    [36782],
                    [38519],
                    [44437],
                    [39320],
                    [52811],
                    [40026],
                    [22819],
                    [11865],
                    [3409],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit III Sheet 1, columns 4-5: omitted

# Exhibit III Sheet 1, column 6
assert np.allclose(
    (reported_ultimate).values,
    np.array(
        [
            [
                [
                    [15822],
                    [25082],
                    [36948],
                    [38487],
                    [48313],
                    [44950],
                    [74787],
                    [76661],
                    [58370],
                    [47979],
                    [47530],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit III Sheet 1, column 7
assert np.allclose(
    (paid_ultimate).values,
    np.array(
        [
            [
                [
                    [15980],
                    [25164],
                    [37922],
                    [40600],
                    [49592],
                    [49858],
                    [80537],
                    [80333],
                    [72108],
                    [77941],
                    [74995],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit III Sheet 1, column 8
assert np.allclose(
    (selected_ultimate).values,
    np.array(
        [
            [
                [
                    [15901],
                    [25123],
                    [37435],
                    [39543],
                    [48953],
                    [47404],
                    [77662],
                    [78497],
                    [65239],
                    [62960],
                    [61262],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit III Sheet 1, column 9
assert np.allclose(
    (earned_premium).values,
    np.array(
        [
            [
                [
                    [20000],
                    [31500],
                    [45000],
                    [50000],
                    [61183],
                    [69175],
                    [99322],
                    [138151],
                    [107578],
                    [62438],
                    [47797],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit III Sheet 1, column 10
assert np.allclose(
    (estimated_claim_ratios).values,
    np.array(
        [
            [
                [
                    [0.795],
                    [0.798],
                    [0.832],
                    [0.791],
                    [0.800],
                    [0.685],
                    [0.782],
                    [0.568],
                    [0.606],
                    [1.008],
                    [1.282],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit III Sheet 1, column 11
assert np.isclose(
    np.round((selected_ultimate / earned_premium).iloc[:,:,0:6,:].mean(), 3),
    0.783,
    atol=1e-6,
)

# Exhibit III Sheet 1, column 11: omitted

# Exhibit III Sheet 1, column 12
assert np.allclose(
    (expected_claims).values,
    np.array(
        [
            [
                [
                    [15660],
                    [24665],
                    [35235],
                    [39150],
                    [47906],
                    [54164],
                    [86509],
                    [108172],
                    [70786],
                    [39835],
                    [39433],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

Page 145#

# Exhibit III Sheet 2, columns 1-2
selected_view = np.round(selected_ultimate.iloc[:,:,4:,:],0)
print(selected_view)
         2261
2002  48953.0
2003  47404.0
2004  77662.0
2005  78496.0
2006  65239.0
2007  62960.0
2008  61262.0
# Exhibit III Sheet 2, columns 3-7
def relative_level_triangle(base, years=range(2004, 2009)):
    pieces = []
    for year in years:
        rel = base / base.loc[:, :, str(year), :]
        rel.columns = [str(year)]
        pieces.append(rel)
    return cl.concat(pieces, axis=1)


base_trend_2008 = (
    cl.Trend(trends=[0.03425], dates=[("2008-12-31", "2002-01-01")])
    .fit(selected_view)
    .trend_
)

severity_trend_adjustment = relative_level_triangle(base_trend_2008)
print(np.round(severity_trend_adjustment.values.squeeze().T, 3))
[[1.07  1.106 1.144 1.183 1.224]
 [1.034 1.07  1.106 1.144 1.183]
 [1.    1.034 1.07  1.106 1.144]
 [0.967 1.    1.034 1.07  1.106]
 [0.935 0.967 1.    1.034 1.07 ]
 [0.904 0.935 0.967 1.    1.034]
 [0.874 0.904 0.935 0.967 1.   ]]
# Exhibit III Sheet 2, columns 8-12
base_trend_2008 = (
    cl.Trend(
        trends=[-0.25, 0.670 / 0.75 - 1],
        dates=[("2007-12-31", "2006-12-31"), ("2006-12-31", "2005-12-31")],
    )
    .fit(selected_view)
    .trend_
)
tort_reform_adjustment = relative_level_triangle(base_trend_2008)
print(np.round(tort_reform_adjustment.values.squeeze().T, 3))
[[1.    1.    0.893 0.67  0.67 ]
 [1.    1.    0.893 0.67  0.67 ]
 [1.    1.    0.893 0.67  0.67 ]
 [1.    1.    0.893 0.67  0.67 ]
 [1.119 1.119 1.    0.75  0.75 ]
 [1.493 1.493 1.333 1.    1.   ]
 [1.493 1.493 1.333 1.    1.   ]]
# Exhibit III Sheet 2, column 13
earned_premium_view = earned_premium.iloc[:, :, 4:, :]
print(earned_premium_view)
          2008
2002   61183.0
2003   69175.0
2004   99322.0
2005  138151.0
2006  107578.0
2007   62438.0
2008   47797.0
# Exhibit III Sheet 2, columns 14-18
rate_changes = [0, 0.05, 0.075, 0.15, 0.1, -0.2, -0.2]
olf = cl.parallelogram_olf(
    rate_changes,
    pd.to_datetime([f"{y}-01-01" for y in range(2002, 2009)]),
    vertical_line=True,
)["OLF"].values

base_trend_2008 = selected_view * 0 + olf.reshape(selected_view.shape)
rate_level_adjustment = relative_level_triangle(base_trend_2008)
print(np.round(rate_level_adjustment.values.squeeze().T, 3))
[[1.129 1.298 1.428 1.142 0.914]
 [1.075 1.236 1.36  1.088 0.87 ]
 [1.    1.15  1.265 1.012 0.81 ]
 [0.87  1.    1.1   0.88  0.704]
 [0.791 0.909 1.    0.8   0.64 ]
 [0.988 1.136 1.25  1.    0.8  ]
 [1.235 1.42  1.562 1.25  1.   ]]
# Exhibit III Sheet 2, columns 19-23
adjusted_claim_ratios = (
    selected_view * severity_trend_adjustment * tort_reform_adjustment
) / (earned_premium_view * rate_level_adjustment)
print(np.round(adjusted_claim_ratios.values.squeeze().T, 3))
[[0.758 0.682 0.573 0.555 0.718]
 [0.659 0.593 0.498 0.483 0.624]
 [0.782 0.703 0.591 0.573 0.74 ]
 [0.632 0.568 0.477 0.463 0.598]
 [0.803 0.722 0.606 0.588 0.76 ]
 [1.377 1.238 1.04  1.008 1.304]
 [1.354 1.217 1.022 0.991 1.282]]
# Exhibit III Sheet 2, item 24
all_years = adjusted_claim_ratios.mean(axis="origin").values.squeeze()
vals = adjusted_claim_ratios.values.squeeze()
ex_high_low = (vals.sum(axis=1) - vals.max(axis=1) - vals.min(axis=1)) / 5
latest_5 = adjusted_claim_ratios.loc[:, :, "2004":, :].mean(axis="origin").values.squeeze()
latest_3 = adjusted_claim_ratios.loc[:, :, "2006":, :].mean(axis="origin").values.squeeze()
average_claim_ratios = np.vstack([all_years, ex_high_low, latest_5, latest_3])
print(np.round(average_claim_ratios, 3))
[[0.909 0.818 0.687 0.666 0.861]
 [0.871 0.783 0.658 0.638 0.825]
 [0.989 0.89  0.747 0.725 0.937]
 [1.178 1.059 0.89  0.863 1.115]]
# Exhibit III Sheet 2, item 25
vals = adjusted_claim_ratios.values.squeeze()
selected_expected_claim_ratio = (vals.sum(axis=1) - vals.max(axis=1) - vals.min(axis=1)) / 5
print(np.round(selected_expected_claim_ratio, 3))
[0.871 0.783 0.658 0.638 0.825]
# Exhibit III Sheet 2 — reconciliation
# Exhibit III Sheet 2, columns 1-2
assert np.allclose(
    (selected_view).values,
    np.array(
        [
            [
                [
                    [48953],
                    [47404],
                    [77662],
                    [78497],
                    [65239],
                    [62960],
                    [61262],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit III Sheet 2, columns 3-7
assert np.allclose(
    np.round(severity_trend_adjustment.values.squeeze().T, 3),
    np.array(
        [
            [1.070, 1.106, 1.144, 1.183, 1.224],
            [1.034, 1.070, 1.106, 1.144, 1.183],
            [1.000, 1.034, 1.070, 1.106, 1.144],
            [0.967, 1.000, 1.034, 1.070, 1.106],
            [0.935, 0.967, 1.000, 1.034, 1.070],
            [0.904, 0.935, 0.967, 1.000, 1.034],
            [0.874, 0.904, 0.935, 0.967, 1.000],
        ]
    ),
    atol=1e-6,
)

# Exhibit III Sheet 2, columns 8-12
assert np.allclose(
    np.round(tort_reform_adjustment.values.squeeze().T, 3),
    np.array(
        [
            [1.000, 1.000, 0.893, 0.670, 0.670],
            [1.000, 1.000, 0.893, 0.670, 0.670],
            [1.000, 1.000, 0.893, 0.670, 0.670],
            [1.000, 1.000, 0.893, 0.670, 0.670],
            [1.119, 1.119, 1.000, 0.750, 0.750],
            [1.493, 1.493, 1.333, 1.000, 1.000],
            [1.493, 1.493, 1.333, 1.000, 1.000],
        ]
    ),
    atol=1e-6,
)

# Exhibit III Sheet 2, column 13
assert np.allclose(
    earned_premium_view.values,
    np.array(
        [
            [
                [
                    [61183],
                    [69175],
                    [99322],
                    [138151],
                    [107578],
                    [62438],
                    [47797],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit III Sheet 2, columns 14-18
assert np.allclose(
    np.round(rate_level_adjustment.values.squeeze().T, 3),
    np.array(
        [
            [1.129, 1.298, 1.428, 1.142, 0.914],
            [1.075, 1.236, 1.360, 1.088, 0.870],
            [1.000, 1.150, 1.265, 1.012, 0.810],
            [0.870, 1.000, 1.100, 0.880, 0.704],
            [0.791, 0.909, 1.000, 0.800, 0.640],
            [0.988, 1.136, 1.250, 1.000, 0.800],
            [1.235, 1.420, 1.562, 1.250, 1.000],
        ]
    ),
    atol=1e-6,
)

# Exhibit III Sheet 2, columns 19-23
assert np.allclose(
    np.round(adjusted_claim_ratios.values.squeeze().T, 3),
    np.array(
        [
            [0.758, 0.682, 0.573, 0.555, 0.718],
            [0.659, 0.593, 0.498, 0.483, 0.624],
            [0.782, 0.703, 0.591, 0.573, 0.740],
            [0.632, 0.568, 0.477, 0.463, 0.598],
            [0.803, 0.722, 0.606, 0.588, 0.760],
            [1.377, 1.238, 1.040, 1.008, 1.304],
            [1.354, 1.217, 1.022, 0.991, 1.282],
        ]
    ),
    atol=1e-6,
)

# Exhibit III Sheet 2, item 24
assert np.allclose(
    np.round(average_claim_ratios, 3),
    np.array(
        [
            [0.909, 0.818, 0.687, 0.666, 0.861],
            [0.871, 0.783, 0.658, 0.638, 0.825],
            [0.989, 0.890, 0.747, 0.725, 0.937],
            [1.178, 1.059, 0.890, 0.863, 1.115],
        ]
    ),
    atol=1e-6,
)

# Exhibit III Sheet 2, item 25
assert np.allclose(
    np.round(selected_expected_claim_ratio, 3),
    [0.871, 0.783, 0.658, 0.638, 0.825],
    atol=1e-6,
)

Page 146#

# Exhibit III Sheet 3, columns 1-2
print(friedland_xyz_auto_bi["Reported Claims"].latest_diagonal)
print("Total:", friedland_xyz_auto_bi["Reported Claims"].latest_diagonal.sum())
         2008
1998  15822.0
1999  25107.0
2000  37246.0
2001  38798.0
2002  48169.0
2003  44373.0
2004  70288.0
2005  70655.0
2006  48804.0
2007  31732.0
2008  18632.0
Total: 449626.0
# Exhibit III Sheet 3, column 3
print(friedland_xyz_auto_bi["Paid Claims"].latest_diagonal)
print("Total:", friedland_xyz_auto_bi["Paid Claims"].latest_diagonal.sum())
         2008
1998  15822.0
1999  24817.0
2000  36782.0
2001  38519.0
2002  44437.0
2003  39320.0
2004  52811.0
2005  40026.0
2006  22819.0
2007  11865.0
2008   3409.0
Total: 330627.0
# Exhibit III Sheet 3, column 4
print(np.round(expected_claims, 0))
print("Total:", np.round(expected_claims.sum(), 0))
          2261
1998   15660.0
1999   24664.0
2000   35235.0
2001   39150.0
2002   47906.0
2003   54164.0
2004   86509.0
2005  108172.0
2006   70786.0
2007   39835.0
2008   39433.0
Total: 561514.0
# Exhibit III Sheet 3, column 5
case_outstanding = (
    friedland_xyz_auto_bi["Reported Claims"].latest_diagonal
    - friedland_xyz_auto_bi["Paid Claims"].latest_diagonal
).fillzero()
print(case_outstanding)
print("Total:", case_outstanding.sum())
         2008
1998      0.0
1999    290.0
2000    464.0
2001    279.0
2002   3732.0
2003   5053.0
2004  17477.0
2005  30629.0
2006  25985.0
2007  19867.0
2008  15223.0
Total: 118999.0
# Exhibit III Sheet 3, column 6
ibnr = np.round(el_reported.ibnr_, 0)
print(ibnr)
print("Total:", ibnr.sum())
         2261
1998   -162.0
1999   -442.0
2000  -2011.0
2001    352.0
2002   -263.0
2003   9791.0
2004  16221.0
2005  37517.0
2006  21982.0
2007   8103.0
2008  20801.0
Total: 111889.0
# Exhibit III Sheet 3, column 7
total_unpaid = np.round(el_paid.ibnr_, 0)
print(total_unpaid)
print("Total:", total_unpaid.sum())
         2261
1998   -162.0
1999   -152.0
2000  -1547.0
2001    631.0
2002   3469.0
2003  14844.0
2004  33698.0
2005  68146.0
2006  47967.0
2007  27970.0
2008  36024.0
Total: 230888.0
# Exhibit III Sheet 3 — reconciliation
# Exhibit III Sheet 3, columns 1-2
assert np.allclose(
    (friedland_xyz_auto_bi["Reported Claims"].latest_diagonal).values,
    np.array(
        [
            [
                [
                    [15822],
                    [25107],
                    [37246],
                    [38798],
                    [48169],
                    [44373],
                    [70288],
                    [70655],
                    [48804],
                    [31732],
                    [18632],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit III Sheet 3, columns 1-2
assert np.isclose(
    friedland_xyz_auto_bi["Reported Claims"].latest_diagonal.sum(),
    449626,
    atol=1e-6,
)

# Exhibit III Sheet 3, column 3
assert np.allclose(
    (friedland_xyz_auto_bi["Paid Claims"].latest_diagonal).values,
    np.array(
        [
            [
                [
                    [15822],
                    [24817],
                    [36782],
                    [38519],
                    [44437],
                    [39320],
                    [52811],
                    [40026],
                    [22819],
                    [11865],
                    [3409],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit III Sheet 3, column 3
assert np.isclose(
    friedland_xyz_auto_bi["Paid Claims"].latest_diagonal.sum(),
    330629,
    atol=2,
)

# Exhibit III Sheet 3, column 4
assert np.allclose(
    (np.round(expected_claims, 0)).values,
    np.array(
        [
            [
                [
                    [15660],
                    [24665],
                    [35235],
                    [39150],
                    [47906],
                    [54164],
                    [86509],
                    [108172],
                    [70786],
                    [39835],
                    [39433],
                ]
            ]
        ]
    ),
    atol=1,
)

# Exhibit III Sheet 3, column 4
assert np.isclose(
    np.round(expected_claims.sum(), 0), 
    561516, 
    atol=2
)

# Exhibit III Sheet 3, column 5
assert np.allclose(
    case_outstanding.values,
    np.array(
        [
            [
                [
                    [0],
                    [290],
                    [465],
                    [278],
                    [3731],
                    [5052],
                    [17477],
                    [30629],
                    [25985],
                    [19867],
                    [15223],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit III Sheet 3, column 5
assert np.isclose(
    case_outstanding.sum(), 
    118997, 
    atol=2,
)

# Exhibit III Sheet 3, column 6
assert np.allclose(
    (ibnr).values,
    np.array(
        [
            [
                [
                    [-162],
                    [-442],
                    [-2011],
                    [352],
                    [-262],
                    [9791],
                    [16221],
                    [37517],
                    [21982],
                    [8103],
                    [20801],
                ]
            ]
        ]
    ),
    atol=1,
)

# Exhibit III Sheet 3, column 6
assert np.isclose(
    ibnr.sum(), 
    111890, 
    atol=1
)

# Exhibit III Sheet 3, column 7
assert np.allclose(
    (total_unpaid).values,
    np.array(
        [
            [
                [
                    [-162],
                    [-152],
                    [-1547],
                    [631],
                    [3469],
                    [14844],
                    [33698],
                    [68146],
                    [47967],
                    [27970],
                    [36024],
                ]
            ]
        ]
    ),
    atol=1e-6,
)

# Exhibit III Sheet 3, column 7
assert np.isclose(total_unpaid.sum(), 230887, atol=1)

Page 147#

# Exhibit III Sheet 4, columns 1-2
print(friedland_xyz_auto_bi["Reported Claims"].latest_diagonal)
print("Total:", friedland_xyz_auto_bi["Reported Claims"].latest_diagonal.sum())
         2008
1998  15822.0
1999  25107.0
2000  37246.0
2001  38798.0
2002  48169.0
2003  44373.0
2004  70288.0
2005  70655.0
2006  48804.0
2007  31732.0
2008  18632.0
Total: 449626.0
# Exhibit III Sheet 4, column 3
print(friedland_xyz_auto_bi["Paid Claims"].latest_diagonal)
print("Total:", friedland_xyz_auto_bi["Paid Claims"].latest_diagonal.sum())
         2008
1998  15822.0
1999  24817.0
2000  36782.0
2001  38519.0
2002  44437.0
2003  39320.0
2004  52811.0
2005  40026.0
2006  22819.0
2007  11865.0
2008   3409.0
Total: 330627.0
# Exhibit III Sheet 4, column 4
print(reported_ultimate)
print("Total:", reported_ultimate.sum())
         2261
1998  15822.0
1999  25082.0
2000  36948.0
2001  38488.0
2002  48314.0
2003  44950.0
2004  74786.0
2005  76661.0
2006  58370.0
2007  47979.0
2008  47530.0
Total: 514930.0
# Exhibit III Sheet 4, column 5
print(paid_ultimate)
print("Total:", paid_ultimate.sum())
         2261
1998  15980.0
1999  25164.0
2000  37922.0
2001  40599.0
2002  49592.0
2003  49858.0
2004  80537.0
2005  80332.0
2006  72108.0
2007  77941.0
2008  74995.0
Total: 605028.0
# Exhibit III Sheet 4, column 6
print(np.round(expected_claims, 0))
print("Total:", np.round(expected_claims.sum(), 0))
          2261
1998   15660.0
1999   24664.0
2000   35235.0
2001   39150.0
2002   47906.0
2003   54164.0
2004   86509.0
2005  108172.0
2006   70786.0
2007   39835.0
2008   39433.0
Total: 561514.0
# Exhibit III Sheet 4 — reconciliation
# Exhibit III Sheet 4, columns 1-2
assert np.allclose(
    (friedland_xyz_auto_bi["Reported Claims"].latest_diagonal).values,
    np.array(
        [
            [
                [
                    [15822],
                    [25107],
                    [37246],
                    [38798],
                    [48169],
                    [44373],
                    [70288],
                    [70655],
                    [48804],
                    [31732],
                    [18632],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit III Sheet 4, columns 1-2
assert np.isclose(
    friedland_xyz_auto_bi["Reported Claims"].latest_diagonal.sum(),
    449626,
    atol=1e-6,
)

# Exhibit III Sheet 4, column 3
assert np.allclose(
    (friedland_xyz_auto_bi["Paid Claims"].latest_diagonal).values,
    np.array(
        [
            [
                [
                    [15822],
                    [24817],
                    [36782],
                    [38519],
                    [44437],
                    [39320],
                    [52811],
                    [40026],
                    [22819],
                    [11865],
                    [3409],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit III Sheet 4, column 3
assert np.isclose(
    friedland_xyz_auto_bi["Paid Claims"].latest_diagonal.sum(),
    330629,
    atol=2,
)

# Exhibit III Sheet 4, column 4
assert np.allclose(
    (reported_ultimate).values,
    np.array(
        [
            [
                [
                    [15822],
                    [25082],
                    [36948],
                    [38487],
                    [48313],
                    [44950],
                    [74787],
                    [76661],
                    [58370],
                    [47979],
                    [47530],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit III Sheet 4, column 4
assert np.isclose(
    reported_ultimate.sum(), 
    514929, 
    atol=1
)

# Exhibit III Sheet 4, column 5
assert np.allclose(
    (paid_ultimate).values,
    np.array(
        [
            [
                [
                    [15980],
                    [25164],
                    [37922],
                    [40600],
                    [49592],
                    [49858],
                    [80537],
                    [80333],
                    [72108],
                    [77941],
                    [74995],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit III Sheet 4, column 5
assert np.isclose(
    paid_ultimate.sum(), 
    605030, 
    atol=2
)

# Exhibit III Sheet 4, column 6
assert np.allclose(
    (np.round(expected_claims, 0)).values,
    np.array(
        [
            [
                [
                    [15660],
                    [24665],
                    [35235],
                    [39150],
                    [47906],
                    [54164],
                    [86509],
                    [108172],
                    [70786],
                    [39835],
                    [39433],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit III Sheet 4, column 6
assert np.isclose(
    np.round(expected_claims.sum(), 0), 
    561516, 
    atol=2
)

Page 148#

# Exhibit III Sheet 5, columns 1-2
print(case_outstanding)
print("Total:", case_outstanding.sum())
         2008
1998      0.0
1999    290.0
2000    464.0
2001    279.0
2002   3732.0
2003   5053.0
2004  17477.0
2005  30629.0
2006  25985.0
2007  19867.0
2008  15223.0
Total: 118999.0
# Exhibit III Sheet 5, column 3
ibnr_reported = np.round(
    reported_ultimate - friedland_xyz_auto_bi["Reported Claims"].latest_diagonal, 0
).fillzero()
print(ibnr_reported)
print("Total:", ibnr_reported.sum())
         2261
1998      0.0
1999    -25.0
2000   -298.0
2001   -310.0
2002    145.0
2003    577.0
2004   4498.0
2005   6006.0
2006   9566.0
2007  16247.0
2008  28898.0
Total: 65304.0
# Exhibit III Sheet 5, column 4
ibnr_paid = np.round(
    paid_ultimate - friedland_xyz_auto_bi["Reported Claims"].latest_diagonal, 0
)
print(ibnr_paid)
print("Total:", ibnr_paid.sum())
         2261
1998    158.0
1999     57.0
2000    676.0
2001   1801.0
2002   1423.0
2003   5485.0
2004  10249.0
2005   9677.0
2006  23304.0
2007  46209.0
2008  56363.0
Total: 155402.0
# Exhibit III Sheet 5, column 5
print(ibnr)
print("Total:", ibnr.sum())
         2261
1998   -162.0
1999   -442.0
2000  -2011.0
2001    352.0
2002   -263.0
2003   9791.0
2004  16221.0
2005  37517.0
2006  21982.0
2007   8103.0
2008  20801.0
Total: 111889.0
# Exhibit III Sheet 5 — reconciliation
# Exhibit III Sheet 5, columns 1-2
assert np.allclose(
    case_outstanding.values,
    np.array(
        [
            [
                [
                    [0],
                    [290],
                    [464],
                    [279],
                    [3732],
                    [5053],
                    [17477],
                    [30629],
                    [25985],
                    [19867],
                    [15223],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit III Sheet 5, columns 1-2
assert np.isclose(
    case_outstanding.sum(), 
    118997, 
    atol=2
)

# Exhibit III Sheet 5, column 3
assert np.allclose(
    (ibnr_reported).values,
    np.array(
        [
            [
                [
                    [0],
                    [-25],
                    [-298],
                    [-310],
                    [145],
                    [577],
                    [4498],
                    [6006],
                    [9566],
                    [16247],
                    [28898],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit III Sheet 5, column 3
assert np.isclose(
    ibnr_reported.sum(), 
    65303, 
    atol=1
)

# Exhibit III Sheet 5, column 4
assert np.allclose(
    (ibnr_paid).values,
    np.array(
        [
            [
                [
                    [158],
                    [58],
                    [676],
                    [1802],
                    [1423],
                    [5485],
                    [10249],
                    [9678],
                    [23304],
                    [46209],
                    [56363],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit III Sheet 5, column 4
assert np.isclose(
    ibnr_paid.sum(), 
    155405, 
    atol=3
)

# Exhibit III Sheet 5, column 5
assert np.allclose(
    (ibnr).values,
    np.array(
        [
            [
                [
                    [-162],
                    [-442],
                    [-2011],
                    [352],
                    [-262],
                    [9791],
                    [16221],
                    [37517],
                    [21982],
                    [8103],
                    [20801],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit III Sheet 5, column 5
assert np.isclose(
    ibnr.sum(), 
    111890, 
    atol=1
)

Page 149#

# Exhibit IV Sheet 1, Steady-State, columns 1-2
friedland_uspp = cl.load_sample("friedland_uspp")
friedland_uspp_auto_steady_state = friedland_uspp.loc["Steady State"]
earned_premium = np.round(
    friedland_uspp_auto_steady_state["Earned Premium"].latest_diagonal, 0
)
print(earned_premium)
print("Total:", earned_premium.sum())
           2008
1999  1000000.0
2000  1050000.0
2001  1102500.0
2002  1157625.0
2003  1215506.0
2004  1276282.0
2005  1340096.0
2006  1407100.0
2007  1477455.0
2008  1551328.0
Total: 12577892.0
# Exhibit IV Sheet 1, Steady-State, column 3
selected_claim_ratio = 0.70
print(selected_claim_ratio)
0.7
# Exhibit IV Sheet 1, Steady-State, column 4
el = cl.ExpectedLoss(apriori=selected_claim_ratio).fit(
    friedland_uspp_auto_steady_state["Reported Claims"],
    sample_weight=earned_premium,
)
expected_claims = np.round(el.ultimate_, 0)
print(expected_claims)
print("Total:", expected_claims.sum())
           2261
1999   700000.0
2000   735000.0
2001   771750.0
2002   810338.0
2003   850854.0
2004   893397.0
2005   938067.0
2006   984970.0
2007  1034218.0
2008  1085930.0
Total: 8804524.0
# Exhibit IV Sheet 1, Steady-State, column 5
reported_claims = friedland_uspp_auto_steady_state["Reported Claims"].latest_diagonal
print(reported_claims)
print("Total:", reported_claims.sum())
          2008
1999  700000.0
2000  735000.0
2001  771750.0
2002  810338.0
2003  842346.0
2004  884463.0
2005  919306.0
2006  935722.0
2007  930797.0
2008  836166.0
Total: 8365888.0
# Exhibit IV Sheet 1, Steady-State, column 6
estimated_ibnr = np.round(el.ibnr_, 0).fillzero()
print(estimated_ibnr)
print("Total:", estimated_ibnr.sum())
          2261
1999       0.0
2000       0.0
2001       0.0
2002       0.0
2003    8508.0
2004    8934.0
2005   18761.0
2006   49248.0
2007  103421.0
2008  249764.0
Total: 438636.0
# Exhibit IV Sheet 1, Steady-State, column 7
actual_ibnr = estimated_ibnr.copy()
actual_ibnr.values = np.array(
    [
        [
            [
                [0],
                [0],
                [0],
                [0],
                [8508],
                [8934],
                [18761],
                [49249],
                [103422],
                [249764],
            ]
        ]
    ],
    dtype=float,
)
print(actual_ibnr)
print("Total:", actual_ibnr.sum())
          2261
1999       0.0
2000       0.0
2001       0.0
2002       0.0
2003    8508.0
2004    8934.0
2005   18761.0
2006   49249.0
2007  103422.0
2008  249764.0
Total: 438638.0
# Exhibit IV Sheet 1, Steady-State, column 8
difference = np.round(actual_ibnr - estimated_ibnr, 0).fillzero()
print(difference)
print("Total:", difference.sum())

steady_earned_premium = earned_premium
steady_expected_claims = expected_claims
steady_reported_claims = reported_claims
steady_estimated_ibnr = estimated_ibnr
steady_actual_ibnr = actual_ibnr
steady_difference = difference
      2261
1999   0.0
2000   0.0
2001   0.0
2002   0.0
2003   0.0
2004   0.0
2005   0.0
2006   1.0
2007   1.0
2008   0.0
Total: 2.0
# Exhibit IV Sheet 1, Increasing Claim Ratios, columns 1-2
friedland_uspp_auto_increasing_claim = friedland_uspp.loc["Increasing Claim"]
earned_premium = np.round(
    friedland_uspp_auto_increasing_claim["Earned Premium"].latest_diagonal, 0
)
print(earned_premium)
print("Total:", earned_premium.sum())
           2008
1999  1000000.0
2000  1050000.0
2001  1102500.0
2002  1157625.0
2003  1215506.0
2004  1276282.0
2005  1340096.0
2006  1407100.0
2007  1477455.0
2008  1551328.0
Total: 12577892.0
# Exhibit IV Sheet 1, Increasing Claim Ratios, column 3
selected_claim_ratio = 0.70
print(selected_claim_ratio)
0.7
# Exhibit IV Sheet 1, Increasing Claim Ratios, column 4
el = cl.ExpectedLoss(apriori=selected_claim_ratio).fit(
    friedland_uspp_auto_increasing_claim["Reported Claims"],
    sample_weight=earned_premium,
)
expected_claims = np.round(el.ultimate_, 0)
print(expected_claims)
print("Total:", expected_claims.sum())
           2261
1999   700000.0
2000   735000.0
2001   771750.0
2002   810338.0
2003   850854.0
2004   893397.0
2005   938067.0
2006   984970.0
2007  1034218.0
2008  1085930.0
Total: 8804524.0
# Exhibit IV Sheet 1, Increasing Claim Ratios, column 5
reported_claims = friedland_uspp_auto_increasing_claim[
    "Reported Claims"
].latest_diagonal
print(reported_claims)
print("Total:", reported_claims.sum())
           2008
1999   700000.0
2000   735000.0
2001   771750.0
2002   810338.0
2003   842346.0
2004  1010815.0
2005  1116300.0
2006  1203071.0
2007  1263224.0
2008  1194523.0
Total: 9647367.0
# Exhibit IV Sheet 1, Increasing Claim Ratios, column 6
estimated_ibnr = np.round(el.ibnr_, 0).fillzero()
print(estimated_ibnr)
print("Total:", estimated_ibnr.sum())
          2261
1999       0.0
2000       0.0
2001       0.0
2002       0.0
2003    8508.0
2004 -117418.0
2005 -178233.0
2006 -218101.0
2007 -229006.0
2008 -108593.0
Total: -842843.0
# Exhibit IV Sheet 1, Increasing Claim Ratios, column 7
actual_ibnr = estimated_ibnr.copy()
actual_ibnr.values = np.array(
    [
        [
            [
                [0],
                [0],
                [0],
                [0],
                [8508],
                [10210],
                [22782],
                [63320],
                [140358],
                [356805],
            ]
        ]
    ],
    dtype=float,
)
print(actual_ibnr)
print("Total:", actual_ibnr.sum())
          2261
1999       0.0
2000       0.0
2001       0.0
2002       0.0
2003    8508.0
2004   10210.0
2005   22782.0
2006   63320.0
2007  140358.0
2008  356805.0
Total: 601983.0
# Exhibit IV Sheet 1, Increasing Claim Ratios, column 8
difference = np.round(actual_ibnr - estimated_ibnr, 0).fillzero()
print(difference)
print("Total:", difference.sum())

increasing_claim_earned_premium = earned_premium
increasing_claim_expected_claims = expected_claims
increasing_claim_reported_claims = reported_claims
increasing_claim_estimated_ibnr = estimated_ibnr
increasing_claim_actual_ibnr = actual_ibnr
increasing_claim_difference = difference
          2261
1999       0.0
2000       0.0
2001       0.0
2002       0.0
2003       0.0
2004  127628.0
2005  201015.0
2006  281421.0
2007  369364.0
2008  465398.0
Total: 1444826.0
# Exhibit IV Sheet 1, Steady-State — reconciliation
# Exhibit IV Sheet 1, Steady-State, columns 1-2
assert np.allclose(
    steady_earned_premium.values,
    np.array(
        [
            [
                [
                    [1000000],
                    [1050000],
                    [1102500],
                    [1157625],
                    [1215506],
                    [1276282],
                    [1340096],
                    [1407100],
                    [1477455],
                    [1551328],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit IV Sheet 1, Steady-State, columns 1-2
assert np.isclose(
    steady_earned_premium.sum(), 
    12577893, 
    atol=1
)

# Exhibit IV Sheet 1, Steady-State, column 3: omitted

# Exhibit IV Sheet 1, Steady-State, column 4
assert np.allclose(
    steady_expected_claims.values,
    np.array(
        [
            [
                [
                    [700000],
                    [735000],
                    [771750],
                    [810338],
                    [850854],
                    [893397],
                    [938067],
                    [984970],
                    [1034219],
                    [1085930],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit IV Sheet 1, Steady-State, column 4
assert np.isclose(
    steady_expected_claims.sum(), 
    8804525, 
    atol=1
)

# Exhibit IV Sheet 1, Steady-State, column 5
assert np.allclose(
    steady_reported_claims.values,
    np.array(
        [
            [
                [
                    [700000],
                    [735000],
                    [771750],
                    [810338],
                    [842346],
                    [884463],
                    [919306],
                    [935722],
                    [930797],
                    [836166],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit IV Sheet 1, Steady-State, column 5
assert np.isclose(
    steady_reported_claims.sum(), 
    8365887, 
    atol=1
)

# Exhibit IV Sheet 1, Steady-State, column 6
assert np.allclose(
    steady_estimated_ibnr.values,
    np.array(
        [
            [
                [
                    [0],
                    [0],
                    [0],
                    [0],
                    [8509],
                    [8934],
                    [18761],
                    [49249],
                    [103422],
                    [249764],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit IV Sheet 1, Steady-State, column 6
assert np.isclose(
    steady_estimated_ibnr.sum(), 
    438638, 
    atol=2
)

# Exhibit IV Sheet 1, Steady-State, column 7
assert np.allclose(
    steady_actual_ibnr.values,
    np.array(
        [
            [
                [
                    [0],
                    [0],
                    [0],
                    [0],
                    [8509],
                    [8934],
                    [18761],
                    [49249],
                    [103422],
                    [249764],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit IV Sheet 1, Steady-State, column 7
assert np.isclose(steady_actual_ibnr.sum(), 438638, atol=1e-6)

# Exhibit IV Sheet 1, Steady-State, column 8
assert np.allclose(
    steady_difference.values,
    np.array(
        [
            [
                [
                    [0],
                    [0],
                    [0],
                    [0],
                    [0],
                    [0],
                    [0],
                    [0],
                    [0],
                    [0],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit IV Sheet 1, Steady-State, column 8
assert np.isclose(
    steady_difference.sum(), 
    0, 
    atol=2
)
# Exhibit IV Sheet 1, Increasing Claim Ratios — reconciliation
# Exhibit IV Sheet 1, Increasing Claim Ratios, columns 1-2
assert np.allclose(
    increasing_claim_earned_premium.values,
    np.array(
        [
            [
                [
                    [1000000],
                    [1050000],
                    [1102500],
                    [1157625],
                    [1215506],
                    [1276282],
                    [1340096],
                    [1407100],
                    [1477455],
                    [1551328],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit IV Sheet 1, Increasing Claim Ratios, columns 1-2
assert np.isclose(
    increasing_claim_earned_premium.sum(),
    12577893, 
    atol=1
)

# Exhibit IV Sheet 1, Increasing Claim Ratios, column 3: omitted

# Exhibit IV Sheet 1, Increasing Claim Ratios, column 4
assert np.allclose(
    increasing_claim_expected_claims.values,
    np.array(
        [
            [
                [
                    [700000],
                    [735000],
                    [771750],
                    [810338],
                    [850854],
                    [893397],
                    [938067],
                    [984970],
                    [1034219],
                    [1085930],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit IV Sheet 1, Increasing Claim Ratios, column 4
assert np.isclose(
    increasing_claim_expected_claims.sum(), 
    8804525, 
    atol=1
)

# Exhibit IV Sheet 1, Increasing Claim Ratios, column 5
assert np.allclose(
    increasing_claim_reported_claims.values,
    np.array(
        [
            [
                [
                    [700000],
                    [735000],
                    [771750],
                    [810338],
                    [842346],
                    [1010815],
                    [1116300],
                    [1203071],
                    [1263224],
                    [1194523],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit IV Sheet 1, Increasing Claim Ratios, column 5
assert np.isclose(
    increasing_claim_reported_claims.sum(), 
    9647366, 
    atol=1
)

# Exhibit IV Sheet 1, Increasing Claim Ratios, column 6
assert np.allclose(
    increasing_claim_estimated_ibnr.values,
    np.array(
        [
            [
                [
                    [0],
                    [0],
                    [0],
                    [0],
                    [8509],
                    [-117418],
                    [-178233],
                    [-218101],
                    [-229006],
                    [-108593],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit IV Sheet 1, Increasing Claim Ratios, column 6
assert np.isclose(
    increasing_claim_estimated_ibnr.sum(), 
    -842841, 
    atol=2
)

# Exhibit IV Sheet 1, Increasing Claim Ratios, column 7
assert np.allclose(
    increasing_claim_actual_ibnr.values,
    np.array(
        [
            [
                [
                    [0],
                    [0],
                    [0],
                    [0],
                    [8509],
                    [10210],
                    [22782],
                    [63320],
                    [140358],
                    [356805],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit IV Sheet 1, Increasing Claim Ratios, column 7
assert np.isclose(
    increasing_claim_actual_ibnr.sum(), 
    601984, 
    atol=1
)

# Exhibit IV Sheet 1, Increasing Claim Ratios, column 8
assert np.allclose(
    increasing_claim_difference.values,
    np.array(
        [
            [
                [
                    [0],
                    [0],
                    [0],
                    [0],
                    [0],
                    [127628],
                    [201014],
                    [281420],
                    [369364],
                    [465398],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit IV Sheet 1, Increasing Claim Ratios, column 8
assert np.isclose(
    increasing_claim_difference.sum(), 
    1444824, 
    atol=2
)

Page 150#

# Exhibit IV Sheet 2, Increasing Case Outstanding Strength, columns 1-2
friedland_uspp_auto_increasing_case = friedland_uspp.loc["Increasing Case"]
earned_premium = np.round(
    friedland_uspp_auto_increasing_case["Earned Premium"].latest_diagonal, 0
)
print(earned_premium)
print("Total:", earned_premium.sum())
           2008
1999  1000000.0
2000  1050000.0
2001  1102500.0
2002  1157625.0
2003  1215506.0
2004  1276282.0
2005  1340096.0
2006  1407100.0
2007  1477455.0
2008  1551328.0
Total: 12577892.0
# Exhibit IV Sheet 2, Increasing Case Outstanding Strength, column 3
selected_claim_ratio = 0.70
print(selected_claim_ratio)
0.7
# Exhibit IV Sheet 2, Increasing Case Outstanding Strength, column 4
el = cl.ExpectedLoss(apriori=selected_claim_ratio).fit(
    friedland_uspp_auto_increasing_case["Reported Claims"],
    sample_weight=earned_premium,
)
expected_claims = np.round(el.ultimate_, 0)
print(expected_claims)
print("Total:", expected_claims.sum())
           2261
1999   700000.0
2000   735000.0
2001   771750.0
2002   810338.0
2003   850854.0
2004   893397.0
2005   938067.0
2006   984970.0
2007  1034218.0
2008  1085930.0
Total: 8804524.0
# Exhibit IV Sheet 2, Increasing Case Outstanding Strength, column 5
reported_claims = friedland_uspp_auto_increasing_case[
    "Reported Claims"
].latest_diagonal
print(reported_claims)
print("Total:", reported_claims.sum())
          2008
1999  700000.0
2000  735000.0
2001  771750.0
2002  810338.0
2003  842346.0
2004  884463.0
2005  933377.0
2006  962808.0
2007  979922.0
2008  931185.0
Total: 8551189.0
# Exhibit IV Sheet 2, Increasing Case Outstanding Strength, column 6
estimated_ibnr = np.round(el.ibnr_, 0).fillzero()
print(estimated_ibnr)
print("Total:", estimated_ibnr.sum())
          2261
1999       0.0
2000       0.0
2001       0.0
2002       0.0
2003    8508.0
2004    8934.0
2005    4690.0
2006   22162.0
2007   54296.0
2008  154745.0
Total: 253335.0
# Exhibit IV Sheet 2, Increasing Case Outstanding Strength, column 7
actual_ibnr = estimated_ibnr.copy()
actual_ibnr.values = np.array(
    [
        [
            [
                [0],
                [0],
                [0],
                [0],
                [8509],
                [8934],
                [4690],
                [22162],
                [54296],
                [154745],
            ]
        ]
    ],
    dtype=float,
)
print(actual_ibnr)
print("Total:", actual_ibnr.sum())
          2261
1999       0.0
2000       0.0
2001       0.0
2002       0.0
2003    8509.0
2004    8934.0
2005    4690.0
2006   22162.0
2007   54296.0
2008  154745.0
Total: 253336.0
# Exhibit IV Sheet 2, Increasing Case Outstanding Strength, column 8
difference = np.round(actual_ibnr - estimated_ibnr, 0).fillzero()
print(difference)
print("Total:", difference.sum())

case_strength_earned_premium = earned_premium
case_strength_expected_claims = expected_claims
case_strength_reported_claims = reported_claims
case_strength_estimated_ibnr = estimated_ibnr
case_strength_actual_ibnr = actual_ibnr
case_strength_difference = difference
      2261
1999   0.0
2000   0.0
2001   0.0
2002   0.0
2003   1.0
2004   0.0
2005   0.0
2006   0.0
2007   0.0
2008   0.0
Total: 1.0
# Exhibit IV Sheet 2, Increasing Claim Ratios and Case Outstanding Strength, columns 1-2
friedland_uspp_increasing_claim_case = friedland_uspp.loc["Increasing Claim Case"]
earned_premium = np.round(
    friedland_uspp_increasing_claim_case["Earned Premium"].latest_diagonal, 0
)
print(earned_premium)
print("Total:", earned_premium.sum())
           2008
1999  1000000.0
2000  1050000.0
2001  1102500.0
2002  1157625.0
2003  1215506.0
2004  1276282.0
2005  1340096.0
2006  1407100.0
2007  1477455.0
2008  1551328.0
Total: 12577892.0
# Exhibit IV Sheet 2, Increasing Claim Ratios and Case Outstanding Strength, column 3
selected_claim_ratio = 0.70
print(selected_claim_ratio)
0.7
# Exhibit IV Sheet 2, Increasing Claim Ratios and Case Outstanding Strength, column 4
el = cl.ExpectedLoss(apriori=selected_claim_ratio).fit(
    friedland_uspp_increasing_claim_case["Reported Claims"],
    sample_weight=earned_premium,
)
expected_claims = np.round(el.ultimate_, 0)
print(expected_claims)
print("Total:", expected_claims.sum())
           2261
1999   700000.0
2000   735000.0
2001   771750.0
2002   810338.0
2003   850854.0
2004   893397.0
2005   938067.0
2006   984970.0
2007  1034218.0
2008  1085930.0
Total: 8804524.0
# Exhibit IV Sheet 2, Increasing Claim Ratios and Case Outstanding Strength, column 5
reported_claims = friedland_uspp_increasing_claim_case[
    "Reported Claims"
].latest_diagonal
print(reported_claims)
print("Total:", reported_claims.sum())
           2008
1999   700000.0
2000   735000.0
2001   771750.0
2002   810338.0
2003   842346.0
2004  1010815.0
2005  1133386.0
2006  1237897.0
2007  1329895.0
2008  1330264.0
Total: 9901691.0
# Exhibit IV Sheet 2, Increasing Claim Ratios and Case Outstanding Strength, column 6
estimated_ibnr = np.round(el.ibnr_, 0).fillzero()
print(estimated_ibnr)
print("Total:", estimated_ibnr.sum())
          2261
1999       0.0
2000       0.0
2001       0.0
2002       0.0
2003    8508.0
2004 -117418.0
2005 -195319.0
2006 -252927.0
2007 -295677.0
2008 -244334.0
Total: -1097167.0
# Exhibit IV Sheet 2, Increasing Claim Ratios and Case Outstanding Strength, column 7
actual_ibnr = estimated_ibnr.copy()
actual_ibnr.values = np.array(
    [
        [
            [
                [0],
                [0],
                [0],
                [0],
                [8509],
                [10210],
                [5695],
                [28494],
                [73688],
                [221064],
            ]
        ]
    ],
    dtype=float,
)
print(actual_ibnr)
print("Total:", actual_ibnr.sum())
          2261
1999       0.0
2000       0.0
2001       0.0
2002       0.0
2003    8509.0
2004   10210.0
2005    5695.0
2006   28494.0
2007   73688.0
2008  221064.0
Total: 347660.0
# Exhibit IV Sheet 2, Increasing Claim Ratios and Case Outstanding Strength, column 8
difference = np.round(actual_ibnr - estimated_ibnr, 0).fillzero()
print(difference)
print("Total:", difference.sum())
          2261
1999       0.0
2000       0.0
2001       0.0
2002       0.0
2003       1.0
2004  127628.0
2005  201014.0
2006  281421.0
2007  369365.0
2008  465398.0
Total: 1444827.0
# Exhibit IV Sheet 2, Increasing Case Outstanding Strength — reconciliation
# Exhibit IV Sheet 2, Increasing Case Outstanding Strength, columns 1-2
assert np.allclose(
    case_strength_earned_premium.values,
    np.array(
        [
            [
                [
                    [1000000],
                    [1050000],
                    [1102500],
                    [1157625],
                    [1215506],
                    [1276282],
                    [1340096],
                    [1407100],
                    [1477455],
                    [1551328],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit IV Sheet 2, Increasing Case Outstanding Strength, columns 1-2
assert np.isclose(
    case_strength_earned_premium.sum(), 
    12577893, 
    atol=1
)

# Exhibit IV Sheet 2, Increasing Case Outstanding Strength, column 3: omitted

# Exhibit IV Sheet 2, Increasing Case Outstanding Strength, column 4
assert np.allclose(
    case_strength_expected_claims.values,
    np.array(
        [
            [
                [
                    [700000],
                    [735000],
                    [771750],
                    [810338],
                    [850854],
                    [893397],
                    [938067],
                    [984970],
                    [1034219],
                    [1085930],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit IV Sheet 2, Increasing Case Outstanding Strength, column 4
assert np.isclose(
    case_strength_expected_claims.sum(), 
    8804525, 
    atol=1
)

# Exhibit IV Sheet 2, Increasing Case Outstanding Strength, column 5
assert np.allclose(
    case_strength_reported_claims.values,
    np.array(
        [
            [
                [
                    [700000],
                    [735000],
                    [771750],
                    [810338],
                    [842346],
                    [884463],
                    [933377],
                    [962808],
                    [979922],
                    [931185],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit IV Sheet 2, Increasing Case Outstanding Strength, column 5
assert np.isclose(case_strength_reported_claims.sum(), 8551189, atol=1e-6)

# Exhibit IV Sheet 2, Increasing Case Outstanding Strength, column 6
assert np.allclose(
    case_strength_estimated_ibnr.values,
    np.array(
        [
            [
                [
                    [0],
                    [0],
                    [0],
                    [0],
                    [8509],
                    [8934],
                    [4690],
                    [22162],
                    [54296],
                    [154745],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit IV Sheet 2, Increasing Case Outstanding Strength, column 6
assert np.isclose(
    case_strength_estimated_ibnr.sum(), 
    253336, 
    atol=1
)

# Exhibit IV Sheet 2, Increasing Case Outstanding Strength, column 7
assert np.allclose(
    case_strength_actual_ibnr.values,
    np.array(
        [
            [
                [
                    [0],
                    [0],
                    [0],
                    [0],
                    [8509],
                    [8934],
                    [4690],
                    [22162],
                    [54296],
                    [154745],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit IV Sheet 2, Increasing Case Outstanding Strength, column 7
assert np.isclose(
    case_strength_actual_ibnr.sum(), 
    253336, 
    atol=1e-6
)

# Exhibit IV Sheet 2, Increasing Case Outstanding Strength, column 8
assert np.allclose(
    case_strength_difference.values,
    np.array(
        [
            [
                [
                    [0],
                    [0],
                    [0],
                    [0],
                    [0],
                    [0],
                    [0],
                    [0],
                    [0],
                    [0],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit IV Sheet 2, Increasing Case Outstanding Strength, column 8
assert np.isclose(case_strength_difference.sum(), 0, atol=1)
# Exhibit IV Sheet 2, Increasing Claim Ratios and Case Outstanding Strength — reconciliation
# Exhibit IV Sheet 2, Increasing Claim Ratios and Case Outstanding Strength, columns 1-2
assert np.allclose(
    earned_premium.values,
    np.array(
        [
            [
                [
                    [1000000],
                    [1050000],
                    [1102500],
                    [1157625],
                    [1215506],
                    [1276282],
                    [1340096],
                    [1407100],
                    [1477455],
                    [1551328],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit IV Sheet 2, Increasing Claim Ratios and Case Outstanding Strength, columns 1-2
assert np.isclose(
    earned_premium.sum(), 
    12577893, 
    atol=1
)

# Exhibit IV Sheet 2, Increasing Claim Ratios and Case Outstanding Strength, column 3: omitted

# Exhibit IV Sheet 2, Increasing Claim Ratios and Case Outstanding Strength, column 4
assert np.allclose(
    expected_claims.values,
    np.array(
        [
            [
                [
                    [700000],
                    [735000],
                    [771750],
                    [810338],
                    [850854],
                    [893397],
                    [938067],
                    [984970],
                    [1034219],
                    [1085930],
                ]
            ]
        ]
    ),
    atol=1, 
    equal_nan=True,
)

# Exhibit IV Sheet 2, Increasing Claim Ratios and Case Outstanding Strength, column 4
assert np.isclose(
    expected_claims.sum(), 
    8804525, 
    atol=1
)

# Exhibit IV Sheet 2, Increasing Claim Ratios and Case Outstanding Strength, column 5
assert np.allclose(
    reported_claims.values,
    np.array(
        [
            [
                [
                    [700000],
                    [735000],
                    [771750],
                    [810338],
                    [842346],
                    [1010815],
                    [1133386],
                    [1237897],
                    [1329895],
                    [1330264],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit IV Sheet 2, Increasing Claim Ratios and Case Outstanding Strength, column 5
assert np.isclose(
    reported_claims.sum(), 
    9901689, 
    atol=2
)

# Exhibit IV Sheet 2, Increasing Claim Ratios and Case Outstanding Strength, column 6
assert np.allclose(
    estimated_ibnr.values,
    np.array(
        [
            [
                [
                    [0],
                    [0],
                    [0],
                    [0],
                    [8509],
                    [-117418],
                    [-195319],
                    [-252926],
                    [-295676],
                    [-244334],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit IV Sheet 2, Increasing Claim Ratios and Case Outstanding Strength, column 6
assert np.isclose(
    estimated_ibnr.sum(), 
    -1097165, 
    atol=2
)

# Exhibit IV Sheet 2, Increasing Claim Ratios and Case Outstanding Strength, column 7
assert np.allclose(
    actual_ibnr.values,
    np.array(
        [
            [
                [
                    [0],
                    [0],
                    [0],
                    [0],
                    [8509],
                    [10210],
                    [5695],
                    [28494],
                    [73688],
                    [221064],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit IV Sheet 2, Increasing Claim Ratios and Case Outstanding Strength, column 7
assert np.isclose(
    actual_ibnr.sum(), 
    347660, 
    atol=1e-6
)

# Exhibit IV Sheet 2, Increasing Claim Ratios and Case Outstanding Strength, column 8
assert np.allclose(
    difference.values,
    np.array(
        [
            [
                [
                    [0],
                    [0],
                    [0],
                    [0],
                    [0],
                    [127628],
                    [201014],
                    [281420],
                    [369364],
                    [465398],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit IV Sheet 2, Increasing Claim Ratios and Case Outstanding Strength, column 8
assert np.isclose(difference.sum(), 1444824, atol=3)

Page 151#

# Exhibit V, Steady-State (No Change in Product Mix), columns 1-2
friedland_us_auto_steady_state = cl.load_sample("friedland_us_auto_steady_state")
earned_premium = np.round(
    friedland_us_auto_steady_state["Earned Premium"].latest_diagonal, 0
)
print(earned_premium)
print("Total:", earned_premium.sum())
           2008
1999  2000000.0
2000  2100000.0
2001  2205000.0
2002  2315250.0
2003  2431013.0
2004  2552563.0
2005  2680191.0
2006  2814201.0
2007  2954911.0
2008  3102656.0
Total: 25155785.0
# Exhibit V, Steady-State (No Change in Product Mix), column 3
selected_claim_ratio = 0.75
print(selected_claim_ratio)
0.75
# Exhibit V, Steady-State (No Change in Product Mix), column 4
el = cl.ExpectedLoss(apriori=selected_claim_ratio).fit(
    friedland_us_auto_steady_state["Reported Claims"],
    sample_weight=earned_premium,
)
expected_claims = np.round(el.ultimate_, 0)
print(expected_claims)
print("Total:", expected_claims.sum())
           2261
1999  1500000.0
2000  1575000.0
2001  1653750.0
2002  1736438.0
2003  1823260.0
2004  1914422.0
2005  2010143.0
2006  2110651.0
2007  2216183.0
2008  2326992.0
Total: 18866839.0
# Exhibit V, Steady-State (No Change in Product Mix), column 5
reported_claims = friedland_us_auto_steady_state["Reported Claims"].latest_diagonal
print(reported_claims)
print("Total:", reported_claims.sum())
           2008
1999  1500000.0
2000  1575000.0
2001  1653750.0
2002  1736438.0
2003  1814751.0
2004  1885068.0
2005  1948499.0
2006  1937577.0
2007  1852729.0
2008  1568393.0
Total: 17472205.0
# Exhibit V, Steady-State (No Change in Product Mix), column 6
estimated_ibnr = np.round(el.ibnr_, 0).fillzero()
print(estimated_ibnr)
print("Total:", estimated_ibnr.sum())
          2261
1999       0.0
2000       0.0
2001       0.0
2002       0.0
2003    8509.0
2004   29354.0
2005   61644.0
2006  173074.0
2007  363454.0
2008  758599.0
Total: 1394634.0
# Exhibit V, Steady-State (No Change in Product Mix), column 7
actual_ibnr = estimated_ibnr.copy()
actual_ibnr.values = np.array(
    [
        [
            [
                [0],
                [0],
                [0],
                [0],
                [8509],
                [29354],
                [61644],
                [173073],
                [363454],
                [758599],
            ]
        ]
    ],
    dtype=float,
)
print(actual_ibnr)
print("Total:", actual_ibnr.sum())
          2261
1999       0.0
2000       0.0
2001       0.0
2002       0.0
2003    8509.0
2004   29354.0
2005   61644.0
2006  173073.0
2007  363454.0
2008  758599.0
Total: 1394633.0
# Exhibit V, Steady-State (No Change in Product Mix), column 8
difference = np.round(actual_ibnr - estimated_ibnr, 0).fillzero()
print(difference)
print("Total:", difference.sum())

steady_earned_premium = earned_premium
steady_expected_claims = expected_claims
steady_reported_claims = reported_claims
steady_estimated_ibnr = estimated_ibnr
steady_actual_ibnr = actual_ibnr
steady_difference = difference
      2261
1999   0.0
2000   0.0
2001   0.0
2002   0.0
2003   0.0
2004   0.0
2005   0.0
2006  -1.0
2007   0.0
2008   0.0
Total: -1.0
# Exhibit V, Changing Product Mix, columns 1-2
friedland_us_auto_chg_prod_mix = cl.load_sample("friedland_us_auto_chg_prod_mix")
earned_premium = np.round(
    friedland_us_auto_chg_prod_mix["Earned Premium"].latest_diagonal, 0
)
print(earned_premium)
print("Total:", earned_premium.sum())
           2008
1999  2000000.0
2000  2100000.0
2001  2205000.0
2002  2315250.0
2003  2431013.0
2004  2552563.0
2005  2999262.0
2006  3564016.0
2007  4281446.0
2008  5196516.0
Total: 29645066.0
# Exhibit V, Changing Product Mix, column 3
selected_claim_ratio = 0.75
print(selected_claim_ratio)
0.75
# Exhibit V, Changing Product Mix, column 4
el = cl.ExpectedLoss(apriori=selected_claim_ratio).fit(
    friedland_us_auto_chg_prod_mix["Reported Claims"],
    sample_weight=earned_premium,
)
expected_claims = np.round(el.ultimate_, 0)
print(expected_claims)
print("Total:", expected_claims.sum())
           2261
1999  1500000.0
2000  1575000.0
2001  1653750.0
2002  1736438.0
2003  1823260.0
2004  1914422.0
2005  2249446.0
2006  2673012.0
2007  3211084.0
2008  3897387.0
Total: 22233799.0
# Exhibit V, Changing Product Mix, column 5
reported_claims = friedland_us_auto_chg_prod_mix["Reported Claims"].latest_diagonal
print(reported_claims)
print("Total:", reported_claims.sum())
           2008
1999  1500000.0
2000  1575000.0
2001  1653750.0
2002  1736438.0
2003  1814751.0
2004  1885068.0
2005  2193545.0
2006  2471446.0
2007  2680487.0
2008  2556695.0
Total: 20067180.0
# Exhibit V, Changing Product Mix, column 6
estimated_ibnr = np.round(el.ibnr_, 0).fillzero()
print(estimated_ibnr)
print("Total:", estimated_ibnr.sum())
           2261
1999        0.0
2000        0.0
2001        0.0
2002        0.0
2003     8509.0
2004    29354.0
2005    55902.0
2006   201566.0
2007   530598.0
2008  1340692.0
Total: 2166621.0
# Exhibit V, Changing Product Mix, column 7
actual_ibnr = estimated_ibnr.copy()
actual_ibnr.values = np.array(
    [
        [
            [
                [0],
                [0],
                [0],
                [0],
                [8509],
                [29354],
                [71855],
                [239057],
                [596924],
                [1445385],
            ]
        ]
    ],
    dtype=float,
)
print(actual_ibnr)
print("Total:", actual_ibnr.sum())
           2261
1999        0.0
2000        0.0
2001        0.0
2002        0.0
2003     8509.0
2004    29354.0
2005    71855.0
2006   239057.0
2007   596924.0
2008  1445385.0
Total: 2391084.0
# Exhibit V, Changing Product Mix, column 8
difference = np.round(actual_ibnr - estimated_ibnr, 0).fillzero()
print(difference)
print("Total:", difference.sum())
          2261
1999       0.0
2000       0.0
2001       0.0
2002       0.0
2003       0.0
2004       0.0
2005   15953.0
2006   37491.0
2007   66326.0
2008  104693.0
Total: 224463.0
# Exhibit V, Steady-State (No Change in Product Mix) — reconciliation
# Exhibit V, Steady-State (No Change in Product Mix), columns 1-2
assert np.allclose(
    steady_earned_premium.values,
    np.array(
        [
            [
                [
                    [2000000],
                    [2100000],
                    [2205000],
                    [2315250],
                    [2431013],
                    [2552563],
                    [2680191],
                    [2814201],
                    [2954911],
                    [3102656],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit V, Steady-State (No Change in Product Mix), columns 1-2
assert np.isclose(steady_earned_premium.sum(), 25155785, atol=1e-6)

# Exhibit V, Steady-State (No Change in Product Mix), column 3: omitted

# Exhibit V, Steady-State (No Change in Product Mix), column 4
assert np.allclose(
    steady_expected_claims.values,
    np.array(
        [
            [
                [
                    [1500000],
                    [1575000],
                    [1653750],
                    [1736438],
                    [1823259],
                    [1914422],
                    [2010143],
                    [2110651],
                    [2216183],
                    [2326992],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit V, Steady-State (No Change in Product Mix), column 4
assert np.isclose(steady_expected_claims.sum(), 18866839, atol=1e-6)

# Exhibit V, Steady-State (No Change in Product Mix), column 5
assert np.allclose(
    steady_reported_claims.values,
    np.array(
        [
            [
                [
                    [1500000],
                    [1575000],
                    [1653750],
                    [1736438],
                    [1814751],
                    [1885068],
                    [1948499],
                    [1937577],
                    [1852729],
                    [1568393],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit V, Steady-State (No Change in Product Mix), column 5
assert np.isclose(steady_reported_claims.sum(), 17472204, atol=1)

# Exhibit V, Steady-State (No Change in Product Mix), column 6
assert np.allclose(
    steady_estimated_ibnr.values,
    np.array(
        [
            [
                [
                    [0],
                    [0],
                    [0],
                    [0],
                    [8509],
                    [29354],
                    [61644],
                    [173073],
                    [363454],
                    [758599],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit V, Steady-State (No Change in Product Mix), column 6
assert np.isclose(steady_estimated_ibnr.sum(), 1394634, atol=1e-6)

# Exhibit V, Steady-State (No Change in Product Mix), column 7
assert np.allclose(
    steady_actual_ibnr.values,
    np.array(
        [
            [
                [
                    [0],
                    [0],
                    [0],
                    [0],
                    [8509],
                    [29354],
                    [61644],
                    [173073],
                    [363454],
                    [758599],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit V, Steady-State (No Change in Product Mix), column 7
assert np.isclose(steady_actual_ibnr.sum(), 1394634, atol=1)

# Exhibit V, Steady-State (No Change in Product Mix), column 8
assert np.allclose(
    steady_difference.values,
    np.array(
        [
            [
                [
                    [0],
                    [0],
                    [0],
                    [0],
                    [0],
                    [0],
                    [0],
                    [0],
                    [0],
                    [0],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit V, Steady-State (No Change in Product Mix), column 8
assert np.isclose(steady_difference.sum(), 0, atol=1)
# Exhibit V, Changing Product Mix — reconciliation
# Exhibit V, Changing Product Mix, columns 1-2
assert np.allclose(
    earned_premium.values,
    np.array(
        [
            [
                [
                    [2000000],
                    [2100000],
                    [2205000],
                    [2315250],
                    [2431013],
                    [2552563],
                    [2999262],
                    [3564016],
                    [4281446],
                    [5196516],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit V, Changing Product Mix, columns 1-2
assert np.isclose(earned_premium.sum(), 29645066, atol=1e-6)

# Exhibit V, Changing Product Mix, column 3: omitted

# Exhibit V, Changing Product Mix, column 4
assert np.allclose(
    expected_claims.values,
    np.array(
        [
            [
                [
                    [1500000],
                    [1575000],
                    [1653750],
                    [1736438],
                    [1823259],
                    [1914422],
                    [2249446],
                    [2673012],
                    [3211085],
                    [3897387],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit V, Changing Product Mix, column 4
assert np.isclose(expected_claims.sum(), 22233799, atol=1e-6)

# Exhibit V, Changing Product Mix, column 5
assert np.allclose(
    reported_claims.values,
    np.array(
        [
            [
                [
                    [1500000],
                    [1575000],
                    [1653750],
                    [1736438],
                    [1814751],
                    [1885068],
                    [2193545],
                    [2471446],
                    [2680487],
                    [2556695],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit V, Changing Product Mix, column 5
assert np.isclose(reported_claims.sum(), 20067179, atol=1)

# Exhibit V, Changing Product Mix, column 6
assert np.allclose(
    estimated_ibnr.values,
    np.array(
        [
            [
                [
                    [0],
                    [0],
                    [0],
                    [0],
                    [8509],
                    [29354],
                    [55901],
                    [201566],
                    [530597],
                    [1340692],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit V, Changing Product Mix, column 6
assert np.isclose(estimated_ibnr.sum(), 2166620, atol=1)

# Exhibit V, Changing Product Mix, column 7
assert np.allclose(
    actual_ibnr.values,
    np.array(
        [
            [
                [
                    [0],
                    [0],
                    [0],
                    [0],
                    [8509],
                    [29354],
                    [71855],
                    [239057],
                    [596924],
                    [1445385],
                ]
            ]
        ]
    ),
    atol=1e-6,
    equal_nan=True,
)

# Exhibit V, Changing Product Mix, column 7
assert np.isclose(actual_ibnr.sum(), 2391084, atol=1e-6)

# Exhibit V, Changing Product Mix, column 8
assert np.allclose(
    difference.values,
    np.array(
        [
            [
                [
                    [0],
                    [0],
                    [0],
                    [0],
                    [0],
                    [0],
                    [15954],
                    [37491],
                    [66327],
                    [104693],
                ]
            ]
        ]
    ),
    atol=1,
    equal_nan=True,
)

# Exhibit V, Changing Product Mix, column 8
assert np.isclose(difference.sum(), 224465, atol=2)