Personal motor

A single-vehicle private car model rated by territory, vehicle group, driver age and no claims discount.

A default model in Ptally. Personal Motor: Single Vehicle 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

Personal motor

Personal motor insurance covers a private car against third-party liability, and usually fire, theft and accidental damage. It is one of the most price-competitive lines in the UK, where most policies are bought on price comparison websites, so the rating model has to be fast, accurate and easy to change.

Methodology

How the model rates

This model uses a multiplicative rating structure. A base rate is looked up by postcode area, then multiplied by relativities for the territory, the ABI vehicle group, the driver's age and the no claims discount.

Driver age is banded in a transform step, because banding is a comparison rather than arithmetic. Under-17 drivers are declined, and high vehicle groups or serious convictions are referred to an underwriter.

Three further factors refine the risk: annual mileage, how the car is used (social, commuting or business) and where it is parked overnight.

8inputs
10steps
5lookup tables
6tests

Inputs

8 fields
FieldLabelTypeDefaultAllowed values
postcode_areaPostcode areastringSWSW, M, EH, B, N
vehicle_groupVehicle groupinteger105, 10, 20, 30, 45
driver_ageDriver ageinteger3017, 21, 25, 40, 60, 75
ncd_yearsNo-claims discount yearsinteger00, 2, 5, 9
convictions_5yConvictions in last 5 yearsinteger00, 1, 3
annual_mileageAnnual mileageinteger80003000, 8000, 12000, 20000
vehicle_useVehicle usestringsocial_commutingsocial_only, social_commuting, business
overnight_parkingOvernight parkingstringdrivewaygarage, driveway, street
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
Territory base rate lookup

Look up base rate and territory band by postcode area. Feeds the premium calculation downstream.

{
  "id": "territory_rates",
  "key": "territory_rates",
  "step": "collection",
  "name": "Territory base rate lookup",
  "retain": true,
  "collection": [
    ["postcode_area", "band", "base_rate", "territory_factor"],
    ["SW", "urban_high", 620, 1.35],
    ["M", "urban_mid", 480, 1.1],
    ["EH", "urban_mid", 460, 1.05],
    ["B", "urban_mid", 490, 1.12],
    ["N", "urban_high", 640, 1.4]
  ],
  "format": {
    "territory_base_rate": {
      "key": "territory_base_rate",
      "label": "Territory base rate",
      "exp": "collection.filter(postcode_area=={{postcode_area}}).map(base_rate).first()",
      "type": "decimal",
      "def": 500
    },
    "territory_factor": {
      "key": "territory_factor",
      "label": "Territory factor",
      "exp": "collection.filter(postcode_area=={{postcode_area}}).map(territory_factor).first()",
      "type": "decimal",
      "def": 1
    },
    "territory_band": {
      "key": "territory_band",
      "label": "Territory band",
      "exp": "collection.filter(postcode_area=={{postcode_area}}).map(band).first()",
      "type": "string",
      "def": "unknown"
    }
  }
}
02Lookup table
Vehicle group factor lookup

Look up a load/discount by ABI vehicle group. Bigger group = higher premium.

{
  "id": "vehicle_rates",
  "key": "vehicle_rates",
  "step": "collection",
  "name": "Vehicle group factor lookup",
  "retain": true,
  "collection": [
    ["group_max", "vehicle_factor"],
    [5, 0.85],
    [15, 1],
    [25, 1.2],
    [35, 1.5],
    [50, 2]
  ],
  "format": {
    "vehicle_factor": {
      "key": "vehicle_factor",
      "label": "Vehicle group factor",
      "exp": "collection.filter(group_max>={{vehicle_group}}).map(vehicle_factor).first()",
      "type": "decimal",
      "def": 1
    }
  }
}
03Transform
Driver age factor

Convert driver age into a rating factor. Young and very old drivers get a load. Banding is a comparison, so it lives in a transform exp (JavaScript); formulas stay arithmetic.

{
  "id": "age_factor",
  "key": "age_factor",
  "step": "transform",
  "name": "Driver age factor",
  "retain": true,
  "format": {
    "age_factor_calc": {
      "key": "age_factor_calc",
      "label": "Driver age factor",
      "exp": "{{driver_age}} < 25 ? 1.6 : {{driver_age}} < 35 ? 1.10 : {{driver_age}} < 65 ? 0.95 : 1.15",
      "type": "decimal",
      "def": 1
    }
  }
}
04Calculation
NCD discount factor

Bigger NCD = larger discount, floored at 0.55.

{
  "id": "ncd_factor_calc",
  "key": "ncd_factor_calc",
  "step": "calculation",
  "name": "NCD discount factor",
  "def": 1,
  "formula": "max(1 - ({{ncd_years}} * 0.05), 0.55)"
}
05Lookup table
Annual mileage factor

More miles means more exposure to accidents. Low mileage earns a credit and high mileage a load.

{
  "id": "mileage_bands",
  "key": "mileage_bands",
  "step": "collection",
  "name": "Annual mileage factor",
  "retain": true,
  "collection": [
    ["annual_mileage_min", "annual_mileage_max", "mileage_factor_rel"],
    [0, 5000, 0.9],
    [5001, 10000, 1],
    [10001, 15000, 1.1],
    [15001, 999999, 1.25]
  ],
  "format": {
    "mileage_factor": {
      "key": "mileage_factor",
      "label": "Annual mileage factor",
      "exp": "collection.filter(annual_mileage_min<={{annual_mileage}}).filter(annual_mileage_max>={{annual_mileage}}).map(mileage_factor_rel).first()",
      "type": "decimal",
      "def": 1
    }
  }
}
06Lookup table
Vehicle use factor

Business use adds time on the road at busy times. Social-only use earns a small credit.

{
  "id": "vehicle_use_rates",
  "key": "vehicle_use_rates",
  "step": "collection",
  "name": "Vehicle use factor",
  "retain": true,
  "collection": [
    ["vehicle_use_value", "vehicle_use_factor_rel"],
    ["social_only", 0.92],
    ["social_commuting", 1],
    ["business", 1.15]
  ],
  "format": {
    "vehicle_use_factor": {
      "key": "vehicle_use_factor",
      "label": "Vehicle use factor",
      "exp": "collection.filter(vehicle_use_value=={{vehicle_use}}).map(vehicle_use_factor_rel).first()",
      "type": "decimal",
      "def": 1
    }
  }
}
07Lookup table
Overnight parking factor

Where the car is kept overnight affects theft and vandalism risk. A locked garage earns a credit.

{
  "id": "parking_rates",
  "key": "parking_rates",
  "step": "collection",
  "name": "Overnight parking factor",
  "retain": true,
  "collection": [
    ["overnight_parking_value", "parking_factor_rel"],
    ["garage", 0.93],
    ["driveway", 1],
    ["street", 1.12]
  ],
  "format": {
    "parking_factor": {
      "key": "parking_factor",
      "label": "Overnight parking factor",
      "exp": "collection.filter(overnight_parking_value=={{overnight_parking}}).map(parking_factor_rel).first()",
      "type": "decimal",
      "def": 1
    }
  }
}
08Calculation
Final premium

Base rate × territory × vehicle × age × NCD, rounded to 2dp. Multiplied by the annual mileage factor, vehicle use factor, overnight parking factor.

{
  "id": "premium",
  "key": "premium",
  "step": "calculation",
  "name": "Final premium",
  "def": 500,
  "formula": "round({{territory_base_rate}} * {{territory_factor}} * {{vehicle_factor}} * {{age_factor_calc}} * {{ncd_factor_calc}} * {{mileage_factor}} * {{vehicle_use_factor}} * {{parking_factor}}, 2)"
}
09Decline rules
Motor exclusions

Decline rules: under-17 drivers cannot be rated.

{
  "id": "motor_exclusions",
  "key": "motor_exclusions",
  "step": "exclusion",
  "name": "Motor exclusions",
  "def": false,
  "items": [
    {
      "id": "under_17",
      "name": "Driver under 17",
      "exp": "{{driver_age}} < 17",
      "def": false
    }
  ]
}
10Refer rules
Motor refers

Refer-to-underwriter rules: high value vehicle group or serious conviction history.

{
  "id": "motor_refers",
  "key": "motor_refers",
  "step": "refer",
  "name": "Motor refers",
  "def": false,
  "items": [
    {
      "id": "high_value_vehicle",
      "name": "High value vehicle",
      "exp": "{{vehicle_group}} > 40",
      "def": false
    },
    {
      "id": "multiple_convictions",
      "name": "Multiple convictions",
      "exp": "{{convictions_5y}} > 1",
      "def": false
    }
  ]
}
Worked example

Worked example: high mileage business driver parked on the street

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

Quote input
{
  "postcode_area": "SW",
  "vehicle_group": 15,
  "driver_age": 21,
  "ncd_years": 0,
  "convictions_5y": 0,
  "annual_mileage": 20000,
  "vehicle_use": "business",
  "overnight_parking": "street"
}
Result2,156.11VALID
Calculation trace
  1. Territory base rate lookupLookup table
    territory_base_rate = 620 · territory_factor = 1.35 · territory_band = "urban_high"
  2. Vehicle group factor lookupLookup table
    vehicle_factor = 1
  3. Driver age factorTransform
    21 < 25 ? 1.6 : 21 < 35 ? 1.10 : 21 < 65 ? 0.95 : 1.15 → 1.6
  4. NCD discount factorCalculation
    max(1 - (0 * 0.05), 0.55) = 1
  5. Annual mileage factorLookup table
    mileage_factor = 1.25
  6. Vehicle use factorLookup table
    vehicle_use_factor = 1.15
  7. Overnight parking factorLookup table
    parking_factor = 1.12
  8. Final premiumCalculation
    round(620 * 1.35 * 1 * 1.6 * 1 * 1.25 * 1.15 * 1.12, 2) = 2,156.11
  9. Motor exclusionsDecline rules
    Driver under 17: not fired
  10. Motor refersRefer rules
    High value vehicle: not firedMultiple convictions: not fired
Start from this model

Select personal motor 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