GIRateEngine — Motor Comprehensive Rating Methodology

How the premium gets calculated

GIRateEngine loads every Motor Comprehensive tariff table into memory once, then prices every quote from Aggregators, the website, POS, and the mobile app entirely in RAM — no database call on the request path. This is the plain-language walkthrough of what it computes today, and an honest map of what's still outstanding.

Basic Premium — implemented & verified Additional Covers & VAT — implemented 2026-07-30 Reflects PremiumCalculation.GetPremium_Comp, reviewed against SPGI_ACIG_GetPremium_Comp_Tameeni, 2026-07-30
01 — Overview

Three pieces make up a quote

A Motor Comprehensive premium is the Basic Premium, minus discounts down to a protected floor, plus whatever Additional Covers the customer selects, plus VAT. GIRateEngine now computes all three pieces.

%%{init: {'theme':'base', 'themeVariables': {'primaryColor':'#e4f0ee','primaryBorderColor':'#0d6b63','primaryTextColor':'#0d6b63','lineColor':'#8a8272','fontFamily':'Georgia, serif','fontSize':'15px'}}}%%
flowchart LR
    A["Basic Premium
tariff + 13 loadings + TPL floor"]:::book --> C{"Discounts +
Minimum-Premium Floor"}:::blend C --> D["NetGross
base policy premium"]:::mid D --> E["+ Additional Covers
priced per eligible cover"]:::book E --> V["+ VAT
flat % per product"]:::book V --> F["Final Premium
what the customer pays"]:::final classDef book fill:#e4f0ee,stroke:#0d6b63,color:#0d6b63,stroke-width:1.5px classDef blend fill:#fdfcf9,stroke:#6b6255,color:#201c16,stroke-width:1.5px classDef mid fill:#fdfcf9,stroke:#6b6255,color:#201c16,stroke-width:1.5px classDef final fill:#201c16,stroke:#201c16,color:#f7f4ec,stroke-width:1.5px
i

"Basic Premium" here means the mandatory base policy cost — third-party + own-damage cover on the vehicle itself. It is not optional. Additional Covers are everything the customer chooses to add on top: Personal Accident benefits, geographic driving extensions, replacement-vehicle cover, and similar.

02 — Basic Premium

The mandatory base premium Implemented

Every quote starts by picking the right tariff row, comparing it against a TPL-only floor, then loading it up by thirteen independent factors — one per rating dimension of the vehicle, the insured, and the policy.

%%{init: {'theme':'base', 'themeVariables': {'primaryColor':'#e4f0ee','primaryBorderColor':'#0d6b63','primaryTextColor':'#0d6b63','lineColor':'#0d6b63','fontFamily':'Georgia, serif','fontSize':'14px'}}}%%
flowchart TD
    S0["Tariff lookup
Policy Type · Product · Scheme · Vehicle Group ·
Usage · Repair Type · Vehicle-Age band · SI band · Region"] S1["Basic Premium = MAX( Rate × SI ÷ 100, TPL-floor premium, Tariff Min Premium )"] S2["× 13 Loadings
Gender · Marital · Ins.Age · Nationality · BodyType · City ·
Profession · Usage · Region · Deductible · RepairType · NCD · SumInsured"] S3["+ Accident/Claims Loading
(only if prior accidents declared)"] S4["= NRP"] S5["÷ (1 − Applicable Loading %)"] S6["= Gross"] S0 --> S1 --> S2 --> S3 --> S4 --> S5 --> S6

Step 1 — Pick the tariff row, then floor it against TPL

The cached Comprehensive tariff set is filtered down to the exact combination of Policy Type, Product, Scheme, Vehicle Group, Usage, Repair Type, the vehicle's age band, its Sum-Insured band, and (if the caller selected one) a specific region — one row survives per deductible option. If no region was pinned by the caller, the engine resolves one from Address / National-ID / Vehicle-Registration region codes, requiring exactly one of the three to repeat before it trusts the result.

Basic Premium
Basic Premium = MAX( Tariff Rate × Sum Insured ÷ 100, TPL Premium × (1 + Min-Premium-Config %), Tariff's own Minimum Premium )

Comparing against a TPL-only floor guarantees a Comprehensive policy is never quoted cheaper than the mandatory Third-Party cover it already includes.

Step 2 — Thirteen loadings build the NRP

Each loading is a percentage of the Basic Premium, looked up independently and summed — not compounded:

LoadingKeyed by
GenderInsured's gender
Marital StatusInsured's marital status
Insured AgeInsured's age band
Vehicle NationalityVehicle's nationality code
Body TypeVehicle body type
Registration CityVehicle registration city
ProfessionInsured's profession/occupation
Use of VehicleDeclared vehicle usage
RegionVehicle registration region
DeductibleSelected deductible band
Repair TypeAgency vs. Non-Agency repair
NCD (as a loading)Claim-free years
Sum InsuredSum-insured band

A fourteenth, conditional loading applies only when the request declares prior accidents: Accident/Claims Loading, keyed by Product, Source Channel (Aggregator/Online/POS), Vehicle Usage, number of claims, and a liability ratio, with the same kind of "closest match, falling back to a wildcard" logic as the other lookups.

NRP & Gross
NRP = Basic Premium + Σ(loading amounts) + Accident Loading amount Gross = NRP ÷ (100 − Applicable Loading %) × 100

"Applicable Loading %" is a single configured gross-up applied to every Comprehensive quote for the product — the equivalent of the Medical engine's combined expense/contingency/profit loading, just collapsed to one number here.

03 — Discounts & the minimum-premium floor

NetGross, protected by a floor Implemented

Seven discount types subtract from Gross. If stacking all of them would push the premium below the scheme's minimum, the engine doesn't just clip the total — it reproduces the SP's own proportional shrink-back algorithm.

DiscountTrigger
No-Claims Discount (NCD)Claim-free years
Scheme, falling back to UserScheme code, or the individual user if the scheme has none
Loyalty (LD)Caller-supplied eligibility flag
DriverCaller-declared: a female driver exists on the policy
PromoCaller-supplied percentage
OtherCaller-supplied percentage
EntityCaller-supplied percentage
!

Several of these — Loyalty, Driver, Promo, Other, Entity — are trusted from the request rather than computed from a lookup the way the SP does it (the SP re-derives Loyalty from an actual prior-policy history check, and aggregator "Other" discounts from an aggregator-specific master table). This is fine as long as every calling channel is independently computing the correct value before it calls the engine — worth confirming with each channel team.

Driver Age top-up

A further loading applies against (Gross − NCD − Loyalty) for young/inexperienced drivers, netted against whatever Insured-Age loading was already applied in §2 so the same risk factor isn't charged twice:

Driver Age top-up
Raw Amount = (Gross − NCD Disc Amt − Loyalty Disc Amt) × Driver-Age Loading % Driver Age Amt = MAX( Raw Amount − Insured-Age Loading Amt already applied, 0 )

Minimum-premium floor — the reverse calculation

If NetGross would fall below the cached minimum premium for this Product / Vehicle Group / Region / Claim-Free-Years combination, the engine doesn't simply raise the price back up. It first checks which discount types are marked non-adjustable for this scheme, then shrinks only the adjustable ones proportionally until the floor is exactly met:

Reverse-calculation (matches the SP's own worked comment, verbatim)
If (Gross − Non-Adjustable Discount Amt) still clears the floor: Max Adjustable Disc Amt = (Gross − Non-Adjustable Disc Amt) − Minimum Premium Adjustment Ratio = Max Adjustable Disc Amt ÷ Total Adjustable Disc % → every adjustable discount % is scaled down by this ratio If even shrinking every adjustable discount to zero isn't enough: Gross += ( Minimum Premium ÷ (100 − Total Disc %) × 100 ) − Gross
i

This is one of the more intricate pieces of the SP, and it's been ported faithfully — the C# even carries the SP's own illustrative comment forward: 800 (Gross) − 450 (Min Premium) = 350 ÷ (20% + 10% + 5%) = 10.

04 — Additional Covers

Optional add-on covers Implemented

Every optional cover a customer can attach to a Comprehensive policy is now priced, checked for eligibility, loaded, and floored — exactly like the Basic Premium above but run a second time per cover, and returned alongside it in the same response.

%%{init: {'theme':'base', 'themeVariables': {'primaryColor':'#f6ecdd','primaryBorderColor':'#a8621a','primaryTextColor':'#a8621a','lineColor':'#a8621a','fontFamily':'Georgia, serif','fontSize':'14px'}}}%%
flowchart TD
    A1["Customer selects one or more Additional Covers"]
    A2["Eligibility filter
Make · Model · Vehicle-Age · Deductible-band · Business-Type"] A3["Rate lookup, per cover
Fixed amount / per-seat —or— rated by Region×BodyType×Nationality×
VehicleGroup×Usage×Deductible×InsuredAge×ManufactureYear"] A4["Re-run applicable loadings
(cover-specific subset of the same 13-factor chain)"] A5["Cover's own minimum premium, then VAT"] A6["= price for this cover"] A1 --> A2 --> A3 --> A4 --> A5 --> A6

What's priced, for Comprehensive

CoverPricing shape
Personal Accident — DriverRated per policy, own loading chain
Personal Accident — PassengersRated per seat (seating capacity × rate)
Zero Depreciation — Total Loss% of Gross, vehicle-age gated
Zero Depreciation — Partial Loss% of Gross, vehicle-age gated
Admin Fee and similar Fixed-rate coversFlat fee per policy

Excluded by design: Geographical Extension covers (GCC/Bahrain/Egypt) and Replacement Vehicle — see the callout below for why.

Why this was more than "one more lookup table"

Three things made this a second pipeline rather than a quick add — all three are now handled:

ComplicationHow it's handled
Two pricing mechanismsSome covers are a flat/per-seat "Fixed" rate; others are "Applicable at Cover level" — rated from an 8-dimension lookup table (region, body type, nationality, vehicle group, usage, deductible band, insured-age band, manufacture-year band). Both are cached and priced.
Per-vehicle eligibility rulesA separate whitelist table can restrict specific covers to specific Make/Model/Vehicle-Age/Deductible-band/Business-Type combinations — checked before a non-mandatory cover is offered.
The loading chain runs againEach cover has its own data-driven map of which of the 13 loadings actually apply to it. The engine reuses the percentages already computed for the Basic Premium rather than re-querying — verified this map is currently empty for all Motor Comp products, so it's a correct no-op today.
i

Deliberately excluded, matching what production's live quote flow actually exercises (not what it theoretically supports): geographic-extension covers (Bahrain/Egypt/GCC/Other) and Replacement Cover — the reference SP always calls its additional-covers logic with no geographic-extension period selected, and its own Replacement Cover block is commented out in production. Sourced via 6 new stored procedures added to Acig_Limra_Db, following the same _RateEngine naming convention as the 8 already wired into MastersCache.

05 — Other known differences

Found while reviewing the SP Mixed

Additional Covers and VAT (§4, and the reference table below) are now closed. Comparing the engine line-by-line against the production SP surfaced five more differences — none as large, but worth a deliberate decision before or shortly after go-live.

GapDirection of errorNotes
Comprehensive premium CAPOverstated (if activated)Ceiling on Basic Premium by make/model/region/etc. Currently zero active rows in production — dormant, but live code in the SP.
Minimum-premium keyingUnderstated (edge cases)Engine keys on Product/Vehicle-Group/Region/Claim-Years only; the SP also keys on Policy Type, Make, Model, Nationality, Manufacture Year, Repair Type.
Cross-Sell & Multi-Vehicle DiscountOverstated (discount withheld)Both require a live per-customer "how many existing policies" lookup — structurally in tension with a pure in-memory cache. See Project Details.md §5.4 for options.
Motor Scheme Discount capUnderstatedA per-scheme ceiling on total stacked discount % is not enforced — a customer stacking several discounts could be quoted below what the scheme actually allows.
Region resolutionCould pick wrong tariff rowThe SP's algorithm is materially richer (aggregator vs. non-aggregator branches, majority-vote across three region codes); the engine only handles the single-duplicate case.

Full detail, verbatim SQL references, and a phased remediation plan for each of these live in Project Details.md.

06 — Worked example

Basic Premium, start to finish

Illustrative figures at realistic Saudi Comprehensive magnitude — not real master data. Shown here is the Basic Premium chain through VAT; Additional Covers are priced separately per eligible cover and returned alongside this total (see §4).

Private car · Sum Insured 90,000 SAR · 5 claim-free years · Agency repair
Tariff Rate         = 6.24% of Sum Insured  →  90,000 × 6.24 / 100        = 5,616.00
TPL-floor premium   = 1,180 × 1.05 (min-premium config)                   =  1,239.00
Tariff Min Premium                                                        =  4,200.00
Basic Premium = MAX(5,616.00, 1,239.00, 4,200.00)                         =  5,616.00

Loadings on Basic Premium (5,616.00):
  Marital Status  +8%  →  449.28        Insured Age    +5%  →  280.80
  Repair Type    +11%  →  617.76        Region          +3%  →  168.48
  Deductible      +4%  →  224.64        NCD (loading)   -2%  → -112.32
  (all other loadings 0% for this profile)
Σ Loadings                                                                =  1,628.64

NRP = 5,616.00 + 1,628.64                                                 =  7,244.64
Applicable Loading % = 12%
Gross = 7,244.64 ÷ (100 − 12) × 100                                       =  8,232.55

Discounts on Gross (8,232.55):
  NCD Discount   -20%  → -1,646.51      Scheme Discount  -5%  →  -411.63
NetGross = 8,232.55 − 1,646.51 − 411.63                                   =  6,174.41

Minimum-Premium check: floor for this Product/Group/Region/NCD = 5,900.00
NetGross (6,174.41) already clears the floor → no reverse-calculation needed

VAT (flat 15%) = 6,174.41 × 15%                                           =    926.16
Final Basic Premium incl. VAT                                             =  7,100.57
07 — Reference

Formula reference

StageFormulaStatus
Basic PremiumMAX(Rate × SI ÷ 100, TPL-floor × (1+MinCfg%), Tariff Min Premium)Live
NRPBasic Premium + Σ(13 loadings) + Accident LoadingLive
GrossNRP ÷ (100 − Applicable Loading %) × 100Live
NetGrossGross − (NCD + Scheme/User + Loyalty + Driver + Promo + Other + Entity)Live
Driver Age top-upMAX((Gross−NCD−LD) × DriverAge% − InsAgeLoadingAmt, 0)Live
Minimum-premium floorShrink adjustable discounts proportionally, else gross back upLive
VATNetGross × VAT% (flat 15% today)Live
Comprehensive CAPMIN(Basic Premium, CAP amount or % of SI)Missing
(dormant in prod)
Additional CoversPer-cover: eligibility → rate → loadings → min premium → VATLive
Cross-Sell / Multi-Vehicle DiscountNeeds live per-customer existing-policy lookupMissing
Motor Scheme Discount capClip total stacked discount % to the scheme's ceilingMissing