npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

canadian-mortgage-math-engine

v1.0.1

Published

Open-source reference and TypeScript engine for Canadian mortgage qualification, OSFI B-20 stress-test, and semi-annual compounding math.

Readme

Canadian Mortgage & Financial Math Engine 🇨🇦

License: MIT TypeScript Live Repo Interactive Calculators

An open-source reference, mathematical specification, and TypeScript implementation of official Canadian lending, mortgage qualification, and taxation formulas. Includes Bank of Canada / OSFI B-20 stress-test rules, semi-annual compounding equations, GDS/TDS limits, and provincial tax brackets.


📌 Why This Exists

Most mortgage and finance calculators on the internet default to US lending standards (monthly compounding). In Canada, federal lending laws mandate semi-annual compounding for fixed-rate mortgages, and OSFI B-20 enforces strict qualifying stress tests.

Using US formulas for Canadian mortgages causes errors in amortization schedules, payment amounts, and debt-service ratios. This repository serves as the transparent, open-source mathematical reference for developers, financial analysts, and mortgage professionals.

🚨 The Hidden $4,479 Calculation Error

Here is what happens when software calculates a typical Canadian home loan using standard US monthly compounding instead of statutory Canadian compounding:

| Scenario: $500,000 Loan @ 5.00% (25-Yr Amortization) | US Monthly Compounding (Default Web Code) | Canadian Semi-Annual Compounding (Interest Act Legal) | Discrepancy / Phantom Error | | :--- | :--- | :--- | :--- | | Monthly Payment | $2,922.95 | $2,908.02 | +$14.93 / month | | Total Paid (25 Years) | $876,885.00 | $872,406.00 | +$4,479.00 CAD | | Total Interest Paid | $376,885.00 | $372,406.00 | +$4,479.00 CAD |

A difference of $14.93/month might seem negligible, but over a standard 25-year amortization it miscalculates mortgage debt by nearly $4,500 CAD. Using American mortgage math on Canadian loans distorts debt-service calculations, misleads borrowers comparing bank offers, and miscalculates qualification thresholds.

Need an interactive browser tool? Test these formulas with visual charts and amortization schedules on UseCOS Canadian Mortgage Calculator and the Mortgage Renewal Offer Analyzer.


📐 1. Canadian Mortgage Compounding Formula

Under Canadian federal law (Interest Act, Section 6), interest on mortgages must be quoted on a semi-annual or annual compounding basis. Fixed-rate Canadian mortgages compound semi-annually, not in advance.

Mathematical Derivation

To calculate the monthly payment from an annual nominal rate $r$:

  1. Semi-Annual Compounding Factor: $$f = 1 + \frac{r}{2}$$

  2. Effective Monthly Interest Rate ($i$): $$i = \left(1 + \frac{r}{2}\right)^{\frac{2}{12}} - 1 = \left(1 + \frac{r}{2}\right)^{\frac{1}{6}} - 1$$

  3. Monthly Payment ($P$): Given loan principal $L$ and total amortization months $n$: $$P = L \times \frac{i \times (1 + i)^n}{(1 + i)^n - 1}$$

TypeScript Implementation

/**
 * Calculates monthly mortgage payment using Canadian semi-annual compounding.
 * @param principal Loan amount in CAD ($)
 * @param annualRate Nominal annual interest rate as percentage (e.g. 4.79 for 4.79%)
 * @param amortizationYears Total amortization period in years (e.g. 25)
 */
export function calculateCanadianMonthlyPayment(
  principal: number,
  annualRate: number,
  amortizationYears: number
): number {
  if (principal <= 0 || amortizationYears <= 0) return 0;
  if (annualRate === 0) return principal / (amortizationYears * 12);

  const r = annualRate / 100;
  // Canadian Semi-Annual Compounding to Monthly Equivalent
  const monthlyRate = Math.pow(1 + r / 2, 2 / 12) - 1;
  const totalMonths = amortizationYears * 12;

  const payment =
    (principal * (monthlyRate * Math.pow(1 + monthlyRate, totalMonths))) /
    (Math.pow(1 + monthlyRate, totalMonths) - 1);

  return Math.round(payment * 100) / 100;
}

// Example Test Vector:
// $500,000 principal at 5.00% for 25 years
// Result: $2,908.02 CAD / month

🛡️ 2. OSFI Guideline B-20 Stress Test (Qualification Rate)

Federal regulation requires federally regulated financial institutions (FRFIs) to qualify uninsured and insured borrowers at the higher of:

  1. The contract mortgage interest rate $+ 2.00%$
  2. The minimum qualifying rate (floor set by OSFI / BoC, currently $5.25%$)

$$r_{\text{qualify}} = \max(r_{\text{contract}} + 2.00%, 5.25%)$$

Debt Service Caps

| Ratio | Cap (Standard) | Cap (Exceptional / Strong Credit) | Formula | | :--- | :--- | :--- | :--- | | GDS (Gross Debt Service) | 39.0% | 39.0% | $\frac{\text{Principal} + \text{Interest} + \text{Property Tax} + \text{Heating} + 50%\text{Condo Fees}}{\text{Gross Annual Income}} \times 100$ | | TDS (Total Debt Service) | 44.0% | 44.0% | $\frac{\text{Housing Costs} + \text{Credit Cards} + \text{Auto Loans} + \text{Other Debts}}{\text{Gross Annual Income}} \times 100$ |

TypeScript Implementation

export function getQualifyingStressRate(contractRate: number): number {
  const OSFI_FLOOR = 5.25;
  return Math.max(contractRate + 2.0, OSFI_FLOOR);
}

export function checkDebtServiceQualification(params: {
  grossAnnualIncome: number;
  monthlyPITI: number;       // Stress-tested Principal + Interest + Property Tax + Heating
  monthlyOtherDebts: number;  // Car payments, student loans, credit lines
}): { gds: number; tds: number; qualifies: boolean } {
  const grossMonthly = params.grossAnnualIncome / 12;
  const gds = (params.monthlyPITI / grossMonthly) * 100;
  const tds = ((params.monthlyPITI + params.monthlyOtherDebts) / grossMonthly) * 100;

  return {
    gds: Math.round(gds * 10) / 10,
    tds: Math.round(tds * 10) / 10,
    qualifies: gds <= 39.0 && tds <= 44.0
  };
}

🔄 3. Mortgage Renewal "Break-Even" & Net Advantage

When a borrower renews or switches lenders, comparing headline interest rates is misleading because lenders charge transfer fees, appraisal costs, or offer cashback bonuses.

True Term Net Cost Equation

$$\text{Net Term Advantage} = (\text{Cost}{\text{Current}} - \text{Cost}{\text{Offer}}) + \text{Cashback} - (\text{Discharge Fee} + \text{Appraisal Fee} + \text{Title Fee})$$

For an interactive comparison of total cost across 3-year and 5-year terms, run your renewal statement through the UseCOS Renewal Offer Grader.


📊 4. Canadian 2026 Federal Tax Brackets

Federal tax brackets indexed for inflation for the 2026 tax year:

| Federal Tax Bracket | Tax Rate | Cumulative Tax at Base | | :--- | :--- | :--- | | $0 to $57,375 | 15.0% | $0.00 | | $57,376 to $114,750 | 20.5% | $8,606.25 | | $114,751 to $177,882 | 26.0% | $20,368.13 | | $177,883 to $253,414 | 29.0% | $36,782.45 | | Over $253,414 | 33.0% | $58,686.73 |

Basic Personal Amount (BPA): Federal maximum $16,129 with phase-out above $177,882.


🛠️ Interactive Tools & Reference Suite

All algorithms in this repository are actively maintained and powering the open browser utilities on UseCOS:


📄 License & Contributing

Licensed under the MIT License. Contributions, bug reports, and updates for annual federal/provincial rate indexation are welcome via GitHub Pull Requests.