Business owner's policy (BOP)

A multi-location small business package rating property and liability per location.

A default model in Ptally. Commercial BOP: Multi-Location is one of the default models you can select when you start a new project in Ptally. It comes with its rate tables, rules and 6 tests, ready to adapt to your own product.
The line of business

Business owner's policy (BOP)

A business owner's policy packages property and general liability cover for small and medium businesses into one policy. Many businesses have more than one site, so the model needs to price each location and combine them.

Methodology

How the model rates

A child model prices property and liability for each location. The parent model sums the locations, then applies a business class factor and an experience credit for established businesses, plus a policy fee.

Policies with no locations or more than 10 are declined as outside standard BOP scope. Restaurants, new businesses and policies with four or more locations are referred.

Three further factors adjust the policy premium: recent claims, the security at the premises and the highest flood risk across the locations.

6inputs
9steps
4lookup tables
6tests

Inputs

6 fields
FieldLabelTypeDefaultAllowed values
business_classBusiness classstringofficeoffice, retail, light_manufacturing, restaurant
years_in_businessYears in businessinteger51, 3, 5, 10, 20
locationsLocationsarraylistA list of items, each rated by the child model
claims_3yClaims in the last 3 yearsinteger00, 1, 2, 3
securitySecuritystringstandardnone, standard, monitored_alarm
flood_exposureFlood exposurestringlowlow, medium, high
The model

Step by step

Steps run in order. Each one can use the inputs and the outputs of every step before it.

01Lookup table
Business class factor

Load or discount by business class. Restaurants attract the highest liability load.

{
  "id": "class_rates",
  "key": "class_rates",
  "step": "collection",
  "name": "Business class factor",
  "retain": true,
  "collection": [
    ["business_class", "class_factor"],
    ["office", 0.9],
    ["retail", 1.1],
    ["light_manufacturing", 1.3],
    ["restaurant", 1.55]
  ],
  "format": {
    "class_factor": {
      "key": "class_factor",
      "label": "Business class factor",
      "exp": "collection.filter(business_class=={{business_class}}).map(class_factor).first()",
      "type": "decimal",
      "def": 1
    }
  }
}
02Calculation
Experience credit

Businesses trading 5+ years get up to 15% credit, capped at 20 years.

{
  "id": "experience_calc",
  "key": "experience_calc",
  "step": "calculation",
  "name": "Experience credit",
  "def": 1,
  "formula": "max(1 - (min({{years_in_business}}, 20) - 5) * 0.01, 0.85)"
}
03Modules
Per-location rating

Iterate locations[]. Child model returns each location's property + GL premium; parent sums into a policy total.

Child model: Per-Location Rating (child)

Prices a single BOP location: property (buildings + contents) + general liability.

State rate lookup. Property and GL base rates per $1000 by state.

Property premium. (Building + contents value) in thousands × state property rate.

General liability premium. Annual sales in thousands × state GL rate.

{
  "id": "per_location_rating",
  "key": "per_location_rating",
  "step": "modules",
  "name": "Per-location rating",
  "format": {
    "locations_total": {
      "key": "locations_total",
      "label": "Sum of per-location premiums",
      "exp": "collection.sum(result)",
      "type": "decimal",
      "def": 0
    },
    "locations_count": {
      "key": "locations_count",
      "label": "Number of locations",
      "exp": "collection.count()",
      "type": "integer",
      "def": 0
    }
  },
  "child_model_steps": [
    {
      "id": "state_rates",
      "key": "state_rates",
      "step": "collection",
      "name": "State rate lookup",
      "retain": true,
      "collection": [
        ["state", "state_property_rate", "state_gl_rate"],
        ["CA", 3.2, 0.8],
        ["NY", 3.6, 0.95],
        ["TX", 2.4, 0.6],
        ["FL", 4.5, 0.85],
        ["IL", 2.8, 0.7]
      ],
      "format": {
        "state_property_rate": {
          "key": "state_property_rate",
          "label": "State property rate per $1000",
          "exp": "collection.filter(state=={{state}}).map(state_property_rate).first()",
          "type": "decimal",
          "def": 3
        },
        "state_gl_rate": {
          "key": "state_gl_rate",
          "label": "State GL rate per $1000",
          "exp": "collection.filter(state=={{state}}).map(state_gl_rate).first()",
          "type": "decimal",
          "def": 0.75
        }
      }
    },
    {
      "id": "property_premium",
      "key": "property_premium",
      "step": "calculation",
      "name": "Property premium",
      "def": 0,
      "formula": "round((({{building_value}} + {{contents_value}}) / 1000) * {{state_property_rate}}, 2)"
    },
    {
      "id": "gl_premium",
      "key": "gl_premium",
      "step": "calculation",
      "name": "General liability premium",
      "def": 0,
      "formula": "round(({{sales}} / 1000) * {{state_gl_rate}}, 2)"
    }
  ]
}
04Lookup table
Claims history load

Load for claims in recent years. A clean record is neutral; each band of claims adds a larger load.

{
  "id": "bop_claims_rates",
  "key": "bop_claims_rates",
  "step": "collection",
  "name": "Claims history load",
  "retain": true,
  "collection": [
    ["claims_3y_min", "claims_3y_max", "bop_claims_factor_rel"],
    [0, 0, 1],
    [1, 1, 1.15],
    [2, 2, 1.3],
    [3, 99, 1.5]
  ],
  "format": {
    "bop_claims_factor": {
      "key": "bop_claims_factor",
      "label": "Claims history load",
      "exp": "collection.filter(claims_3y_min<={{claims_3y}}).filter(claims_3y_max>={{claims_3y}}).map(bop_claims_factor_rel).first()",
      "type": "decimal",
      "def": 1
    }
  }
}
05Lookup table
Security factor

Alarms and monitoring reduce theft and fire losses across the business's premises.

{
  "id": "bop_security_rates",
  "key": "bop_security_rates",
  "step": "collection",
  "name": "Security factor",
  "retain": true,
  "collection": [
    ["security_value", "bop_security_factor_rel"],
    ["none", 1.1],
    ["standard", 1],
    ["monitored_alarm", 0.92]
  ],
  "format": {
    "bop_security_factor": {
      "key": "bop_security_factor",
      "label": "Security factor",
      "exp": "collection.filter(security_value=={{security}}).map(bop_security_factor_rel).first()",
      "type": "decimal",
      "def": 1
    }
  }
}
06Lookup table
Flood exposure factor

Locations in higher flood risk areas carry a load for property damage and business interruption.

{
  "id": "bop_flood_rates",
  "key": "bop_flood_rates",
  "step": "collection",
  "name": "Flood exposure factor",
  "retain": true,
  "collection": [
    ["flood_exposure_value", "bop_flood_factor_rel"],
    ["low", 1],
    ["medium", 1.1],
    ["high", 1.3]
  ],
  "format": {
    "bop_flood_factor": {
      "key": "bop_flood_factor",
      "label": "Flood exposure factor",
      "exp": "collection.filter(flood_exposure_value=={{flood_exposure}}).map(bop_flood_factor_rel).first()",
      "type": "decimal",
      "def": 1
    }
  }
}
07Calculation
Policy premium

Sum of per-location premiums × business class factor × experience credit, plus £100 policy fee. Multiplied by the claims history load, security factor, flood exposure factor.

{
  "id": "policy_premium",
  "key": "policy_premium",
  "step": "calculation",
  "name": "Policy premium",
  "def": 0,
  "formula": "round(({{locations_total}} * {{class_factor}} * {{experience_calc}} * {{bop_claims_factor}} * {{bop_security_factor}} * {{bop_flood_factor}}) + 100, 2)"
}
08Decline rules
BOP exclusions

Decline policies with no locations supplied or with more than 10 locations (outside standard BOP scope).

{
  "id": "bop_exclusions",
  "key": "bop_exclusions",
  "step": "exclusion",
  "name": "BOP exclusions",
  "def": false,
  "items": [
    {
      "id": "no_locations",
      "name": "No locations supplied",
      "exp": "{{locations_count}} == 0",
      "def": false
    },
    {
      "id": "too_many_locations",
      "name": "More than 10 locations",
      "exp": "{{locations_count}} > 10",
      "def": false
    }
  ]
}
09Refer rules
BOP refers

Refer restaurants (high liability), new businesses, and multi-site policies with 4+ locations for underwriter review.

{
  "id": "bop_refers",
  "key": "bop_refers",
  "step": "refer",
  "name": "BOP refers",
  "def": false,
  "items": [
    {
      "id": "new_business",
      "name": "New business (<2 years trading)",
      "exp": "{{years_in_business}} < 2",
      "def": false
    },
    {
      "id": "restaurant_class",
      "name": "Restaurant class",
      "exp": "{{business_class}} == 'restaurant'",
      "def": false
    },
    {
      "id": "many_locations",
      "name": "4+ locations",
      "exp": "{{locations_count}} >= 4",
      "def": false
    }
  ]
}
Worked example

Worked example: monitored premises with one claim in a medium flood area

This quote was priced by the Ptally rating engine. The trace below follows it through every step to the final result.

Quote input
{
  "business_class": "office",
  "years_in_business": 8,
  "locations": [
    {
      "state": "CA",
      "building_value": 500000,
      "contents_value": 80000,
      "sales": 750000
    }
  ],
  "claims_3y": 1,
  "security": "monitored_alarm",
  "flood_exposure": "medium"
}
Result2,595.29VALID
Calculation trace
  1. Business class factorLookup table
    class_factor = 0.9
  2. Experience creditCalculation
    max(1 - (min(8, 20) - 5) * 0.01, 0.85) = 0.97
  3. Per-location ratingModules
    Item 1 {"state":"CA","building_value":500000,"contents_value":80000,"sales":750000} → 2,456locations_total = 2,456 · locations_count = 1
  4. Claims history loadLookup table
    bop_claims_factor = 1.15
  5. Security factorLookup table
    bop_security_factor = 0.92
  6. Flood exposure factorLookup table
    bop_flood_factor = 1.1
  7. Policy premiumCalculation
    round((2,456 * 0.9 * 0.97 * 1.15 * 0.92 * 1.1) + 100, 2) = 2,595.29
  8. BOP exclusionsDecline rules
    No locations supplied: not firedMore than 10 locations: not fired
  9. BOP refersRefer rules
    New business (<2 years trading): not firedRestaurant class: not fired4+ locations: not fired
Start from this model

Select business owner's policy (bop) 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.

Talk to our team