AggXL Share Financial Modelling Step-By-Step

This step-by-step guide illustrates how an Aggregate Excess of Loss contract type is modelled in Graphene. It assumes a conventional AggXL contract which may or may not have franchise deductible.

Objective

For this guide, the objective is to model a conventional AggXL with the following terms:

Term

Value

Occurrence Limit

30,000 USD

Occurrence Attachment

10,000 USD

Aggregate Limit

50,000 USD

Aggregate Attachment

20,000 USD

Franchise Deductible

10,000 USD

Share

20%

Upfront Premium

3,000 USD

Upfront Brokerage

10%

Inception Date

2019-01-01T00:00:00Z

Expiry Date

2020-01-01T00:00:00Z

We express this contract definition in Graphene’s business model network as a node with the following definition:

{
    "_schema": "AggXL_1.0",
    "inception_date": 1546300800,
    "expiration_date": 1577836800,
    "occurrence_attachment_value": 10000,
    "occurrence_limit_value": 30000,
    "aggregate_attachment_value": 20000,
    "aggregate_limit_value": 50000,
    "franchise_deductible_value": 15000,
    "premium_value": 3000,
    "brokerage": 0.1,
    "share": 0.2,
}

We then use templates to generate the financial model graph for this AggXL definition. This graph is finally evaluated by the Graphene financial engine.

digraph G { graph [ fontname="Courier", fontsize=12, size="20,20"]; node [ shape=rect, fontname="Courier", fontcolor=blue, fontsize=10, margin=0.1]; edge [ fontname="Courier", fontcolor=blue, fontsize=8]; premium [label="_schema: Record_1.0\ltype: \"Premium\"\ltime: 2019-01-01T00:00:00Z\lvalue: 3000\l"]; brokerage [label="_schema: Record_1.0\ltype: \"BrokerageFee\"\ltime: 2019-01-01T00:00:00Z\lvalue: -300\l"]; participation [label="_schema: Scale_1.0\lfactor:0.2\l"]; loss_only [label="_schema: RecordTypeFilter_1.0\loperation: EQUAL\lvalue: Loss\l"]; non_loss [label="_schema: RecordTypeFilter_1.0\loperation: NOT_EQUAL\lvalue: Loss\l"]; time_before [label="_schema: TimeFilter_1.0\loperation:LESS_THAN \lvalue: 2020-01-01T00:00:00Z\l"]; time_after [label="_schema: TimeFilter_1.0\loperation:GREATER_THAN_EQUAL\lvalue: 2019-01-01T00:00:00Z\l"]; occ_attachment [label="_schema: OccurrenceAttachment_1.0\lvalue: 10000\l"]; occ_limit [label="_schema: OccurrenceLimit_1.0\lvalue: 30000\l"]; agg_attachment [label="_schema: AggregateAttachment_1.0\lvalue: 20000\l"]; agg_limit [label="_schema: AggregateLimit_1.0\lvalue: 50000\l"]; franchise_deductible [label="_schema: FranchiseDeductible_1.0\lvalue: 15000\l"]; premium -> participation; brokerage -> participation; time_before -> time_after -> loss_only -> franchise_deductible -> occ_attachment -> occ_limit-> agg_attachment-> agg_limit-> participation; time_after -> non_loss -> participation; }

Step-By-Step Breakdown

In order to better understand the individual elements of the financial model graph illustrated above, let’s decompose the graph into separate components.

Layering of Loss Claims

The primary layering of loss claims is performed in this subgraph:

digraph G { graph [ fontname="Courier", fontsize=12, size="9!,25"]; node [ shape=rect, fontname="Courier", fontcolor=blue, fontsize=10, margin=0.1]; edge [ fontname="Courier", fontcolor=blue, fontsize=8]; participation [label="_schema: Scale_1.0\lfactor:0.2\l"]; loss_only [label="_schema: RecordTypeFilter_1.0\loperation: EQUAL\lvalue: Loss\l"]; time_before [label="_schema: TimeFilter_1.0\loperation:LESS_THAN\lvalue: 2020-01-01T00:00:00Z\l"]; time_after [label="_schema: TimeFilter_1.0\loperation:GREATER_THAN_EQUAL\lvalue: 2019-01-01T00:00:00Z\l"]; occ_attachment [label="_schema: OccurrenceAttachment_1.0\lvalue: 10000\l"]; occ_limit [label="_schema: OccurrenceLimit_1.0\lvalue: 30000\l"]; agg_attachment [label="_schema: AggregateAttachment_1.0\lvalue: 20000\l"]; agg_limit [label="_schema: AggregateLimit_1.0\lvalue: 50000\l"]; franchise_deductible [label="_schema: FranchiseDeductible_1.0\lvalue: 15000\l"]; time_before -> time_after -> loss_only -> franchise_deductible -> occ_attachment -> occ_limit-> agg_attachment-> agg_limit-> participation; }

The graph consists of a number of core operations that are applied to the input Ledger in sequential order:

  1. Do not consider records past the expiry date. Only keep records before the expiry date.

  2. Do not consider records before the inception date. Only keep records on or after the inception date.

  3. For layering only consider losses as subjects. All other records such as upstream premiums or fees are not subject to the layering.

  4. Apply a franchise deductible of 15,000. The franchise deductible is applied to the sum of values of all records with identical Trial, Time, and occurrence key values. If the franchise deductible is not exceeded by the sum of occurrence records, the records of that occurrence are not subject to subsequent terms and are set to zero. On the other hand, if the franchise deductible is exceeded by the sum of occurrence records, the unmodified occurrence records are subject to subsequent terms.

  5. Apply an occurrence attachment of 10,000. The attachment is applied to the sum of values of all records with identical Trial, Time, and occurrence key values. Once the attachment is applied, the result is proportionally allocated to all records included in the group of records that makes up the occurrence.

  6. Apply an occurrence limit of 30,000. The limit is applied to the sum of values of all records with identical Trial, Time, and occurrence key values. Once the limit is applied, the result is proportionally allocated to all records included in the group of records that makes up the occurrence.

  7. Apply an aggregate attachment of 10,000. The attachment is applied to the sum of values of all records with identical Trial. Once the attachment is applied, the result is proportionally allocated to all records included in the group of records that makes up the trial.

  8. Apply an aggregate limit of 50,000. The limit is applied to the sum of values of all records with identical Trial. Once the limit is applied, the result is proportionally allocated to all records included in the group of records that makes up the trial.

  9. Finally we apply the participation using a simple scaling function.

Upfront Premium, Brokerage Fees, Non-loss records

The Aggregate Excess of Loss contract pays an upfront premium income and the insurer must pay a 10% brokerage fee on the premium to the broker.

digraph G { graph [ fontname="Courier", fontsize=12, size="9!,9"]; node [ shape=rect, fontname="Courier", fontcolor=blue, fontsize=10, margin=0.1]; edge [ fontname="Courier", fontcolor=blue, fontsize=8]; premium [label="_schema: Record_1.0\ltype: \"Premium\"\ltime: 2019-01-01T00:00:00Z\lvalue: 3000\l"]; brokerage [label="_schema: Record_1.0\ltype: \"BrokerageFee\"\ltime: 2019-01-01T00:00:00Z\lvalue: -300\l"]; participation [label="_schema: Scale_1.0\lfactor:0.2\l"]; non_loss [label="_schema: RecordTypeFilter_1.0\loperation: NOT_EQUAL\lvalue: Loss\l"]; time_before [label="_schema: TimeFilter_1.0\loperation:LESS_THAN \lvalue: 2020-01-01T00:00:00Z\l"]; time_after [label="_schema: TimeFilter_1.0\loperation:GREATER_THAN_EQUAL\lvalue: 2019-01-01T00:00:00Z\l"]; premium -> participation; brokerage -> participation; time_before -> time_after -> non_loss -> participation; }

  1. The upfront premium is simply a record that is created in the Ledger at the time of contract inception with a value equal to the premium amount and a type of Premium.

  2. Similarly, the brokerage fee on the upfront premium is a record created in the Ledger at the time of contract inception with a negative value equal to 10% of the upfront premium. The value is negative to indicate an expense to the insurer.

  3. Select only records that are not of type Loss and pass them on to apply the contract participation.

Putting it back together

In order to model the complete Aggregate Excess of Loss contract, all components are combined together and collectively produce a single Ledger that contains:

  • A single upfront premium income record on inception of the contract

  • A single brokerage fee expense record on inception of the contract

  • Any loss records that represent a loss expense to the contract

Core operations

The entire Aggregate Excess of Loss contract structure consists of the following core operations:

TimeFilter

RecordTypeFilter

OccurrenceFranchiseDeductible

OccurrenceAttachment

OccurrenceLimit

AggregateAttachment

AggregateLimit

Scale

Record

SetRecordType

Templates

Using Graphene template capabilities, we can build out the appropriate templates to generate the financial model shown above from the initial JSON definition:

{
    "_schema": "AggXL_1.0",
    "inception_date": 1546300800,
    "expiration_date": 1577836800,
    "franchise_deductible_value": 15000,
    "occurrence_attachment_value": 10000,
    "occurrence_limit_value": 30000,
    "aggregate_attachment_value": 20000,
    "aggregate_limit_value": 50000,
    "premium_value": 3000,
    "brokerage": 0.1,
    "share": 0.2,
}

The entire AggXL structure can be modelled using a single template of the following form:

{
    vertices: [
        # Vertex 0
        {
            _schema: "TimeCoverage_1.0",
            inception_date: .inception_date,
            expiration_date: .expiration_date
        },
        # Vertex 1
        {
            _schema: "RecordTypeFilter_1.0",
            op: "EQUAL",
            value: "Loss"
        },
        # Vertex 2
        (
            if .franchise_deductible_value then (
                {
                    _schema: "OccurrenceFranchiseDeductible_1.0",
                    franchise_deductible: .franchise_deductible_value
                }
            ) else {} end
        ),
        # Vertex 3
        {
            _schema: "OccurrenceCoverage_1.0",
            attachment: .occurrence_attachment_value,
            limit: .occurrence_limit_value
        },
        # Vertex 4
        {
            _schema: "AggregateCoverage_1.0",
            attachment: .aggregate_attachment_value,
            limit: .aggregate_limit_value
        },
        # Vertex 5
        {
            _schema: "Record_1.0",
            _internal_terminal: true,
            time: .inception_date,
            type: "BrokerageFee",
            value: (.premium_value * .brokerage * -1.0)
        },
        # Vertex 6
        {
            _schema: "Record_1.0",
            _internal_terminal: true,
            time: .inception_date,
            type: "Premium",
            value: .premium_value
        },
        # Vertex 7
        {
            _schema: "RecordTypeFilter_1.0",
            op: "NOT_EQUAL",
            value: "Loss"
        },
        # Vertex 8
        {
            _schema: "Scale_1.0",
            factor: .share
        }
    ],
    edges: [
        {
            from: 0,
            to: 1
        },
        {
            from: 1,
            to: 2
        },
        {
            from: 2,
            to: 3
        },
        {
            from: 3,
            to: 4
        },
        {
            from: 0,
            to: 7
        },
        {
            from: 4,
            to: 8
        },
        {
            from: 5,
            to: 8
        },
        {
            from: 6,
            to: 8
        },
        {
            from: 7,
            to: 8
        }
    ]
}