Inspectable Arithmetic for the Canada Personal Income Tax Calculator

Version 1.2
Last verified: May 2026

Transparent arithmetic is the operating system of this calculator.

This document publishes the formulae, computational structure, and assumptions used to generate the outputs displayed on the calculator page.

No opinions. No hidden assumptions. Just arithmetic.

Purpose

This calculator estimates combined federal and provincial/territorial personal income tax for the selected tax year (2025 or 2026) in Canada. It models regular income, common investment income types, registered-account deductions, and payroll contributions, then reports total income tax, CPP/EI, average and marginal tax rates, and take-home pay by province or territory.

Definitions

Let:

Core Equations

1. Taxable Income

Dividend gross-up uses CRA-style rates from the internal dividends.json data file. Grossed-up dividends:

Delig,gross = Delig × gelig
Dne,gross = Dne × gne

Taxable capital gains:

Gtaxable = G × rcg

Gross income for tax and net income (T1 lines 15000 → 23600):

GI = E + S + O + Delig,gross + Dne,gross + Gtaxable
NI = max(0, GI − RRRSP − RFHSA − Dest − CPPenh)
TI = NI

RRSP and FHSA are treated purely as deductions against income for the current year; contribution room, over-contribution penalties, and carry-forward rules are not modeled. CPPenh is first additional CPP plus CPP2 (line 22215). EI is credit-only, not deducted from TI.

2. Federal Tax

Federal tax is computed using a standard bracket-and-credit structure derived from CRA parameters for 2025 (stored in federal.json).

Step 1 — bracket tax on TI:

BaseTaxfed = Σbrackets (income in bracket × rate)
(rounded to the nearest dollar per bracket)

Step 2 — non-refundable credits (Schedule 1 style):

Creditsfed = BPAfed × cfed + [CEA × cfed if E > 0] + CPPbase × rCPP/EI,cred + EI × rCPP/EI,cred
TaxAfterCreditsfed = max(0, BaseTaxfed − Creditsfed)

Step 3 — federal dividend tax credit (DTC):

For each dividend type (eligible, non-eligible), the calculator computes a dividend tax credit using an explicit schema (base and rate) from dividends.json. The arithmetic is:

DTCelig,fed = Delig,gross × rDTC,elig,fed
DTCne,fed = Dne,gross × rDTC,ne,fed
DTCfed = DTCelig,fed + DTCne,fed
TaxAfterDTCfed = max(0, TaxAfterCreditsfed − DTCfed)

Step 4 — minimum tax adjustments (not modeled in 2025 engine):

Taxfed = TaxAfterDTCfed

3. Provincial / Territorial Tax

Provincial / territorial tax uses the same taxable income TI but parameters from the selected province or territory in provinces.json. Two flows exist: a generic flow for most provinces and an Ontario-specific flow that mirrors ON428 ordering and arithmetic.

3.1 Generic provinces

For provinces and territories other than Ontario:

  1. Compute base bracket tax on TI using province-specific brackets and rates.
  2. Subtract non-refundable credits (e.g., provincial Basic Personal Amount, using the configured credit rate or the lowest bracket rate).
  3. Apply surtaxes, if any, to tax after credits.
  4. Apply provincial dividend tax credit.
  5. Apply provincial reductions or premiums (if configured).
BaseTaxprov = Σ(income in bracket × rate)
Creditsprov = BPAprov × cprov (and other credits, if configured)
TaxAfterCreditsprov = max(0, BaseTaxprov − Creditsprov)
TaxAfterSurtaxprov = TaxAfterCreditsprov + Surtaxprov
TaxAfterDTCprov = max(0, TaxAfterSurtaxprov − DTCprov)
Taxprov = TaxAfterDTCprov + Premiumsprov

3.2 Ontario-specific flow

Ontario follows ON428 ordering exactly:

  1. Compute base bracket tax on TI.
  2. Subtract Ontario non-refundable credits (Basic Personal Amount, etc.).
  3. Compute surtax on tax after credits (with two tiers).
  4. Add surtax.
  5. Subtract Ontario dividend tax credit.
  6. Add Ontario Health Premium based on TI.
TaxON = max(0, TaxAfterCreditsON + SurtaxON − DTCON) + OHP

4. CPP and EI (annual return, not payroll withholding)

Employee CPP uses CRA YMPE/YAMPE and rates in payroll.json (Schedule 8 / T4), not per-paycheque withholding tables.

CPP1 on earnings up to YMPE:

Pensionable = max(0, min(E, YMPE) − BasicExemption)
CPPbase = min(Pensionable × rbase, MaxBaseCPP) — line 30800 credit
CPP1st add = min(Pensionable × r1st add, MaxFirstAdditionalCPP) — line 22215 deduction
CPP1 = CPPbase + CPP1st add

CPP2 between YMPE and YAMPE:

AdditionalEarnings = max(0, min(E, YAMPE) − YMPE)
CPP2 = min(AdditionalEarnings × rCPP2, MaxCPP2) — line 22215 deduction
CPPenh = CPP1st add + CPP2

Total CPP:

CPP = CPP1 + CPP2 — NI reduced by CPPenh only; credits use CPPbase and EI

EI:

Insurable = min(E, MaxInsurableEarnings)
EI = min(Insurable × rEI, MaxEI)

5. Total Tax, Burden, and Take-Home Pay

Total income tax (federal plus provincial or territorial) before netting against income tax already paid:

Taxtotal = Taxfed + Taxprov

Total tax burden including payroll contributions:

Burdentotal = Taxtotal + CPP + EI

Total income before tax (cash income, including full capital gains amounts before inclusion):

Incomegross = E + S + O + Delig + Dne + G

Take-home pay after income tax and payroll:

ATI = Incomegross − Taxtotal − CPP − EI

Tax balance for income tax only (matches the result card; signed value; CPP and EI are not part of this line):

RIT = Tpaid − Taxtotal

RIT > 0 is shown as Income tax refund; RIT < 0 is shown as Income tax owing (absolute value in the UI). Tpaid is the “Income tax already paid (federal + provincial or territorial only)” input. CPP and EI appear only in Burdentotal and take-home pay, not in RIT.

6. Average and Marginal Tax Rates

Average tax rate (displayed as a percentage):

AvgRate = Taxtotal ÷ Incomegross

Incomegross reflects cash income (including the full capital gain amount before inclusion), not taxable income TI, so the displayed average rate may differ from CRA-style average rates that use taxable income as the denominator.

Marginal tax rate is computed using a $1 perturbation:

  1. Compute baseline: Taxbaseline = Taxtotal(inputs).
  2. Choose an active income type (employment, then dividends, other income, or capital gains) based on which fields are non-zero.
  3. Add $1 to that income type and recompute tax.
MarginalRate = Taxtotal(inputs with +$1 of chosen income) − Taxbaseline

The engine uses unrounded bracket tax (no per-bracket rounding) for the marginal-rate perturbation, so the $1 change is not lost to rounding. If the combined marginal rate falls outside 0–100%, the calculator falls back to the first in-bounds marginal rate for an active income type.

Assumptions and Limitations

  1. Tax year is fixed at 2025; only provinces and territories supported by the underlying data files are available.
  2. RRSP and FHSA inputs are treated strictly as deductions; contribution room, over-contribution penalties, and carry-forward rules are out of scope.
  3. Only common non-refundable credits are modeled (federal BPA, Canada Employment Amount, base CPP and EI credits, provincial BPAs and provincial base CPP/EI where configured, selected credits in data files).
  4. Enhanced CPP (first additional + CPP2) is deducted from net income (line 22215); payroll withholding calculators that do not model the return split may disagree with this calculator.
  5. Additional credits and deductions (medical expenses, tuition, donations, prior-year loss carryforwards, etc.) are not modeled individually; they can be approximated via the “Estimated Additional Deductions” field.
  6. Dividend gross-up and tax credit rates come from federal and provincial data tables for 2025; province-specific nuances beyond the encoded schema are not modeled.
  7. Capital gains use a fixed 50% inclusion rate for 2025 across all provinces.
  8. CPP and EI are modeled from the employee perspective on employment income only, using official annual maximums and rates. Self-employment income is included in income for tax brackets but does not generate CPP or EI in v1 (no Schedule 8 self-employment path). Employer contributions are not included.
  9. Quebec (QPP/QPIP), multiple employers, and Schedule 8 overpayment are out of scope for v1; see docs/SCOPE-v1.md.
  10. Display rounding: Federal and provincial net income tax are each rounded to the nearest dollar for display; total income tax shown is the sum of those two rounded amounts. Internal tests compare unrounded form-trace values.
  11. All amounts are in Canadian dollars; inflation, indexation beyond the configured year, and time value of money are not modeled in this calculator.
  12. All calculations use full floating-point precision internally; rounding occurs only where required to mirror CRA per-bracket rounding and at the display layer.

Implementation Notes

If any discrepancy is identified between this documentation and the calculator output, the arithmetic here governs.

What This Calculator Does Not Include

Sources and References