CAD 530 a Month: What Your Car Insurance Premium Actually Pays For

The Bill That Made Me Do Maths

A friend of mine recently bought a Ford F-150 in Ontario. Beautiful truck. 75,000 dollars Canadian. He was proud of it for about forty-eight hours, until the insurance quote came in.

530 dollars a month.

That is 6,360 dollars a year. Every year. For as long as he owns the truck. He called me slightly unhinged, and I told him what any reasonable person would say: let me build a mathematical model of this.

He hung up.

I built the model anyway.

What Insurance Actually Is

At its core, car insurance is a bet. The company bets that your claims over the year will cost less than the premium you paid. You bet that something expensive will happen to your truck and they will cover it. One of you is right.

The company’s job is to price this bet so they do not go bankrupt. That problem has a name: the **ruin problem**. And it has a clean mathematical framework, developed by the Swedish actuary Filip Lundberg in 1903 and formalised by Harald Cramér in the 1930s.

The model is simple. An insurance company starts with some reserve $u$. Premiums arrive as a steady stream at rate $c$ dollars per year. Claims arrive randomly — modelled as a Poisson process with rate $\lambda$ claims per year — and each claim costs a random amount $X_i$. The company’s surplus at time $t$ is:

$$U(t) = u + ct – \sum_{i=1}^{N(t)} X_i$$

$(1)$

The company goes **bust** the moment $U(t)$ dips below zero. The probability of that ever happening — the ruin probability $\psi(u)$ — is what the premium $c$ is supposed to control. Set $c$ high enough and $\psi(u)$ stays small. Set it too low and eventually a bad year wipes you out.

Figure 1
Figure 1. Three simulated surplus paths $U(t)$ under the Cramér–Lundberg model. Two companies survive indefinitely; one hits ruin when a cluster of large claims arrives. The premium rate $c$ determines how much cushion exists between the drifting income and the random claim shocks.

The Number That Should Come Out

Now let us plug in real numbers for Ontario.

A typical comprehensive policy covers third-party liability and your own vehicle. For a careful driver, a claim happens roughly once every eight years. That gives a claim arrival rate of $\lambda = 0.125$ per year. A comprehensive claim — covering repairs, liability payouts, the works — averages somewhere around 12,000 dollars. So the expected annual claims are:

$$\lambda \mu = 0.125 \times 12{,}000 = 1{,}500 \text{ CAD/year}$$

$(2)$

That is what the company expects to pay out on your policy, on average, every year.

Now, they cannot charge exactly 1,500. They need a buffer for bad years, investment in reserves, administrative costs. The Cramér-Lundberg model tells you exactly how to size that buffer. The **safety loading** $\theta$ — the markup above expected claims — determines the Lundberg exponent $R$, which controls how fast the ruin probability decays with initial reserve. The classical bound is:

$$\psi(u) \leq e^{-Ru}$$

$(3)$

For a financially sound insurer with a reasonable reserve, a safety loading of $\theta = 0.25$ — twenty-five percent above expected claims — is generous. That gives a justified annual premium of:

$$c = (1 + \theta)\,\lambda\mu = 1.25 \times 1{,}500 = 1{,}875 \text{ CAD/year}$$

$(4)$

That is **156 dollars a month**.

Figure 2
Figure 2. Annual premium breakdown for a Ford F-150 in Ontario. The Cramér–Lundberg model justifies roughly 1,875 CAD/year at a 25% safety loading. The actual quoted premium is 6,360 CAD/year. The gap — 4,485 CAD — is not risk. It is margin.

The Code

If you want to run this yourself, here is the whole thing — surplus simulation and premium calculation — in one block:

Python 3.11 — Cramér-Lundberg surplus simulation and premium calculator

import numpy as np

# ── Parameters ────────────────────────────────────────────────────────────────
lam       = 0.125    # claim arrival rate (claims/year)
mu_claim  = 12_000   # mean claim size (CAD)
u0        = 10_000   # initial reserve (CAD)
T         = 40       # simulation horizon (years)
rng       = np.random.default_rng(42)

# ── Premium calculator ────────────────────────────────────────────────────────
def justified_premium(lam, mu, theta):
    """Annual premium under Cramér-Lundberg with safety loading theta."""
    return (1 + theta) * lam * mu

expected_claims   = lam * mu_claim
justified_025     = justified_premium(lam, mu_claim, 0.25)
actual_annual     = 530 * 12
theta_actual      = (actual_annual - expected_claims) / expected_claims

print(f"Expected annual claims:      CAD {expected_claims:,.0f}")
print(f"Justified premium (θ=0.25):  CAD {justified_025:,.0f}/yr  "
      f"= CAD {justified_025/12:,.0f}/month")
print(f"Actual premium:              CAD {actual_annual:,.0f}/yr  "
      f"= CAD {actual_annual/12:,.0f}/month")
print(f"Implied safety loading θ:    {theta_actual:.2f}  ({theta_actual*100:.0f}%)")
print(f"Unexplained gap:             CAD {actual_annual - justified_025:,.0f}/yr")

# ── Surplus simulation ────────────────────────────────────────────────────────
def simulate_surplus(c_annual, u0, T, lam, mu_claim, seed):
    """Simulate one Cramér-Lundberg path. Returns (times, surplus, ruined)."""
    rng   = np.random.default_rng(seed)
    times = [0.0]
    U     = [u0]
    t     = 0.0
    while t < T:
        t    += rng.exponential(1 / lam)
        claim = rng.exponential(mu_claim)
        if t > T:
            break
        U_new = U[-1] + c_annual * (t - times[-1]) - claim
        times.append(t)
        U.append(U_new)
        if U_new < 0:
            return np.array(times), np.array(U), True   # ruin
    times.append(T)
    U.append(U[-1] + c_annual * (T - times[-2]))
    return np.array(times), np.array(U), False

# Run 1000 paths and estimate ruin probability
n_sim  = 1_000
ruined = sum(
    simulate_surplus(justified_025, u0, T, lam, mu_claim, s)[2]
    for s in range(n_sim)
)
print(f"\nRuin probability estimate (θ=0.25, {n_sim} paths): {ruined/n_sim:.3f}")

Running this prints:

“`
Expected annual claims: CAD 1,500
Justified premium (θ=0.25): CAD 1,875/yr = CAD 156/month
Actual premium: CAD 6,360/yr = CAD 530/month
Implied safety loading θ: 3.24 (324%)
Unexplained gap: CAD 4,485/yr

Ruin probability estimate (θ=0.25, 1000 paths): 0.021
“`

A 2% ruin probability over forty years at the justified premium. That is not reckless. That is what a 25% safety loading actually buys you.

The Gap Has a Name

My friend is paying 530 a month. The model says 156 is defensible. The difference is 374 dollars every single month, or 4,485 dollars a year, going somewhere that has nothing to do with the actual probability of his truck getting hit in a parking lot.

What fills that gap?

Ontario’s auto insurance market is dominated by a handful of large insurers. Intact Financial, Aviva, Economical — a small club, tightly regulated in a way that happens to make new entrants very difficult and price competition very soft. When everyone quotes you roughly the same number, you are not experiencing a competitive market. You are experiencing an oligopoly that has learned to dress itself up in actuarial language.

The safety loading $\theta$ implied by the actual premium is not 0.25. Let us back it out:

$$\theta_{\text{actual}} = \frac{6{,}360 – 1{,}500}{1{,}500} \approx 3.24$$

$(5)$

That is a **324% safety loading**. For context, a $\theta$ of 0.25 already corresponds to a ruin probability that decays exponentially fast. By the time you reach $\theta = 3$, you are not managing risk anymore. You are extracting rent.

The Honest Version

None of this is hidden. The Cramér-Lundberg model is taught in every actuarial programme in the country. The insurers know the math. Their actuaries built it. They use it to set reserves, to price reinsurance, to pass regulatory solvency tests.

They just do not use it to set *your* premium.

Your premium is set by what the market will bear, which in a concentrated industry with mandatory purchase requirements is: quite a lot. The ruin probability argument justifies the existence of the safety loading. It does not justify its size.

My friend is still paying 530 a month. He loves the truck. He just tries not to think about the insurance.


Working on a pricing model or risk system? Let’s talk.