SigmaField
Mathematical Foundations for Quant Finance
0 of 256 lessons
      1. 2.1.1 Limits: what a function approachesConcept · 25 min
      2. 2.1.2 One-sided limits and continuityConcept · 30 min
      3. 2.1.3 Limits at infinityConcept · 30 min
      4. 2.1.4 Practice set: limitsPractice set · 25 min
      5. 2.1.5 Case study: continuous compounding as a limitCase study · 30 min

Level 2, Single-variable calculus 2.1 Limits and continuity Lesson 5 of 5

Case studyLesson 2.1.5 in Level 2, Single-variable calculus. About 30 minutes.

Case study: continuous compounding as a limit

Continuous compounding is a limit

A yearly rate rr, written as a decimal, paid nn times a year grows $1 to (1+r/n)n(1 + r/n)^n in a year (case study 1.4.6). Continuous compounding is what this approaches as nn grows without end: a limit at infinity, as in lesson 2.1.3.

The limit has the shape lesson 2.1.3 warned about. The base 1+r/n1 + r/n tends to 1 while the power nn grows without end, and the result is neither 1 nor infinite. The two pulls balance at ere^r, just as (1+1/n)n→e(1 + 1/n)^n \to e.

Rule: Continuous compounding

lim⁡n→∞(1+rn)n=er\lim_{n \to \infty} \left(1 + \frac{r}{n}\right)^{n} = e^{r}

The growth of $1 in a year, compounded more and more often, tends to ere^r. Over tt years the same limit gives erte^{rt}.

At 5%, compounding more often climbs towards the continuous value e0.05=1.051271e^{0.05} = 1.051271, quickly at first and then slowly. On $1,000,000 the shortfall falls like about 1,314÷n1{,}314 \div n dollars.

Try it

SymPy computes the limit exactly for any positive rate rr, then the three-year version, (1+r/n)3n→e3r(1 + r/n)^{3n} \to e^{3r}.

n and r are declared positive so SymPy can simplify.

⌘/Ctrl + Enter runs the cell

How fast is the limit reached?

The table shows the gap between continuous and nn-times-a-year compounding, at r=5%r = 5\%, per $1 over a year.

nn1123658760
gap er−(1+r/n)ne^r - (1 + r/n)^n0.00127110.000109200.00000360.00000015
gap × n\times\, n0.00127110.00131040.00131400.0013141

The gap is always positive: compounding nn times a year always falls short of continuous. The last row is the key. The gap times nn settles on a number, about 0.0013141: another limit at infinity.

So for large nn the gap is about 0.0013141n\frac{0.0013141}{n}. Compound ten times as often and the gap shrinks about ten times. That number is r2er2\frac{r^2 e^r}{2}, which is 0.0013141 at 5%; lesson 2.7.2 shows where it comes from.

Rule: Size of the gap

er−(1+rn)n≈r2er2ne^r - \left(1 + \frac{r}{n}\right)^n \approx \frac{r^2 e^r}{2n}

For large nn the gap shrinks like 1n\frac{1}{n}, and it grows with the square of the rate.

Try it

The cell rebuilds the table and compares the last row with r2er2\frac{r^2 e^r}{2}. The table rounds the outputs to 5 significant figures, and the two smallest gaps to 2.

The :.7g format shows 7 significant figures.

⌘/Ctrl + Enter runs the cell
Check yourself
At 5%, roughly how many compounding periods a year bring the gap below one millionth per $1?

What it means in money

On $1,000,000 for a year at 5%, monthly compounding falls $109.20 short of continuous, and daily compounding $3.60 short. For most purposes daily and continuous compounding are interchangeable, which is why models use the simpler erte^{rt}.

The gap grows with the horizon. Over 10 years, monthly compounding on $1,000,000 falls $1,711.77 short of continuous; over 30 years, $13,944.76. A pricing model that says "continuous" while the contract says "monthly" is off by that much.

Try it

The one-year shortfalls from the opening, then the 10- and 30-year shortfalls for monthly compounding, Pert−P(1+r/12)12tP e^{rt} - P(1 + r/12)^{12t}.

The loop finds the smallest nn that brings the one-year gap below one millionth per $1.

⌘/Ctrl + Enter runs the cell

Try other rates and horizons. The gap on $1,000,000 shrinks as compounding gets more frequent, while gap × n\times\, n settles; a higher rate or a longer horizon makes both bigger.

Explore

Compound more often and the growth climbs, but more and more slowly, towards continuous compounding, the dashed line. The axis for n is spaced by powers of 10.

1101001,00010,0001.051.05051.051
Compounded monthly
(1 + 0.05/12)^(12 × 1) = 1.0511619
Continuously
e^(0.05 × 1) = 1.0512711
Gap on $1,000,000.00
$109.20
Gap × n
$1,310.38: it settles as n grows, so the gap shrinks like 1 ÷ n

What goes wrong in practice

The formula is simple; the inputs and the computer are where it fails.

Rates are decimals. Typing 5 for 5% gives e5=148.41e^5 = 148.41 continuously and (1+5/12)12=65.34(1 + 5/12)^{12} = 65.34 monthly: growth factors no deposit could earn. A factor far from 1 for a one-year deposit means the rate went in as a percentage.

Zero and negative rates. At r=0r = 0 every convention gives exactly 1, and the gap is 0. Rates can also be negative: some central banks have set them below zero. The limit still holds, and the gap r2er2n\frac{r^2 e^r}{2n} is still positive because r2r^2 is.

At −0.5%-0.5\%, $1 shrinks to 0.99501248 continuously and to 0.99501144 monthly. Monthly compounding still ends lower, by $1.04 on $1,000,000. The formula does need 1+r/n>01 + r/n > 0: a loss of 100% or more in one period wipes out the balance.

Very large nn breaks the computer. The computer stores about 16 significant digits, so 1+r/n1 + r/n loses most of r/nr/n when nn is huge. Lesson 2.1.1 met the same trap, and here the results go wrong long before nn looks extreme:

nn10610^610810^8101510^{15}
computed gap × n\times\, n0.0014001−0.4336-0.4336about 5×10135 \times 10^{13}

At 10810^8 the computed gap is negative, which is impossible. At 101510^{15}, 1+r/n1 + r/n is stored as exactly 1, so the computed growth is 1: no interest at all.

Two habits avoid this. For continuous compounding, use math.exp(r * t) directly, never a huge nn. For a huge nn, write (1+r/n)n=enln⁡(1+r/n)(1 + r/n)^n = e^{n \ln(1 + r/n)} (lesson 1.4.3) and compute ln⁡(1+z)\ln(1 + z) with math.log1p(z), which stays accurate for tiny zz.

Try it

For each nn the cell prints the gap times nn two ways: from (1 + r / n) ** n, then from math.log1p. The second gives 0.0013141 where the first fails.

At 101510^{15} even the second gap prints 0: a gap of about 10−1810^{-18} is below what 16 digits can show. Use the estimate r2er2n\frac{r^2 e^r}{2n} there. Lesson 2.8.1 returns to rounding.

⌘/Ctrl + Enter runs the cell
Exercise

How often is often enough?

Write two functions.

  1. compounding_gap(r, n) returns er−(1+r/n)ne^r - (1 + r/n)^n.
  2. periods_needed(r, tol) returns the smallest whole nn with compounding_gap(r, n) < tol. Counting up from 1 is fine.

The tests check the gap at a few rates, including zero and a negative rate. They also compare periods_needed with the estimate r2er2 tol\frac{r^2 e^r}{2\,\text{tol}}.

See the tests
import math


def test_annual_gap():
    """At 5% compounded once, the gap is e^0.05 − 1.05"""
    expect_close(compounding_gap(0.05, 1), math.exp(0.05) - 1.05, what="compounding_gap(0.05, 1)")


def test_monthly_gap():
    """At 5% compounded monthly, the gap is about 0.0001092"""
    expect_close(compounding_gap(0.05, 12), 0.00010919849429114059, what="compounding_gap(0.05, 12)", rel=1e-6)


def test_zero_rate():
    """At a zero rate every convention grows $1 to exactly $1, so the gap is 0"""
    expect_close(compounding_gap(0.0, 12), 0.0, what="compounding_gap(0, 12)")


def test_negative_rate():
    """At −2%, monthly compounding still falls short of continuous, by about 0.00001635"""
    expect_close(compounding_gap(-0.02, 12), math.exp(-0.02) - (1 - 0.02 / 12) ** 12, what="compounding_gap(-0.02, 12)", rel=1e-6)
    assert compounding_gap(-0.02, 12) > 0, "the gap should be positive at a negative rate too"


def test_periods_for_one_millionth():
    """At 5%, 1315 periods bring the gap below one millionth"""
    expect_equal(periods_needed(0.05, 1e-6), 1315, what="periods_needed(0.05, 1e-6)")


def test_smallest_n():
    """The answer is the smallest n: one period fewer is not enough"""
    n = periods_needed(0.10, 1e-5)
    assert compounding_gap(0.10, n) < 1e-5, f"gap at your n = {n} is not below 1e-5"
    assert compounding_gap(0.10, n - 1) >= 1e-5, f"n − 1 = {n - 1} already works, so {n} is not the smallest"


def test_close_to_estimate():
    """The answer is close to the estimate r² e^r / (2 tol)"""
    estimate = 0.10**2 * math.exp(0.10) / (2 * 1e-5)
    n = periods_needed(0.10, 1e-5)
    assert abs(n - estimate) / estimate < 0.01, f"expected about {estimate:.0f}, got {n}"

Summary card

  • Continuous compounding is the limit lim⁡n→∞(1+r/n)n=er\lim_{n \to \infty}(1 + r/n)^n = e^r, and over tt years erte^{rt}. The base tends to 1, yet the limit is not 1.
  • The gap to the limit is about r2er2n\frac{r^2 e^r}{2n}: it shrinks like 1n\frac{1}{n}, and nn-times-a-year compounding always falls short, even at negative rates.
  • Daily compounding is within a few dollars per million of continuous over a year; the gap grows with the horizon.
  • Enter rates as decimals. Compute continuous growth with math.exp, and (1+r/n)n(1 + r/n)^n for huge nn with math.log1p; tiny gaps cannot be computed by subtraction.

Free further reading

Optional. This lesson covers what you need; these add more examples and practice. All are free to read.