A class and exposure rated CGL model with increased limit factors and a claims load.
Commercial general liability (CGL) covers a business against third-party bodily injury and property damage claims. Premium depends on what the business does, how much of it it does, where it operates and the limit of cover.
Each class code has a rate per $1,000 of exposure, such as payroll or sales. The exposure-based premium is adjusted by a state factor, an increased limit factor (1.00 at a $1m occurrence limit) and a load for prior claims.
A policy fee and a minimum premium are applied. Exposures outside the middle market are declined, and high-hazard classes, claim-heavy accounts and $5m limits are referred.
Three further factors adjust the premium: how long the business has traded, the share of work subcontracted and any products and completed operations exposure.
| Field | Label | Type | Default | Allowed values |
|---|---|---|---|---|
class_code | GL class code | string | offices | offices, retail, contractors_light, contractors_roofing, restaurants, light_manufacturing |
state | State | string | CA | CA, NY, TX, FL, IL |
exposure | Exposure ($) | integer | 500000 | 100000, 500000, 2000000, 10000000 |
occurrence_limit | Per-occurrence limit ($) | integer | 1000000 | 500000, 1000000, 2000000, 5000000 |
prior_claims_3y | Prior GL claims in last 3 years | integer | 0 | 0, 1, 3, 5 |
years_in_business | Years in business | integer | 5 | 1, 3, 5, 10 |
subcontracted_pct | Work subcontracted (%) | integer | 0 | 0, 25, 50, 75 |
products_completed_ops | Products and completed operations | boolean | false | false, true |
Steps run in order. Each one can use the inputs and the outputs of every step before it.
Rate per $1000 exposure and exposure basis by class code. Roofing and restaurants carry the highest loads.
{
"id": "class_gl_rates",
"key": "class_gl_rates",
"step": "collection",
"name": "GL class base rate",
"retain": true,
"collection": [
["class_code", "gl_rate_per_k", "exposure_basis", "high_hazard"],
["offices", 1.1, "payroll", false],
["retail", 2.2, "sales", false],
["contractors_light", 6.5, "payroll", false],
["contractors_roofing", 22, "payroll", true],
["restaurants", 8.4, "sales", false],
["light_manufacturing", 4.8, "payroll", false]
],
"format": {
"gl_rate_per_k": {
"key": "gl_rate_per_k",
"label": "GL rate per $1000 exposure",
"exp": "collection.filter(class_code=={{class_code}}).map(gl_rate_per_k).first()",
"type": "decimal",
"def": 2
},
"class_exposure_basis": {
"key": "class_exposure_basis",
"label": "Exposure basis",
"exp": "collection.filter(class_code=={{class_code}}).map(exposure_basis).first()",
"type": "string",
"def": "payroll"
},
"class_high_hazard": {
"key": "class_high_hazard",
"label": "High-hazard class flag",
"exp": "collection.filter(class_code=={{class_code}}).map(high_hazard).first()",
"type": "boolean",
"def": false
}
}
}State load: plaintiff-friendly and coastal states run higher.
{
"id": "state_gl_rates",
"key": "state_gl_rates",
"step": "collection",
"name": "State GL factor",
"retain": true,
"collection": [
["state", "state_gl_factor"],
["CA", 1.15],
["NY", 1.25],
["TX", 1],
["FL", 1.2],
["IL", 1.05]
],
"format": {
"state_gl_factor": {
"key": "state_gl_factor",
"label": "State GL factor",
"exp": "collection.filter(state=={{state}}).map(state_gl_factor).first()",
"type": "decimal",
"def": 1
}
}
}Standard ILF curve: factor 1.00 at $1m occurrence limit, escalating to $5m.
{
"id": "limit_rates",
"key": "limit_rates",
"step": "collection",
"name": "Increased limits factor",
"retain": true,
"collection": [
["limit_max", "limit_factor"],
[500000, 0.8],
[1000000, 1],
[2000000, 1.35],
[5000000, 1.85]
],
"format": {
"limit_factor": {
"key": "limit_factor",
"label": "Increased limits factor",
"exp": "collection.filter(limit_max>={{occurrence_limit}}).map(limit_factor).first()",
"type": "decimal",
"def": 1
}
}
}Each prior claim in the last 3 years adds 10%, capped at 60%.
{
"id": "claims_load_calc",
"key": "claims_load_calc",
"step": "calculation",
"name": "Claims history load",
"def": 1,
"formula": "min(1 + ({{prior_claims_3y}} * 0.10), 1.60)"
}Established businesses tend to have better processes and fewer claims than new ones.
{
"id": "gl_experience_rates",
"key": "gl_experience_rates",
"step": "collection",
"name": "Years in business factor",
"retain": true,
"collection": [
["years_in_business_min", "years_in_business_max", "gl_experience_factor_rel"],
[0, 2, 1.15],
[3, 4, 1.05],
[5, 9, 1],
[10, 999, 0.95]
],
"format": {
"gl_experience_factor": {
"key": "gl_experience_factor",
"label": "Years in business factor",
"exp": "collection.filter(years_in_business_min<={{years_in_business}}).filter(years_in_business_max>={{years_in_business}}).map(gl_experience_factor_rel).first()",
"type": "decimal",
"def": 1
}
}
}Work done by subcontractors is harder to control and can bring their liability back to the insured.
{
"id": "subcontract_rates",
"key": "subcontract_rates",
"step": "collection",
"name": "Subcontracted work factor",
"retain": true,
"collection": [
["subcontracted_pct_min", "subcontracted_pct_max", "subcontract_factor_rel"],
[0, 10, 1],
[11, 40, 1.08],
[41, 100, 1.18]
],
"format": {
"subcontract_factor": {
"key": "subcontract_factor",
"label": "Subcontracted work factor",
"exp": "collection.filter(subcontracted_pct_min<={{subcontracted_pct}}).filter(subcontracted_pct_max>={{subcontracted_pct}}).map(subcontract_factor_rel).first()",
"type": "decimal",
"def": 1
}
}
}Liability for products sold or work already finished adds exposure after the job is done.
{
"id": "products_rates",
"key": "products_rates",
"step": "collection",
"name": "Products and completed operations factor",
"retain": true,
"collection": [
["products_completed_ops_value", "products_factor_rel"],
[false, 1],
[true, 1.15]
],
"format": {
"products_factor": {
"key": "products_factor",
"label": "Products and completed operations factor",
"exp": "collection.filter(products_completed_ops_value=={{products_completed_ops}}).map(products_factor_rel).first()",
"type": "decimal",
"def": 1
}
}
}Exposure in thousands × class rate × state × limit × claims load. Multiplied by the years in business factor, subcontracted work factor, products and completed operations factor.
{
"id": "base_premium",
"key": "base_premium",
"step": "calculation",
"name": "Base premium",
"def": 0,
"formula": "round(({{exposure}} / 1000) * {{gl_rate_per_k}} * {{state_gl_factor}} * {{limit_factor}} * {{claims_load_calc}} * {{gl_experience_factor}} * {{subcontract_factor}} * {{products_factor}}, 2)"
}Add $150 policy fee. Minimum premium is $500.
{
"id": "policy_premium",
"key": "policy_premium",
"step": "calculation",
"name": "Policy premium",
"def": 0,
"formula": "round(max({{base_premium}} + 150, 500), 2)"
}Decline exposures under $10k or over $50m (outside standard middle-market GL).
{
"id": "gl_exclusions",
"key": "gl_exclusions",
"step": "exclusion",
"name": "General liability exclusions",
"def": false,
"items": [
{
"id": "exposure_too_low",
"name": "Exposure below $10k",
"exp": "{{exposure}} < 10000",
"def": false
},
{
"id": "exposure_too_high",
"name": "Exposure over $50m",
"exp": "{{exposure}} > 50000000",
"def": false
}
]
}Refer high-hazard classes (roofing), claim-heavy accounts, and $5m limits for underwriter review.
{
"id": "gl_refers",
"key": "gl_refers",
"step": "refer",
"name": "General liability refers",
"def": false,
"items": [
{
"id": "high_hazard_class",
"name": "High-hazard class code",
"exp": "{{class_high_hazard}} == true",
"def": false
},
{
"id": "claims_heavy",
"name": "3+ prior claims",
"exp": "{{prior_claims_3y}} >= 3",
"def": false
},
{
"id": "max_limit",
"name": "$5m occurrence limit",
"exp": "{{occurrence_limit}} >= 5000000",
"def": false
}
]
}This quote was priced by the Ptally rating engine. The trace below follows it through every step to the final result.
{
"class_code": "offices",
"state": "CA",
"exposure": 400000,
"occurrence_limit": 1000000,
"prior_claims_3y": 0,
"years_in_business": 12,
"subcontracted_pct": 25,
"products_completed_ops": true
}gl_rate_per_k = 1.1 · class_exposure_basis = "payroll" · class_high_hazard = falsestate_gl_factor = 1.15limit_factor = 1min(1 + (0 * 0.10), 1.60) = 1gl_experience_factor = 0.95subcontract_factor = 1.08products_factor = 1.15round((400,000 / 1000) * 1.1 * 1.15 * 1 * 1 * 0.95 * 1.08 * 1.15, 2) = 597.03round(max(597.03 + 150, 500), 2) = 747.03Exposure below $10k: not firedExposure over $50m: not firedHigh-hazard class code: not fired3+ prior claims: not fired$5m occurrence limit: not firedSelect commercial general liability as the default model for a new project, then change the rates, rules and tests to match your product. Our consultants can do this for you, with no implementation fee.