Time Value of Money & Interest Rates: Finance Fundamentals

Michael BrenndoerferUpdated February 6, 202652 min read

Covers time value of money concepts: compounding, discounting, present value, annuities, and interest rate conventions essential for quantitative finance.

Quantitative FinanceAll chapters
Part 1 of 15Mathematical Foundations
Chapter 1Time Value of Money and Interest Rates
Reading the full chapter · 9 sections · 52 min9 sections · 52 min

All 9 sections · 52 min read

Time Value of Money and Interest RatesFull chapter · Sections in this chapter1 / 9 ↓
Reading tools Definitions, links & notes

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Article links

Make inline references clickable

Notes & comments

Time Value of Money and Interest Rates

When the applicable discount rate is positive and the cash flows are otherwise comparable, a dollar today is worth more than a dollar tomorrow. This ordering connects calculations used to price bonds, value companies, structure mortgages, and plan for retirement. The concept is called the time value of money (TVM), and it is a recurring foundation in quantitative finance.

Why can money be worth more today? An investment opportunity creates an opportunity cost for waiting. Expected inflation can reduce future purchasing power, and uncertainty can make a promised payment less valuable than an otherwise comparable certain payment. The applicable discount rate should reflect whichever of these considerations belong to the cash flow being valued; they are not universal simultaneous causes, and zero or negative rates can change the ordering.

The time value of money gives us a framework for comparing cash flows that occur at different points in time. Without this framework, how would you choose between receiving $1,000 today versus $1,100 in one year? Or evaluate a business that requires $1 million upfront but promises $200,000 annually for the next seven years? TVM provides the mathematical machinery to answer these questions rigorously.

Interest rates are the mechanism that links present and future values. They quantify the "price" of borrowing money or the "reward" for lending it. In quantitative finance, discount rates are central to debt securities, discounted-cash-flow valuations, and interest-rate-sensitive derivatives. Understanding how rates work, how they compound, and how they are quoted across markets is knowledge that we will use throughout this book.

Future Value and Compounding

With a positive interest rate and no withdrawals or offsetting fees, an interest-bearing deposit grows over time. Compounding adds earned interest to the balance so that it can earn interest in later periods. The same mechanism can increase an unpaid debt. We will build from simple interest to the continuous limit used in derivatives pricing.

Simple Interest

Simple interest is the most basic form of interest calculation and is our conceptual starting point. Under simple interest, the interest accrues only on the original principal amount, never on accumulated interest. Think of it as a linear process: each period adds the same fixed amount of interest, regardless of how much has accumulated before. If you invest a principal PP at an annual interest rate rr for tt years, the future value is:

FV=P(1+rt)FV = P(1 + rt)

where:

  • FVFV: future value of the investment
  • PP: principal amount (initial investment)
  • rr: annual interest rate (expressed as a decimal)
  • tt: time in years

The structure of this formula reveals its linear nature. The term rtrt represents the total proportional increase: the rate rr multiplied by time tt. When you add this to 1 (representing the original principal as 100%), you get the total growth factor. Multiplying by PP then scales this to your actual investment amount. Notice that time and rate enter symmetrically through their product, which is then added to 1. Doubling the time has exactly the same effect as doubling the rate.

Simple Interest

Simple interest is calculated only on the original principal amount. The interest earned each period remains constant regardless of how long the investment is held.

For example, investing $1,000 at 5% simple interest for 3 years yields:

PythonIn [3]
CollapseExpand
# Simple interest calculation
P = 1000  # Principal
r = 0.05  # Annual interest rate
t = 3  # Time in years

FV_simple = P * (1 + r * t)
interest_earned = FV_simple - P
ConsoleOut [4]
CollapseExpand
Principal: $1,000.00
Future value: $1,150.00
Interest earned: $150.00

Notice that the interest earned ($150) equals the annual interest ($50) multiplied by the number of years (3). Simple interest grows linearly with time because this convention deliberately excludes interest on accumulated interest. Many products instead use periodic compounding, which we turn to next.

Discrete Compounding

Under periodic compounding, each period's interest is added to the balance before the next period's interest is calculated. At a constant positive rate, with interest reinvested and no other balance changes, your original investment and its accumulated interest both earn returns. The balance then grows exponentially rather than linearly. At zero interest the balance stays constant; an admissible negative rate reduces it.

To understand this exponential behavior, consider what happens period by period. After the first compounding period, your balance is P(1+r/n)P(1 + r/n). After the second period, interest is calculated on that updated balance, giving P(1+r/n)(1+r/n)=P(1+r/n)2P(1 + r/n)(1 + r/n) = P(1 + r/n)^2. Each period multiplies the previous balance by the same factor. A factor greater than one produces growth; a positive factor below one produces decay.

For an investment compounding nn times per year at annual rate rr, the future value after tt years is:

FV=P(1+rn)ntFV = P\left(1 + \frac{r}{n}\right)^{nt}

where:

  • FVFV: future value after tt years
  • PP: principal amount invested
  • rr: nominal annual interest rate (stated rate)
  • nn: number of compounding periods per year
  • tt: time in years
  • (1+r/n)(1 + r/n): growth factor per compounding period
  • ntnt: total number of compounding periods

Here nn must be positive and the per-period growth factor 1+r/n1+r/n must remain positive when the exponent ntnt is not an integer. The product ntnt measures the number of compounding periods; contracts that accrue only over completed periods need an integer period count or an explicit stub-period rule. These domain conditions are usually implicit in ordinary deposit and loan examples, but they matter when rates can be negative or time includes a fractional period.

The formula captures a key insight: each compounding period applies a growth factor (1+r/n)(1 + r/n), and these compound multiplicatively over ntnt total periods. The rate per period is r/nr/n because we divide the nominal annual rate among nn periods, and the total number of periods is ntnt because we have nn periods per year for tt years. With a positive nominal rate, positive principal, and positive horizon held fixed, more frequent compounding increases future value. The size of this increase depends on those parameters. Interest added to the balance earlier can itself earn interest over more of the remaining horizon.

Compound Interest

Compound interest calculates interest on both the initial principal and previously accumulated interest. With a constant positive rate, reinvestment, and no other balance changes, the balance grows exponentially and the interest earned per period increases.

Let's compare different compounding frequencies for the same nominal rate:

PythonIn [5]
CollapseExpand
P = 1000
r = 0.05
t = 3

# Different compounding frequencies
compounding = {
    "Annual (n=1)": 1,
    "Semi-annual (n=2)": 2,
    "Quarterly (n=4)": 4,
    "Monthly (n=12)": 12,
    "Daily (n=365)": 365,
}

results = {}
for name, n in compounding.items():
    FV = P * (1 + r / n) ** (n * t)
    results[name] = FV
ConsoleOut [6]
CollapseExpand
Principal: $1,000.00 | Rate: 5.0% | Time: 3 years

Compounding Frequency     Future Value Extra vs Annual
-------------------------------------------------------
Annual (n=1)              $  1,157.63 $          0.00
Semi-annual (n=2)         $  1,159.69 $          2.07
Quarterly (n=4)           $  1,160.75 $          3.13
Monthly (n=12)            $  1,161.47 $          3.85
Daily (n=365)             $  1,161.82 $          4.20

For the parameters in this example, future value grows as compounding frequency increases, but the incremental gains diminish. Moving from annual to semi-annual compounding adds about $2.07, while moving from monthly to daily adds about $0.35. These values approach a finite limit as n→∞n \to \infty, with the nominal rate, principal, and horizon held fixed. This limit forms the basis for continuous compounding, a common convention in continuous-time derivatives models.

VisualizationOut [7]
CollapseExpand
Line chart showing future value increasing with compounding frequency but converging to a horizontal asymptote.
Future value convergence as compounding frequency increases for $1,000 at a 5% nominal rate over three years. The curve approaches the continuous compounding limit (dashed line). In this example, increasing frequency beyond monthly adds less than $0.37 to future value.

Continuous Compounding

Taking the limit as the compounding frequency approaches infinity gives us continuous compounding. Rather than compounding at discrete intervals like monthly, daily, or even every second, continuous compounding assumes that interest accrues and is reinvested at every instant. It is a common mathematical convention in continuous-time derivatives models because exponential growth factors compose cleanly across time.

The continuous compounding formula emerges from taking the limit of the discrete formula as nn grows without bound:

FV=lim⁡n→∞P(1+rn)nt=PertFV = \lim_{n \to \infty} P\left(1 + \frac{r}{n}\right)^{nt} = Pe^{rt}

where:

  • FVFV: future value
  • PP: principal amount
  • rr: continuously compounded annual rate
  • tt: time in years
  • ee: Euler's number (≈2.71828\approx 2.71828)

This result relies on the fundamental limit lim⁡n→∞(1+x/n)n=ex\lim_{n \to \infty}(1 + x/n)^n = e^x, one of the most important limits in mathematics. To see why this limit makes sense intuitively, consider that as nn increases, each individual growth factor (1+r/n)(1 + r/n) gets closer to 1, but you apply more and more of them. These two effects, smaller factors applied more times, balance out to give a finite limit, and that limit happens to be the exponential function.

The exponential function erte^{rt} emerges naturally because continuous compounding represents the limiting case of infinitely many infinitesimally small growth events. This makes continuous compounding mathematically convenient: returns become additive in the logarithm, meaning ln⁡(FV/P)=rt\ln(FV/P) = rt. This logarithmic property greatly simplifies many calculations in derivatives pricing, because the return over multiple periods can be computed simply by adding up the returns over sub-periods, rather than multiplying growth factors together.

Continuous Compounding

Continuous compounding assumes interest accrues and compounds instantaneously at every moment. The future value is calculated as FV=PertFV = Pe^{rt}, where ee is Euler's number.

PythonIn [8]
CollapseExpand
import numpy as np

# Parameters
P = 1000
r = 0.05
t = 3

# Continuous compounding
FV_continuous = P * np.exp(r * t)

# Compare to discrete compounding
FV_daily = P * (1 + r / 365) ** (365 * t)
difference = FV_continuous - FV_daily
ConsoleOut [9]
CollapseExpand
Continuous compounding: $1,161.8342
Daily compounding:      $1,161.8223
Difference:             $0.0119

For this rate and horizon, the difference between daily and continuous compounding is negligible. Continuous compounding also has useful mathematical properties: log returns become additive because the log of a product equals the sum of logs. The balance V(t)=PertV(t)=Pe^{rt} also satisfies dV/dt=rVdV/dt=rV, which gives a direct bridge between the compounding formula and the constant-rate differential equation.

Let's visualize how future value grows under different compounding schemes:

VisualizationOut [10]
CollapseExpand
Line chart comparing simple interest, smooth effective-annual-rate interpolation, and continuous compounding over 10 years.
Growth of $1,000 over 10 years at 5% interest under simple, annually compounded, and continuous conventions. The smooth annual curve uses the effective-annual-rate interpolation $(1+r)^t$ between integer years; a contract may instead specify completed periods or a stub rule.

The chart reveals that simple interest grows linearly while compound interest grows exponentially. Over short horizons, the differences are small. Over long horizons, they become dramatic. This explains why compound interest accumulates so powerfully over time.

Present Value and Discounting

While future value answers "what will this be worth later?", present value addresses the inverse question: "what is a future payment worth today?" Pricing a bond, evaluating an investment project, and calculating how much to invest today for a future retirement payment all involve present value calculations.

The Discounting Process

Discounting is the reverse of compounding. If compounding moves money forward in time by multiplying by growth factors, discounting moves money backward in time by dividing by those same factors. Algebraically, we unwrap the future value formula to find the present value:

PV=FV(1+r)tPV = \frac{FV}{(1 + r)^t}

where:

  • PVPV: present value (value today)
  • FVFV: future value (amount to be received)
  • rr: effective annual discount rate
  • tt: time until payment (years)
  • (1+r)−t(1 + r)^{-t}: the discount factor

Use r>−1r>-1 so the annual growth factor is positive. For fractional years, this expression uses the effective-annual-rate interpolation; a contract may instead specify completed periods or a stub-period rule.

The discount factor (1+r)−t(1 + r)^{-t} answers a simple question: what fraction of a future dollar is worth today? For a positive interest rate and a strictly positive horizon, this fraction is less than one, which reflects the fundamental principle that a dollar today is worth more than a dollar tomorrow. Holding the other variable fixed, a higher discount rate or longer horizon produces a smaller discount factor. Distant or heavily discounted cash flows then contribute less to present value.

For continuous compounding, the discounting formula takes an even more elegant form:

PV=FV⋅e−rtPV = FV \cdot e^{-rt}

where:

  • PVPV: present value
  • FVFV: future value
  • rr: continuously compounded discount rate
  • tt: time in years
  • e−rte^{-rt}: the continuous discount factor, strictly between 0 and 1 when r>0r>0 and t>0t>0, and equal to 1 at t=0t=0

The negative exponent in e−rte^{-rt} reflects that we are reversing the compounding process. Just as erte^{rt} grows money forward in time by a factor that increases with time, e−rte^{-rt} shrinks it backward by a factor that decreases with time. The symmetry works as follows: if continuous compounding with rate rr takes $1 today to erte^{rt} at time tt, then discounting takes erte^{rt} at time tt back to $1 today. The discount factor decays exponentially with time, meaning distant cash flows are worth progressively less today. The decay is steeper for higher discount rates.

Present Value

Present value is the current worth of a future sum of money, calculated by discounting the future amount at an appropriate interest rate. It answers the question: how much would you need to invest today to receive a specified amount in the future?

The term (1+r)−t(1 + r)^{-t} or e−rte^{-rt} is called the discount factor. It represents the present value of $1 received at time tt. The discount factor is the "exchange rate" between future dollars and present dollars. If the 5-year discount factor is 0.78, then $1 received in 5 years is worth only $0.78 today, or equivalently, you would need to invest $0.78 today to have $1 in 5 years.

PythonIn [11]
CollapseExpand
import numpy as np


def discount_factor(r, t, continuous=False):
    """Calculate discount factor for rate r and time t."""
    t = np.asarray(t, dtype=float)
    if continuous:
        return np.exp(-r * t)
    return (1.0 + r) ** (-t)


# Example: What is $1,000 in 5 years worth today at 6%?
FV = 1000
r = 0.06
t = 5

PV_discrete = FV * discount_factor(r, t, continuous=False)
PV_continuous = FV * discount_factor(r, t, continuous=True)
ConsoleOut [12]
CollapseExpand
Future value: $1,000.00 in 5 years
Discount rate: 6.0%

Present value (discrete):   $747.26
Present value (continuous): $740.82

Discount factor (discrete):   0.747258
Discount factor (continuous): 0.740818

For a positive future payment, a positive discount rate and a strictly positive horizon give a present value below the future amount. The discount factor tells you what fraction of a future dollar is worth today. At an effective annual rate of 6% for 5 years, each future dollar is worth about 75 cents today. The code holds the numerical quote at 6% under both conventions, so it compares different economic rates. Converting 6% effective annual to its equivalent continuous quote, ln⁡(1.06)\ln(1.06), would make the two present values identical.

The Discount Curve

In practice, interest rates vary by maturity. Short-term rates may differ substantially from long-term rates. A discount curve (or discount function) maps each maturity to its corresponding discount factor. This curve is a key building block of fixed-income analysis. Once the currency, collateral or funding setup, and discounting conventions are fixed, it contains the discount factors needed to value deterministic cash flows compatible with that setup. Contingent or floating cash flows can require additional projection or model inputs.

The shape of a discount-factor curve encodes the term structure of spot rates and, through ratios of discount factors, implied forward rates. A steep decline means that discounting over those maturities is strong; a slow decline means it is weak. Interpreting either shape as an expectation of future short rates requires a model that also accounts for term premia, so curve steepness alone does not establish that rates are expected to rise or fall. The field of term-structure modeling focuses on constructing and interpreting these relationships.

VisualizationOut [13]
CollapseExpand
Declining curve showing discount factors from 1.0 at year 0 to about 0.6 at year 10.
Discount curve showing the present value of $1 received at different future dates. At a constant 5% rate, the discount factor declines exponentially with time, reaching about 0.61 at year 10.

Discount curves are fundamental inputs to fixed-income analysis because they supply maturity-specific discount factors. A complete valuation may also require credit and liquidity adjustments, separate discount and projection curves, rate dynamics, volatility, and contract or collateral conventions. We will explore term structure modeling in depth in later chapters.

VisualizationOut [14]
CollapseExpand
Multiple declining curves showing discount factors at different rates from 2% to 10%.
Impact of discount rate on present value across different time horizons. Higher discount rates dramatically reduce present values, especially for distant cash flows. A 10% rate reduces a 20-year cash flow to less than 15% of its nominal value.

Interest Rate Quotations

Interest rates can be quoted using different compounding conventions. The same numerical quote can imply different effective costs or returns. For example, an 18% nominal annual rate capitalized monthly corresponds to a 19.56% EAR, not an 18% EAR. That comparison isolates compounding; actual credit-card charges also depend on contract terms and payments.

APR vs. Effective Annual Rate

For the compounding conversion below, APR denotes a nominal annual rate obtained by multiplying the periodic rate by the number of periods per year. If the monthly rate is 1.5%, this nominal rate is 12 × 1.5% = 18%. Statutory APR disclosures are product- and jurisdiction-specific: consumer-credit rules may incorporate specified finance charges, so a disclosed APR is not always just this nominal compounding label. The simplified conversion below isolates compounding and excludes fees.

The Effective Annual Rate (EAR) represents the one-year growth rate after accounting for compounding:

EAR=(1+APRn)n−1EAR = \left(1 + \frac{APR}{n}\right)^n - 1

where:

  • EAREAR: effective annual rate (true annual return)
  • APRAPR: annual percentage rate (nominal/stated rate)
  • nn: number of compounding periods per year
  • (1+APR/n)n(1 + APR/n)^n: the growth factor over one year with nn compounding periods

The formula works by computing what $1 actually grows to over one year: the term (1+APR/n)n(1 + APR/n)^n is the growth factor, representing the final balance after one year per dollar invested. Here nn is a positive integer and the per-period growth factor must be admissible. For a positive APR and n>1n>1, EAR is strictly greater than APR because interest compounds within the year; at APR =0=0, they are equal.

The gap between EAR and the nominal rate grows with both the rate and the compounding frequency. At low rates or with annual compounding, the difference is small. At high rates with frequent compounding, the difference becomes significant. Disclosure terminology depends on the product and jurisdiction. In the United States, consumer-credit rules specify APR disclosures, while deposit-account rules specify an Annual Percentage Yield (APY). APY is a regulated deposit disclosure, not a universal synonym for the generic EAR used in the formula here.

Effective Annual Rate

The effective annual rate (EAR) is the actual annual return earned on an investment or paid on a loan after accounting for compounding. It allows meaningful comparison between rates with different compounding frequencies.

PythonIn [15]
CollapseExpand
def apr_to_ear(apr, n):
    """Convert APR to EAR given n compounding periods per year."""
    return np.expm1(n * np.log1p(apr / n))


# Illustrative nominal rate: 18% compounded monthly, excluding fees
apr = 0.18
n = 12

ear = apr_to_ear(apr, n)
ConsoleOut [16]
CollapseExpand
Illustrative nominal APR: 18.0%
Compounding: Monthly (n=12)
Effective Annual Rate: 19.56%

Extra cost vs. stated rate: 1.56 percentage points

In this simplified example, an 18% nominal annual rate with monthly capitalization gives a 19.56% EAR. That is the one-year balance increase if there are no payments, new transactions, or fees. Actual credit-card charges depend on the contract's accrual rules, balances, payments, grace period, and fees; the CFPB's explanation describes daily accrual and the effect of payments.

VisualizationOut [17]
CollapseExpand
Line chart showing APR vs EAR with the gap widening at higher rates.
The gap between APR and effective annual rate (EAR) widens with higher nominal rates. With monthly compounding, an 18% APR translates to a 19.56% EAR, while a 30% APR becomes 34.5% EAR, a 4.5 percentage point difference.

Continuous Rate Conversions

In quantitative finance, we often need to convert between discrete and continuous rates. Quoting conventions vary by product, currency, and market, while continuous-time models often use continuously compounded rates for mathematical convenience. These conversions let us express economically equivalent growth factors under different conventions.

If rnr_n is the nominal rate compounding nn times per year and rcr_c is the equivalent continuous rate, they must produce the same terminal value over one year:

erc=(1+rnn)ne^{r_c} = \left(1 + \frac{r_n}{n}\right)^n

where:

  • erce^{r_c}: annual growth factor under continuous compounding
  • rcr_c: continuously compounded rate
  • rnr_n: nominal rate compounding nn times per year
  • nn: compounding frequency
  • (1+rn/n)n(1 + r_n/n)^n: annual growth factor under discrete compounding

This equation states that both rates must produce identical growth factors over one year. They are economically equivalent even though they are expressed differently. Solving for the continuous rate by taking the natural logarithm of both sides:

rc=n⋅ln⁡(1+rnn)r_c = n \cdot \ln\left(1 + \frac{r_n}{n}\right)

This formula converts a discretely compounded rate to its continuous equivalent. The logarithm "undoes" the exponential, extracting the continuous rate that achieves the same growth. And converting back by solving for the nominal rate:

rn=n(erc/n−1)r_n = n\left(e^{r_c/n} - 1\right)

This inverse formula takes a continuous rate and finds the discrete rate that produces identical growth. The exponential "undoes" the logarithm, and scaling by nn converts from a per-period rate back to an annual nominal rate.

For a positive compounding frequency nn, the comparison requires a valid discrete quote, rn>−nr_n>-n. Because ln⁡(1+x)≤x\ln(1+x)\leq x for x>−1x>-1, the equivalent rate satisfies rc=nln⁡(1+rn/n)≤rnr_c=n\ln(1+r_n/n)\leq r_n, with equality only when rn=0r_n=0. For a positive discrete quote, the continuous quote is numerically smaller; for a negative discrete quote, it is more negative. The size of the gap depends on the rate and compounding frequency, so quote conventions must be compared on an equivalent basis rather than by the stated numbers alone.

PythonIn [18]
CollapseExpand
import numpy as np


def discrete_to_continuous(r_discrete, n):
    """Convert discrete rate (n compounds/year) to continuous rate."""
    return n * np.log1p(r_discrete / n)


def continuous_to_discrete(r_continuous, n):
    """Convert continuous rate to discrete rate (n compounds/year)."""
    return n * np.expm1(r_continuous / n)


# Example: 5% annual rate
r_annual = 0.05
r_continuous = discrete_to_continuous(r_annual, 1)
r_back = continuous_to_discrete(r_continuous, 1)
ConsoleOut [19]
CollapseExpand
Annual discrete rate:    5.0000%
Equivalent continuous:   4.8790%
Converted back:          5.0000%

For this positive rate, the continuous quote is slightly lower than the annual discrete quote while producing the same one-year growth. When a quoted rate and a model input use different compounding conventions, conversion places them on an equivalent-growth basis before the rate enters the formula.

Day Count Conventions

Real-world interest calculations must handle fractional years. When interest accrues between two dates that do not span exact years, we need a rule for converting calendar days into a fraction of a year. Different markets use different day count conventions to determine this fraction, and the choice of convention can affect calculated interest amounts, especially for large notional values.

Named convention families contain variants, so a contract must identify the exact rule. Common labels include:

  • Actual/365 Fixed: Days between dates divided by 365
  • Actual/360: Days between dates divided by 360 (common for money markets)
  • 30/360 family: Uses convention-specific adjustments to represent 30-day months and a 360-day year; variants include 30U/360 and 30E/360
  • Actual/Actual family: Uses actual calendar days, with variants such as Actual/Actual ICMA and Actual/Actual ISDA

For a positive elapsed interval, Actual/360 produces a larger year fraction than Actual/365 Fixed. With the same positive principal and positive nominal rate, this gives a larger stated simple-interest accrual. At a negative rate, the algebraic accrual ordering reverses. Commercial pricing can offset the difference, so the convention alone does not guarantee an economic benefit to either party. Actual/Actual is calendar-sensitive rather than inherently "more accurate"; the correct calculation is the contractual variant. The code below is a simplified illustration and does not implement every end-of-month or February rule used by named 30/360 variants.

PythonIn [20]
CollapseExpand
from datetime import date


def year_fraction(start_date, end_date, convention="actual/365"):
    """Calculate year fraction between two dates."""
    days = (end_date - start_date).days

    if convention == "actual/365":
        return days / 365
    elif convention == "actual/360":
        return days / 360
    elif (
        convention == "30/360"
    ):  # Simplified illustration, not a named contractual variant
        d1 = min(start_date.day, 30)
        d2 = min(end_date.day, 30) if d1 == 30 else end_date.day
        months = (end_date.year - start_date.year) * 12 + (
            end_date.month - start_date.month
        )
        return (months * 30 + (d2 - d1)) / 360
    else:
        raise ValueError(f"Unknown convention: {convention}")


# Example: 6-month period
start = date(2024, 1, 15)
end = date(2024, 7, 15)

fractions = {}
for conv in ["actual/365", "actual/360", "30/360"]:
    fractions[conv] = year_fraction(start, end, conv)
ConsoleOut [21]
CollapseExpand
Period: 2024-01-15 to 2024-07-15
Actual days: 182

Convention        Year Fraction
--------------------------------
actual/365             0.498630
actual/360             0.505556
30/360                 0.500000

The same 6-month period produces different year fractions depending on the convention. These differences compound in interest calculations, particularly for large notional amounts. Always verify which convention applies to your specific market and instrument.

Valuing Cash Flow Streams

Financial instruments and investments can involve multiple cash flows over time:

  • A fixed-coupon bond pays periodic coupons.
  • An amortizing loan may require monthly payments.
  • A business valuation can use forecast operating cash flows, which are not the same as accounting profits.

The time value of money framework values a stream by treating each cash flow separately and summing the results.

Net Present Value

The Net Present Value (NPV) is the sum of all discounted cash flows. It takes each future cash flow, discounts it back to today using the appropriate discount factor, and adds up all these present values. This single number captures the total value of an entire cash flow stream in today's dollars:

NPV=∑t=0TCFt(1+r)tNPV = \sum_{t=0}^{T} \frac{CF_t}{(1+r)^t}

where:

  • NPVNPV: net present value (total value in today's dollars)
  • CFtCF_t: cash flow occurring at time tt (negative for outflows, positive for inflows)
  • rr: discount rate (required rate of return)
  • TT: final period of the cash flow stream
  • (1+r)−t(1+r)^{-t}: discount factor for period tt
  • ∑t=0T\sum_{t=0}^{T}: summation over all periods from 0 (today) to TT (final period)

Here the periods are years and rr is a constant effective annual rate with r>−1r>-1. The code also accepts fractional times measured in years. Each cash-flow amount must have a corresponding time. Both inputs must be one-dimensional arrays with the same shape; the function rejects mismatches rather than allowing NumPy to broadcast them. At r=0r=0, discount factors are one and NPV is simply the signed sum of the cash flows.

A positive NPV indicates the investment creates value; a negative NPV indicates it destroys value. NPV answers the question of net benefit in today's dollars by converting all future cash flows to a common time reference. The discount rate rr represents your opportunity cost, meaning what you could earn on alternative investments of similar risk. By using this rate to discount future cash flows, you are implicitly comparing the investment to your next best alternative.

The NPV framework accounts for when each cash flow occurs. At a positive discount rate, an equal positive inflow has a higher present value when received earlier. An equal negative outflow has a more negative present value when paid earlier: its present cost is larger. Discount factors capture both effects, so the sign matters as well as the timing.

Net Present Value

Net present value is the sum of all cash flows discounted to the present. It measures the total value created (or destroyed) by an investment in today's dollars.

PythonIn [22]
CollapseExpand
import numpy as np


def npv(cash_flows, times, r):
    """
    Calculate net present value of cash flows.

    Parameters:
    - cash_flows: array of cash flow amounts
    - times: array of times when cash flows occur
    - r: discount rate (annual)
    """
    cash_flows = np.asarray(cash_flows, dtype=float)
    times = np.asarray(times, dtype=float)
    if cash_flows.ndim != 1 or times.ndim != 1 or cash_flows.shape != times.shape:
        raise ValueError("cash_flows and times must be paired one-dimensional arrays")
    discount_factors = (1.0 + r) ** (-times)
    return np.sum(cash_flows * discount_factors)


# Investment example: Pay $10,000 now, receive $3,000/year for 5 years
cf = [-10000, 3000, 3000, 3000, 3000, 3000]
times = [0, 1, 2, 3, 4, 5]
r = 0.08

investment_npv = npv(cf, times, r)
ConsoleOut [23]
CollapseExpand
Investment Analysis
========================================
Initial investment: $10,000
Annual cash flows: $3,000 for 5 years
Discount rate: 8%

NPV: $1,978.13
Decision: Accept

The NPV is positive, indicating the investment generates value at an 8% discount rate. However, NPV is highly sensitive to the discount rate chosen. Let's examine this sensitivity:

VisualizationOut [24]
CollapseExpand
Line chart showing NPV declining from about $4,560 at a 1% discount rate to negative values above approximately 15.2%.
NPV sensitivity to discount rate for an investment of $10,000 returning $3,000 annually for 5 years. The NPV declines as the discount rate increases, crossing zero at approximately 15% (the internal rate of return).

The discount rate where NPV equals zero is called the Internal Rate of Return (IRR). For this investment, the IRR is approximately 15.2%, meaning the investment breaks even at that discount rate.

Annuities

An annuity is a series of equal payments made at regular intervals. Fixed-rate mortgages, amortizing car loans, and fixed-payment annuity products can be modeled as annuities. The defining characteristic is regularity: the same amount paid at the same interval for a fixed number of periods. This structure is common enough in finance to merit its own specialized formulas.

Rather than discounting each payment individually and summing, which would require TT separate calculations, we can derive a closed-form expression that computes the entire sum at once. The present value of an ordinary annuity (payments at end of each period) is:

PV=C⋅1−(1+r)−TrPV = C \cdot \frac{1 - (1+r)^{-T}}{r}

where:

  • PVPV: present value of the annuity
  • CC: periodic payment amount
  • rr: periodic interest rate (e.g., monthly rate for monthly payments)
  • TT: total number of payment periods
  • 1−(1+r)−Tr\frac{1 - (1+r)^{-T}}{r}: the annuity factor (present value of $1 per period for TT periods)

Here TT is a nonnegative integer count of payments and r>−1r>-1. Solving for the payment needed to repay a loan requires T>0T>0; an empty payment schedule cannot repay a positive principal. The zero-rate case is handled separately below.

The annuity formula comes from summing a geometric series of discount factors. The series 1/(1+r)+1/(1+r)2+…+1/(1+r)T1/(1+r) + 1/(1+r)^2 + \ldots + 1/(1+r)^T forms a geometric progression with first term 1/(1+r)1/(1+r) and common ratio 1/(1+r)1/(1+r). Applying the geometric series formula and simplifying yields the expression above. Rather than computing C/(1+r)+C/(1+r)2+…+C/(1+r)TC/(1+r) + C/(1+r)^2 + \ldots + C/(1+r)^T individually, the closed-form solution captures all terms at once.

For r>0r>0, the formula approaches C/rC/r (a perpetuity) as TT increases because (1+r)−T(1+r)^{-T} shrinks toward zero. If r=0r=0, the present value is instead CTCT; for −1<r<0-1<r<0 and positive payments, it grows without a finite perpetuity limit. The intuition that very distant payments contribute negligibly therefore depends on a positive discount rate.

Annuity

An annuity is a series of equal cash flows occurring at regular intervals. The annuity formula allows direct calculation of present or future value without summing each individual payment.

The term 1−(1+r)−Tr\frac{1 - (1+r)^{-T}}{r} is called the annuity factor. It represents the present value of receiving $1 per period for TT periods. This factor depends only on the interest rate and number of periods, not on the payment amount, making it a useful building block. Once you know the annuity factor, you simply multiply by the payment amount to get the present value of any annuity with those characteristics.

PythonIn [25]
CollapseExpand
def annuity_pv(payment, r, periods):
    """Present value of ordinary annuity."""
    if r == 0:
        return payment * periods
    annuity_factor = -np.expm1(-periods * np.log1p(r)) / r
    return payment * annuity_factor


def annuity_payment(pv, r, periods):
    """Calculate payment for a positive integer count of periods and r > -1."""
    if periods <= 0 or int(periods) != periods:
        raise ValueError("periods must be a positive integer")
    if r <= -1:
        raise ValueError("r must exceed -1")
    if r == 0:
        return pv / periods
    annuity_factor = -np.expm1(-periods * np.log1p(r)) / r
    return pv / annuity_factor


# Mortgage example: $300,000 loan, 6% annual rate, 30 years
loan_amount = 300000
annual_rate = 0.06
years = 30
monthly_rate = annual_rate / 12
months = years * 12

monthly_payment = annuity_payment(loan_amount, monthly_rate, months)
total_paid = monthly_payment * months
total_interest = total_paid - loan_amount
mortgage_years = 30  # Store for output display
ConsoleOut [26]
CollapseExpand
Mortgage Analysis
========================================
Loan amount:      $  300,000.00
Annual rate:             6.00%
Term:                       30 years

Monthly payment:  $    1,798.65
Total payments:   $  647,514.57
Total interest:   $  347,514.57

Interest/Principal ratio: 1.16x

Over 30 years, this borrower pays about 2.16 times the original principal in total: roughly $647,515 of payments on a $300,000 loan. Total interest is about 116% of the original principal. Most of the early payments go toward interest, with principal reduction accelerating over time. This amortization structure has practical implications for refinancing decisions.

VisualizationOut [27]
CollapseExpand
Stacked area chart showing interest declining and principal increasing over 30 years of mortgage payments.
Mortgage amortization over 30 years showing annual totals of the interest and principal components of twelve monthly payments. Interest (blue) dominates early annual totals, while principal repayment (orange) increases in later years. The first annual total with more principal than interest occurs in year 19.

Perpetuities

A perpetuity is an annuity that continues indefinitely in the model. Perpetual securities have no contractual maturity, although their terms may permit redemption. A permanent endowment can be planned over an indefinite horizon. In these settings, the perpetuity formula can provide a useful approximation.

For constant positive payments beginning one period from now, and a constant positive per-period discount rate rr, the present value is:

PV=CrPV = \frac{C}{r}

where:

  • PVPV: present value of the perpetuity
  • CC: constant periodic payment
  • rr: discount rate per period

The present value equals the principal amount that, if invested at rate rr, would generate exactly CC in interest each period forever, leaving the principal intact. If you have C/rC/r dollars earning rate rr, your interest income is (C/r)×r=C(C/r) \times r = C per period. You can withdraw this interest forever without touching the principal, creating a perpetual income stream of CC per period.

This formula emerges from taking the limit of the annuity formula as T→∞T \to \infty:

lim⁡T→∞C⋅1−(1+r)−Tr=Cr\lim_{T \to \infty} C \cdot \frac{1 - (1+r)^{-T}}{r} = \frac{C}{r}

For a fixed positive rr, the term (1+r)−T(1+r)^{-T} tends to zero as TT grows without bound, leaving C/rC/r. A finite cutoff needs a rate-specific check. Omitting payments after period TT leaves a tail worth (C/r)(1+r)−T(C/r)(1+r)^{-T}, or a fraction (1+r)−T(1+r)^{-T} of the perpetuity value. At 4% per period, the fraction beyond payment 1,000 is about 9.3×10−189.3\times10^{-18}; at 0.01% per period it is still about 90.48%. A positive rate alone does not make a particular finite cutoff negligible.

Perpetuity

A perpetuity is a stream of equal payments continuing indefinitely. For positive payments beginning one period from now and a positive per-period discount rate, its present value is PV=C/rPV=C/r.

PythonIn [28]
CollapseExpand
def perpetuity_pv(payment, r):
    """PV of end-period level payments under the model's positive-rate assumption."""
    return payment / r


# Example: Endowment providing $50,000 annually at 4% rate
annual_payment = 50000
r = 0.04

endowment_needed = perpetuity_pv(annual_payment, r)
ConsoleOut [29]
CollapseExpand
Annual scholarship payment: $50,000
Interest rate: 4.0%

Endowment required: $1,250,000

To fund a $50,000 annual scholarship in perpetuity at a constant 4% return, with the first withdrawal at year-end, the model requires $1.25 million. Each year's interest funds that year's withdrawal, leaving the nominal principal intact.

A growing perpetuity accounts for payments that change at a constant rate gg. For the usual nonnegative-payment model, take C>0C>0, 1+r>01+r>0, and 1+g≥01+g\geq0; if every payment must remain strictly positive, require 1+g>01+g>0.

PV=Cr−g,q=1+g1+r,∣q∣<1PV = \frac{C}{r - g}, \qquad q=\frac{1+g}{1+r}, \qquad |q|<1

where:

  • PVPV: present value of the growing perpetuity
  • CC: first payment (occurring one period from now)
  • rr: discount rate per period, with positive discount gross factor 1+r>01+r>0
  • gg: constant payment growth rate, with 1+g≥01+g\geq0 for nonnegative payments (strictly greater than zero for payments that remain positive forever)
  • r−gr - g: the discount-growth spread in the closed form; under these nonnegative gross-factor assumptions, ∣q∣<1|q|<1 reduces to r>gr>g

Growth partially offsets discounting. When payments grow at 2% and the discount rate is 5%, the discount-growth spread r−gr-g is 3 percentage points. Successive present-value terms have ratio q=1.02/1.05q=1.02/1.05, so the decline per term is 1−q≈2.857%1-q\approx2.857\%. The equivalent discount-rate quote is instead 1/q−1=1.05/1.02−1≈2.941%1/q-1=1.05/1.02-1\approx2.941\%; these are different quantities. With CC and rr fixed in the positive-gross-factor domain, as gg approaches rr from below, the terms barely decline and the sum grows without bound.

To see why mathematically, the tt-th payment is C(1+g)t−1C(1+g)^{t-1}, so its present value is C/(1+r)⋅qt−1C/(1+r)\cdot q^{t-1} with q=(1+g)/(1+r)q=(1+g)/(1+r). A geometric series converges exactly when ∣q∣<1|q|<1. In the nonnegative-payment domain, q≥0q\geq0, so this becomes q<1q<1 and, because 1+r>01+r>0, is equivalent to g<rg<r. If g≥rg\geq r, the nonnegative discounted terms do not decay to zero and the infinite sum diverges.

Applied to a constant-growth dividend stream, this formula gives the Gordon Growth Model for stock valuation.

VisualizationOut [30]
CollapseExpand
Line chart showing annuity present value approaching the horizontal perpetuity asymptote.
Present value of a $1,000 annual annuity converges to the perpetuity value as the number of periods increases. At a 5% discount rate, a 50-year annuity captures about 91% of the perpetuity value. At 100 years, the remaining tail is about 0.76% ($152.09 of the $20,000 perpetuity value), and it decreases for longer terms.

Worked Example: Bond Valuation

Let us apply our time value framework to a plain fixed-coupon bond with a stated maturity and principal repaid at maturity. Its cash flows consist of periodic coupons and that final principal repayment. Valuing this bond is a direct application of present value concepts; other bond structures can have different cash flows.

Consider a 5-year bond with:

  • Face value: $1,000
  • Coupon rate: 4% (annual payments)
  • Market yield: 5%

The bond's price equals the present value of all future cash flows:

P=∑t=1540(1.05)t+1000(1.05)5P = \sum_{t=1}^{5} \frac{40}{(1.05)^t} + \frac{1000}{(1.05)^5}

where:

  • PP: bond price (present value of all cash flows)
  • 4040: annual coupon payment ($1,000 × 4%)
  • 1.051.05: one plus the yield (1 + 0.05)
  • 10001000: face value returned at maturity
  • The first term ∑t=1540(1.05)t\sum_{t=1}^{5} \frac{40}{(1.05)^t}: present value of the coupon stream (an annuity)
  • The second term 1000(1.05)5\frac{1000}{(1.05)^5}: present value of the principal repayment

The structure of this formula reflects the two components of a bond's value. The coupon stream is an annuity: five equal payments of $40, one at the end of each year. We can either discount each payment separately or use the annuity formula. The principal repayment is a single lump sum occurring at maturity, which we discount using the basic present value formula. The bond price is simply the sum of these two present values.

PythonIn [31]
CollapseExpand
def annuity_pv(payment, r, periods):
    """Present value of ordinary annuity."""
    if r == 0:
        return payment * periods
    annuity_factor = -np.expm1(-periods * np.log1p(r)) / r
    return payment * annuity_factor


def bond_price(face_value, coupon_rate, yield_rate, years):
    """
    Calculate bond price given face value, coupon rate, yield, and maturity.
    Assumes annual coupon payments.
    """
    coupon = face_value * coupon_rate

    # PV of coupons (annuity)
    pv_coupons = annuity_pv(coupon, yield_rate, years)

    # PV of face value
    pv_face = face_value / (1 + yield_rate) ** years

    return pv_coupons + pv_face


# Bond parameters
face_value = 1000
coupon_rate = 0.04
yield_rate = 0.05
years = 5

price = bond_price(face_value, coupon_rate, yield_rate, years)
coupon = face_value * coupon_rate
ConsoleOut [32]
CollapseExpand
Bond Valuation
========================================
Face value:    $1,000
Coupon rate:   4.0% ($40/year)
Market yield:  5.0%
Maturity:      5 years

Bond price:    $956.71
Discount:      $43.29

The bond trades at a discount ($956.71 vs. $1,000 face) because its 4% coupon is below the 5% market yield. Investors require compensation for accepting below-market coupons, which comes in the form of a lower price.

Let's visualize how the bond's cash flows contribute to its price:

VisualizationsOut [33]
CollapseExpand
Bar chart showing nominal bond cash flows over 5 years with larger final payment.
Nominal cash flows of a 5-year bond with 4% coupon. The final year includes both the coupon payment and principal repayment.
Bar chart showing four successively smaller present values for the equal $40 coupons, followed by a much larger year-5 present value because the final cash flow includes principal.
Present value of bond cash flows discounted at 5% yield. Equal coupon payments have lower present values at later dates; the principal-bearing year-5 payment still contributes the most.

The final cash flow of $1,040 (coupon plus principal) accounts for the bulk of the bond's value, but its contribution is substantially reduced when discounted back five years.

VisualizationOut [34]
CollapseExpand
Downward sloping curve showing bond price decreasing as yield increases, crossing par at 4% yield.
Inverse relationship between bond price and yield for a 5-year, 4% coupon bond. When yield equals the coupon rate (4%), the bond trades at par ($1,000). Below par when yields exceed coupons; above par when yields fall below coupons.

Limitations and Practical Considerations

The time value of money framework is powerful but rests on assumptions that may not hold in practice. Understanding these limitations helps you apply the framework appropriately and recognize when more sophisticated approaches are needed.

A central limitation of the basic examples is their assumption of a constant, known discount rate. In reality, interest rates vary over time, differ across maturities (the term structure), and contain uncertainty about future values. A bond's yield to maturity is the single rate that equates the present value of its scheduled cash flows to its price under the specified compounding convention. It summarizes the price rather than supplying a separate market rate for every maturity. Using one rate can obscure term structure effects, so a fuller fixed-income analysis uses maturity-specific discount factors and, when needed, models rate dynamics.

Selecting a discount rate requires judgment. Even when a cash flow is treated as risk-free, the discounting setup must specify a rate source, currency, maturity, and relevant market conventions. For risky valuations, account for relevant risks consistently in cash-flow assumptions, discount rates, or both, without counting the same risk adjustment twice. For example, certainty-equivalent cash flows and risk-adjusted discount rates are alternative ways to represent risk in discounted-cash-flow valuation. Small changes in the discount rate can produce large changes in present value, particularly for long-duration cash flows, so examine sensitivity to the chosen assumptions.

Day count conventions, compounding frequencies, and accrued interest calculations introduce complexity that can cause errors if handled incorrectly. Different markets quote rates differently. The same nominal rate under different conventions produces different cash flows. In an implementation, treat the contractual convention and its exact variant as explicit inputs rather than relying on a generic family label. Any serious quantitative work requires careful attention to these details.

Finally, the basic examples here treat cash-flow amounts and dates as known. Real-world payments can be uncertain: a borrower may default, a project may underperform, or a loan may be prepaid. Discounted-cash-flow valuation can also use expected payments with a consistent risk adjustment; certainty is not a requirement of the general framework. The probability and risk-adjustment tools needed for uncertain payments appear in subsequent chapters.

Summary

This chapter covered the core concepts of time value of money and interest rates used throughout quantitative finance. With a positive applicable discount rate, earlier equal positive inflows have higher present values, while earlier equal outflows have higher present costs. Investment opportunity, expected inflation, and payment uncertainty can contribute to the valuation assumptions when relevant.

We developed the mathematics of compounding, progressing from simple interest through discrete compounding to the continuous compounding framework used in many continuous-time derivatives models. You now understand how to move between present and future values using discount factors, convert between rate quotations (nominal APR, EAR, continuous rates), and calculate year fractions under the illustrated day count conventions.

For valuing cash flow streams, you learned to calculate net present value, recognize when the annuity and perpetuity formulas apply, and understand the sensitivity of valuations to discount rate assumptions. The bond valuation example demonstrated how these tools combine in practice.

The key formulas to remember are:

  • Future value (continuous): FV=PertFV = Pe^{rt}
  • Present value (continuous): PV=FV⋅e−rtPV = FV \cdot e^{-rt}
  • Annuity PV: PV=C⋅1−(1+r)−TrPV = C \cdot \frac{1-(1+r)^{-T}}{r} for r≠0r\neq0; at r=0r=0, PV=CTPV=CT
  • Perpetuity PV: PV=C/rPV = C/r for an ordinary positive-payment perpetuity with r>0r>0

These building blocks appear throughout the book as we work with more complex instruments. The next chapter develops the probability foundations needed to represent uncertain returns, cash flows, and defaults.

Quiz

Ready to test your understanding? Take this quick quiz to reinforce what you've learned about the time value of money and interest rates.

Join the discussion1 comment

Comments

Add to the conversation

A question, a correction, or an example from your own work.

1 comment

  1. MarkMember

    Wow thanks for a thorough refresher of basics.

    1. Michael BrenndoerferMember

      Thanks Mark - glad you found it useful!

A different angle
All writing
Quantitative Finance · Vol. 1

Data Handling & Visualization: Python for Quant Finance

Covers financial data handling with pandas, NumPy, and Numba. Topics include time series operations, return calculations, and visualization for quant finance.

41 min read
Quantitative Finance · Vol. 1

Numerical Methods in Finance: Algorithms for Pricing & Risk

Covers root-finding, interpolation, and numerical integration for finance. Compute implied volatility, build yield curves, and price derivatives.

63 min read
Quantitative Finance · Vol. 1

Integral Calculus & Differential Equations in Finance

Covers continuous compounding, present value calculations, and differential equations. Essential tools for derivative pricing and financial modeling.

55 min read

About the author

Reference

Citation details

Cite or share this article.

BIBTEXAcademic
@misc{brenndoerfer2025timevalue, author = {Michael Brenndoerfer}, title = {Time Value of Money & Interest Rates: Finance Fundamentals}, year = {2025}, url = {https://mbrenndoerfer.com/writing/time-value-money-interest-rates-compounding-discounting}, organization = {mbrenndoerfer.com}, note = {Accessed: 2026-11-13} }
APAAcademic
Michael Brenndoerfer (2025). Time Value of Money & Interest Rates: Finance Fundamentals. Retrieved from https://mbrenndoerfer.com/writing/time-value-money-interest-rates-compounding-discounting
MLAAcademic
Michael Brenndoerfer. "Time Value of Money & Interest Rates: Finance Fundamentals." 2026. Web. November 13, 2026. <https://mbrenndoerfer.com/writing/time-value-money-interest-rates-compounding-discounting>.
CHICAGOAcademic
Michael Brenndoerfer. "Time Value of Money & Interest Rates: Finance Fundamentals." Accessed November 13, 2026. https://mbrenndoerfer.com/writing/time-value-money-interest-rates-compounding-discounting.
HARVARDAcademic
Michael Brenndoerfer (2025) 'Time Value of Money & Interest Rates: Finance Fundamentals'. Available at: https://mbrenndoerfer.com/writing/time-value-money-interest-rates-compounding-discounting (Accessed: November 13, 2026).
SimpleBasic
Michael Brenndoerfer (2025). Time Value of Money & Interest Rates: Finance Fundamentals. https://mbrenndoerfer.com/writing/time-value-money-interest-rates-compounding-discounting
Newsletter

Stay up to date

Get new articles, book updates, and notes on AI and technology.

Unsubscribe at any time. Privacy policy