---
title: "Chapter 5. Martingales in Discrete Time"
---
::: {.chapter-objectives}
## Learning Goals
By the end of this chapter, students should be able to:
- describe information flow using a filtration $(\mathcal F_n)_{n\ge 0}$;
- compute conditional expectations in finite probability spaces;
- define martingales, submartingales, and supermartingales in discrete time;
- explain why discounted asset prices are martingales under a risk-neutral measure;
- use the martingale property to price contingent claims by conditional expectation;
- connect dynamic replication in a binomial tree with martingale pricing;
- state and apply the optional stopping principle in simple bounded settings;
- interpret Doob decomposition as predictable drift plus martingale noise;
- implement discrete-time martingale checks and pricing recursions in Python;
- use AI tools to audit conditional-expectation calculations, assumptions, and code.
:::
::: {.hero-box}
The central mathematical idea of risk-neutral pricing is simple to state:
$$
\mathbb E^{\mathbb Q}\left[\widetilde S_{n+1}\mid \mathcal F_n\right]=\widetilde S_n.
$$
The discounted price $\widetilde S_n=S_n/B_n$ has no predictable drift under the pricing measure $\mathbb Q$. This does **not** say that investors are risk-neutral in the real world. It says that after changing from the physical probability $\mathbb P$ to a pricing probability $\mathbb Q$, no-arbitrage prices can be computed by conditional expectations.
:::
## 5.1 Why Martingales Appear in Finance
In Chapters 3 and 4, we priced contingent claims in one-period and multi-period binomial models. The formulas looked like discounted expectations under a special probability measure:
$$
V_0=\frac{1}{R^N}\mathbb E^{\mathbb Q}[H].
$$
For a claim $H$ paid at time $N$, this formula is correct at time $0$. But financial pricing is not only a time-zero problem. At each intermediate date $n$, a trader observes some information and must update the value of the claim. Therefore the correct dynamic formula is
$$
V_n=R^{-(N-n)}\mathbb E^{\mathbb Q}[H\mid \mathcal F_n].
$$
Equivalently, if $B_n=R^n$ is the bank account and $\widetilde V_n=V_n/B_n$ is the discounted derivative value, then
$$
\widetilde V_n=\mathbb E^{\mathbb Q}\left[\widetilde H\mid \mathcal F_n\right],
\qquad
\widetilde H=\frac{H}{B_N}.
$$
The process $(\widetilde V_n)_{n=0}^N$ is a martingale. This is the mathematical form of the statement:
> A fairly priced discounted asset has no predictable gain.
This chapter develops the discrete-time martingale language carefully. We will work mostly in finite probability spaces, where every conditional expectation can be computed as an average over states. This keeps the measure-theoretic ideas clean while still preparing for Brownian motion, stochastic integration, and continuous-time martingale pricing later in the book.
## 5.2 Probability Space and Information
A discrete-time financial model begins with a probability space
$$
(\Omega,\mathcal F,\mathbb P),
$$
where:
- $\Omega$ is the set of possible scenarios;
- $\mathcal F$ is the collection of events whose probabilities are defined;
- $\mathbb P$ is the physical probability measure.
In a finite model, $\Omega=\{\omega_1,\ldots,\omega_m\}$ and probabilities are simply positive weights $p_i=\mathbb P(\{\omega_i\})$ satisfying
$$
\sum_{i=1}^m p_i=1.
$$
A random variable is a function
$$
X:\Omega\to \mathbb R.
$$
The expectation of $X$ is
$$
\mathbb E[X]=\sum_{\omega\in\Omega}X(\omega)\mathbb P(\omega).
$$
In finance, what matters is not only what can happen, but also **when information is revealed**.
::: {.definition}
### Definition 5.1: Filtration
A filtration is an increasing sequence of sigma-algebras
$$
\mathcal F_0\subseteq \mathcal F_1\subseteq\cdots\subseteq \mathcal F_N\subseteq \mathcal F.
$$
The sigma-algebra $\mathcal F_n$ represents the information available at time $n$.
:::
In a finite tree model, $\mathcal F_n$ tells us which node of the tree has been reached by time $n$. At time $0$, there is no uncertainty resolved, so $\mathcal F_0$ usually contains only the trivial events $\varnothing$ and $\Omega$. At maturity $N$, all relevant uncertainty may be revealed, so $\mathcal F_N$ may be the full sigma-algebra.
::: {.example}
### Example 5.1: Two-step binomial information
Let $\Omega=\{UU,UD,DU,DD\}$ be the four possible two-step paths of a binomial stock model. At time $0$, the investor cannot distinguish any paths:
$$
\mathcal F_0=\{\varnothing,\Omega\}.
$$
At time $1$, the investor knows whether the first move was up or down. Thus $\Omega$ is partitioned into two information cells:
$$
\{UU,UD\},\qquad \{DU,DD\}.
$$
At time $2$, the investor knows the full path. The information cells are singletons:
$$
\{UU\},\{UD\},\{DU\},\{DD\}.
$$
:::
## 5.3 Adapted Processes
A stochastic process is a sequence of random variables
$$
X_0,X_1,\ldots,X_N.
$$
In financial applications, $X_n$ may represent a stock price, portfolio value, discounted price, cumulative gain, trading strategy, or derivative value.
::: {.definition}
### Definition 5.2: Adapted process
A process $(X_n)_{n=0}^N$ is adapted to the filtration $(\mathcal F_n)_{n=0}^N$ if $X_n$ is $\mathcal F_n$-measurable for every $n$.
:::
The phrase "$X_n$ is $\mathcal F_n$-measurable" means that the value of $X_n$ is known using the information available at time $n$. In a tree model, this means that $X_n$ is constant on every node at time $n$.
::: {.example}
### Example 5.2: Stock price is adapted
In a two-step binomial model, suppose
$$
S_0=100,
\qquad
u=1.2,
\qquad
d=0.8.
$$
At time $1$, the stock price is $120$ on paths $UU,UD$ and $80$ on paths $DU,DD$. Since these values are constant on the time-$1$ information cells, $S_1$ is $\mathcal F_1$-measurable.
At time $2$, each path has its own final value. Therefore $S_2$ is $\mathcal F_2$-measurable.
:::
A trading strategy must also be adapted or predictable, depending on convention. A trader cannot choose today's position using tomorrow's information. This simple restriction is one of the most important modeling assumptions in no-arbitrage theory.
## 5.4 Conditional Expectation in Finite Models
Conditional expectation is the mathematical tool for updating fair values when information changes.
::: {.definition}
### Definition 5.3: Conditional expectation in a finite partition
Suppose $\mathcal G$ corresponds to a finite partition
$$
A_1,\ldots,A_k
$$
of $\Omega$, where each $A_j$ has positive probability. The conditional expectation $\mathbb E[X\mid\mathcal G]$ is the random variable that is constant on each cell $A_j$ and satisfies
$$
\mathbb E[X\mid\mathcal G](\omega)
=
\frac{\sum_{\eta\in A_j}X(\eta)\mathbb P(\eta)}{\mathbb P(A_j)},
\qquad \omega\in A_j.
$$
:::
Thus conditional expectation is obtained by averaging only over the scenarios that remain possible given the current information.
::: {.example}
### Example 5.3: Conditional expectation on a two-step tree
Let $\Omega=\{UU,UD,DU,DD\}$ with probabilities
$$
\mathbb P(UU)=0.36,
\quad
\mathbb P(UD)=0.24,
\quad
\mathbb P(DU)=0.24,
\quad
\mathbb P(DD)=0.16.
$$
Let $X$ be a payoff with values
$$
X(UU)=44,
\quad
X(UD)=0,
\quad
X(DU)=0,
\quad
X(DD)=0.
$$
At time $1$, the information cells are
$$
A_U=\{UU,UD\},
\qquad
A_D=\{DU,DD\}.
$$
Then
$$
\mathbb E[X\mid\mathcal F_1](UU)
=
\mathbb E[X\mid\mathcal F_1](UD)
=
\frac{44(0.36)+0(0.24)}{0.36+0.24}=26.4.
$$
On the down cell,
$$
\mathbb E[X\mid\mathcal F_1](DU)
=
\mathbb E[X\mid\mathcal F_1](DD)=0.
$$
:::
Conditional expectation satisfies several identities that are essential in mathematical finance.
::: {.theorem}
### Theorem 5.1: Basic properties of conditional expectation
Let $X,Y$ be integrable random variables and let $\mathcal G\subseteq \mathcal F$ be a sigma-algebra. Then:
1. **Linearity:**
$$
\mathbb E[aX+bY\mid\mathcal G]
=a\mathbb E[X\mid\mathcal G]+b\mathbb E[Y\mid\mathcal G].
$$
2. **Taking out what is known:** if $Z$ is $\mathcal G$-measurable, then
$$
\mathbb E[ZX\mid\mathcal G]=Z\mathbb E[X\mid\mathcal G].
$$
3. **Tower property:** if $\mathcal H\subseteq\mathcal G$, then
$$
\mathbb E[\mathbb E[X\mid\mathcal G]\mid\mathcal H]
=\mathbb E[X\mid\mathcal H].
$$
4. **Total expectation:**
$$
\mathbb E[\mathbb E[X\mid\mathcal G]]=\mathbb E[X].
$$
:::
The tower property is especially important. It says that updating in two steps is consistent with updating directly. In asset pricing, this means that today's price obtained through tomorrow's price must agree with today's price obtained directly from the terminal payoff.
## 5.5 Martingales, Submartingales, and Supermartingales
We can now define the central object.
::: {.definition}
### Definition 5.4: Discrete-time martingale
Let $(X_n)_{n=0}^N$ be an adapted process with $\mathbb E[|X_n|]<\infty$ for every $n$. The process is a martingale with respect to $(\mathcal F_n)$ and probability measure $\mathbb P$ if
$$
\mathbb E[X_{n+1}\mid\mathcal F_n]=X_n,
\qquad n=0,1,\ldots,N-1.
$$
:::
A martingale is a fair game in the following precise sense: given the information available now, the expected next value equals the current value.
::: {.definition}
### Definition 5.5: Submartingale and supermartingale
An adapted integrable process $(X_n)$ is a submartingale if
$$
\mathbb E[X_{n+1}\mid\mathcal F_n]\ge X_n,
$$
and a supermartingale if
$$
\mathbb E[X_{n+1}\mid\mathcal F_n]\le X_n.
$$
:::
A submartingale has nonnegative conditional drift. A supermartingale has nonpositive conditional drift. Martingales are the zero-drift boundary case.
::: {.example}
### Example 5.4: Random walk martingale
Let $\xi_1,\xi_2,\ldots$ be independent random variables with
$$
\mathbb P(\xi_k=1)=\mathbb P(\xi_k=-1)=\frac12.
$$
Define
$$
X_n=\sum_{k=1}^n\xi_k,
\qquad X_0=0.
$$
Let $\mathcal F_n$ be the information generated by $\xi_1,\ldots,\xi_n$. Then
$$
\mathbb E[X_{n+1}\mid\mathcal F_n]
=
\mathbb E[X_n+\xi_{n+1}\mid\mathcal F_n]
=X_n+\mathbb E[\xi_{n+1}]
=X_n.
$$
Therefore $(X_n)$ is a martingale.
:::
::: {.warning}
A martingale does not mean that paths are constant. A martingale can move up and down randomly. The condition is about the **conditional expectation** of the next value, not about deterministic equality from one time to the next.
:::
## 5.6 Discounted Prices and Risk-Neutral Martingales
Let $S_n$ be a stock price and let $B_n$ be the bank account. If the risk-free gross return is constant $R=1+r$, then
$$
B_n=R^n.
$$
The discounted stock price is
$$
\widetilde S_n=\frac{S_n}{B_n}=\frac{S_n}{R^n}.
$$
In a no-arbitrage model, there exists a probability measure $\mathbb Q$ such that discounted traded asset prices are martingales:
$$
\mathbb E^{\mathbb Q}[\widetilde S_{n+1}\mid \mathcal F_n]
=\widetilde S_n.
$$
This measure $\mathbb Q$ is called a **risk-neutral measure** or an **equivalent martingale measure**.
::: {.theorem}
### Theorem 5.2: Binomial discounted stock is a martingale under $\mathbb Q$
Consider a binomial model with stock dynamics
$$
S_{n+1}=\begin{cases}
u S_n, & \text{up},\\ dS_n, & \text{down},\end{cases}
$$
and bank account $B_n=R^n$. Assume
$$
d<R<\nu.
$$
Define
$$
q=\frac{R-d}{\nu-d}.
$$
If each next up move has conditional probability $q$ under $\mathbb Q$, then the discounted stock price $\widetilde S_n=S_n/R^n$ is a $\mathbb Q$-martingale.
:::
::: {.proof}
At time $n$, the stock price $S_n$ is known. Therefore
$$
\mathbb E^{\mathbb Q}[S_{n+1}\mid\mathcal F_n]
=q\nu S_n+(1-q)dS_n
=S_n\left(q\nu+(1-q)d\right).
$$
By the definition of $q$,
$$
q\nu+(1-q)d=R.
$$
Thus
$$
\mathbb E^{\mathbb Q}[S_{n+1}\mid\mathcal F_n]=RS_n.
$$
Dividing by $B_{n+1}=R^{n+1}$ gives
$$
\mathbb E^{\mathbb Q}\left[\frac{S_{n+1}}{R^{n+1}}\mid\mathcal F_n\right]
=
\frac{RS_n}{R^{n+1}}
=
\frac{S_n}{R^n}
=\widetilde S_n.
$$
Therefore $\widetilde S$ is a martingale under $\mathbb Q$.
:::
The physical probability $p$ determines real-world statistical behavior. The risk-neutral probability $q$ determines no-arbitrage prices. They are generally not equal.
## 5.7 Pricing Claims by Martingales
Let $H$ be a contingent claim paid at time $N$. For example, for a European call option,
$$
H=(S_N-K)^+.
$$
If the bank account is $B_n=R^n$, the discounted payoff is
$$
\widetilde H=\frac{H}{B_N}.
$$
The no-arbitrage value process is
$$
V_n
=B_n\mathbb E^{\mathbb Q}\left[\frac{H}{B_N}\mid\mathcal F_n\right].
$$
Equivalently,
$$
\widetilde V_n
=\frac{V_n}{B_n}
=
\mathbb E^{\mathbb Q}[\widetilde H\mid\mathcal F_n].
$$
::: {.theorem}
### Theorem 5.3: Discounted derivative prices are martingales
Let
$$
\widetilde V_n=\mathbb E^{\mathbb Q}[\widetilde H\mid\mathcal F_n],
\qquad n=0,1,\ldots,N.
$$
Then $(\widetilde V_n)$ is a $\mathbb Q$-martingale.
:::
::: {.proof}
Using the tower property,
$$
\mathbb E^{\mathbb Q}[\widetilde V_{n+1}\mid\mathcal F_n]
=
\mathbb E^{\mathbb Q}\left[
\mathbb E^{\mathbb Q}[\widetilde H\mid\mathcal F_{n+1}]
\mid\mathcal F_n
\right]
=
\mathbb E^{\mathbb Q}[\widetilde H\mid\mathcal F_n]
=\widetilde V_n.
$$
Hence the discounted value process is a martingale.
:::
This theorem explains why pricing is naturally recursive. If a claim is fairly priced at all future nodes, then today's discounted value is the conditional average of tomorrow's discounted value.
## 5.8 Worked Example: Two-Step European Call
Consider a two-step binomial model with
$$
S_0=100,
\qquad
u=1.2,
\qquad
d=0.8,
\qquad
R=1.05,
\qquad
K=100.
$$
The risk-neutral probability is
$$
q=\frac{R-d}{\nu-d}=\frac{1.05-0.8}{1.2-0.8}=0.625.
$$
The terminal stock prices are
$$
S_2(UU)=144,
\qquad
S_2(UD)=S_2(DU)=96,
\qquad
S_2(DD)=64.
$$
The European call payoff is
$$
H=(S_2-K)^+,
$$
so
$$
H(UU)=44,
\qquad
H(UD)=H(DU)=H(DD)=0.
$$
At time $1$, the option value after an up move is
$$
V_1(U)
=\frac{1}{R}\left(q\cdot 44+(1-q)\cdot 0\right)
=\frac{0.625\cdot 44}{1.05}
\approx 26.1905.
$$
After a down move,
$$
V_1(D)=0.
$$
At time $0$,
$$
V_0
=\frac{1}{R}\left(qV_1(U)+(1-q)V_1(D)\right)
\approx
\frac{0.625\cdot 26.1905}{1.05}
\approx 15.5896.
$$
Equivalently,
$$
V_0
=\frac{1}{R^2}\mathbb E^{\mathbb Q}[H]
=
\frac{1}{1.05^2}\left(44q^2\right)
\approx 15.5896.
$$
The equality of these two calculations is an example of the tower property.
## 5.9 Interactive Demo: Martingale Versus Drift
The next activity compares three processes on a binomial tree:
1. the stock price $S_n$ under the physical probability $p$;
2. the discounted stock price $\widetilde S_n=S_n/R^n$ under $\mathbb P$;
3. the discounted stock price under the risk-neutral probability $q$.
Only the third process is guaranteed to have zero conditional drift.
::: {.interactive-card}
### Explore conditional drift in a one-step binomial model
Move the sliders and compare the physical probability $p$ with the risk-neutral probability $q=(R-d)/(u-d)$. The plot shows the one-step conditional expected change of the discounted stock price.
<div class="mf-controls">
<label for="ch5-u">up factor $u$</label>
<input id="ch5-u" type="range" min="1.02" max="1.80" step="0.01" value="1.20">
<label for="ch5-d">down factor $d$</label>
<input id="ch5-d" type="range" min="0.40" max="0.98" step="0.01" value="0.80">
<label for="ch5-R">gross risk-free return $R$</label>
<input id="ch5-R" type="range" min="1.00" max="1.20" step="0.005" value="1.05">
<label for="ch5-p">physical up probability $p$</label>
<input id="ch5-p" type="range" min="0.05" max="0.95" step="0.01" value="0.55">
</div>
<div id="ch5-martingale-drift" class="plotly-demo"></div>
<div id="ch5-martingale-output" class="mf-output"></div>
<script>
(function(){
function $(id){ return document.getElementById(id); }
function update(){
if (typeof Plotly === "undefined") return;
const u = parseFloat($("ch5-u").value);
const d = parseFloat($("ch5-d").value);
const R = parseFloat($("ch5-R").value);
const p = parseFloat($("ch5-p").value);
const out = $("ch5-martingale-output");
if (!(d < R && R < u)) {
Plotly.react("ch5-martingale-drift", [], {title: "No-arbitrage condition fails"});
out.innerHTML = `Current parameters violate <strong>d < R < u</strong>. The risk-neutral probability is not inside (0,1).`;
return;
}
const q = (R - d) / (u - d);
const S0 = 100;
const discUp = u * S0 / R;
const discDown = d * S0 / R;
const physicalExpected = p * discUp + (1 - p) * discDown;
const rnExpected = q * discUp + (1 - q) * discDown;
const x = ["Physical probability p", "Risk-neutral probability q"];
const y = [physicalExpected - S0, rnExpected - S0];
const trace = {x:x, y:y, type:"bar", text:y.map(v => v.toFixed(4)), textposition:"auto"};
const layout = {
title:"Conditional expected change of discounted stock price",
yaxis:{title:"E[discounted S1 | F0] - S0"},
margin:{t:55,l:65,r:25,b:70},
shapes:[{type:"line", xref:"paper", x0:0, x1:1, y0:0, y1:0, line:{dash:"dot"}}]
};
Plotly.react("ch5-martingale-drift", [trace], layout, {responsive:true});
out.innerHTML = `Risk-neutral probability: <strong>q = ${q.toFixed(4)}</strong>. Under Q, the discounted stock has expected change <strong>${(rnExpected-S0).toExponential(2)}</strong>. Under P, the expected change is <strong>${(physicalExpected-S0).toFixed(4)}</strong>.`;
}
["ch5-u","ch5-d","ch5-R","ch5-p"].forEach(id => $(id).addEventListener("input", update));
update();
})();
</script>
:::
## 5.10 Python Example: Conditional Expectation on a Tree
The following code computes conditional expectations in the two-step example directly from path probabilities.
```{python}
import numpy as np
import pandas as pd
# Two-step path space
paths = ["UU", "UD", "DU", "DD"]
q = 0.625
prob_Q = {
"UU": q * q,
"UD": q * (1 - q),
"DU": (1 - q) * q,
"DD": (1 - q) * (1 - q),
}
# Terminal payoff of a European call in the example
H = {"UU": 44.0, "UD": 0.0, "DU": 0.0, "DD": 0.0}
# Time-1 information cells
cells_F1 = {
"U": ["UU", "UD"],
"D": ["DU", "DD"],
}
def conditional_expectation_on_cells(X, probs, cells):
values = {}
for cell_name, states in cells.items():
total_prob = sum(probs[s] for s in states)
avg = sum(X[s] * probs[s] for s in states) / total_prob
for s in states:
values[s] = avg
return values
EH_F1 = conditional_expectation_on_cells(H, prob_Q, cells_F1)
pd.DataFrame({
"path": paths,
"Q probability": [prob_Q[p] for p in paths],
"payoff H": [H[p] for p in paths],
"E_Q[H | F1]": [EH_F1[p] for p in paths],
})
```
Because the payoff is positive only after two up moves, the time-$1$ conditional expectation is positive after an up move and zero after a down move.
## 5.11 Python Example: Checking the Martingale Property
A process is a martingale if the conditional expectation of the next value equals the current value at every node. The following code checks this property for the discounted stock in a binomial model.
```{python}
S0 = 100.0
u = 1.2
d = 0.8
R = 1.05
q = (R - d) / (u - d)
N = 4
rows = []
for n in range(N):
for j in range(n + 1):
S_n = S0 * (u ** j) * (d ** (n - j))
discounted_now = S_n / (R ** n)
S_up = u * S_n
S_down = d * S_n
discounted_next_expectation = (
q * S_up / (R ** (n + 1))
+ (1 - q) * S_down / (R ** (n + 1))
)
rows.append({
"time n": n,
"up moves j": j,
"discounted current": discounted_now,
"conditional expected discounted next": discounted_next_expectation,
"difference": discounted_next_expectation - discounted_now,
})
pd.DataFrame(rows)
```
The difference column should be essentially zero, up to floating-point rounding.
## 5.12 Martingales and Self-Financing Strategies
A portfolio strategy is called self-financing if all changes in portfolio value come from gains and losses on assets already held, not from adding or withdrawing cash.
In a simple one-stock, one-bank-account model, let $\Delta_n$ be the number of shares held over the interval from $n$ to $n+1$, and let $\beta_n$ be the number of bank-account units. The portfolio value at time $n$ is
$$
V_n=\Delta_n S_n+\beta_n B_n.
$$
The discounted value is
$$
\widetilde V_n=\frac{V_n}{B_n}
=\Delta_n\widetilde S_n+\beta_n.
$$
If the strategy is self-financing, then the discounted gains satisfy
$$
\widetilde V_{n+1}-\widetilde V_n
=\Delta_n(\widetilde S_{n+1}-\widetilde S_n).
$$
Under a risk-neutral measure, $\widetilde S$ is a martingale. Since $\Delta_n$ is known at time $n$,
$$
\mathbb E^{\mathbb Q}[\widetilde V_{n+1}-\widetilde V_n\mid\mathcal F_n]
=
\Delta_n\mathbb E^{\mathbb Q}[\widetilde S_{n+1}-\widetilde S_n\mid\mathcal F_n]
=0.
$$
Therefore a self-financing discounted portfolio value is also a martingale, provided the strategy is admissible and integrable.
::: {.theorem}
### Theorem 5.4: Self-financing portfolios preserve martingales
Suppose $\widetilde S$ is a martingale under $\mathbb Q$. Let $(\Delta_n)$ be a predictable trading strategy, meaning $\Delta_n$ is known at time $n$. If the discounted self-financing portfolio satisfies
$$
\widetilde V_{n+1}-\widetilde V_n
=\Delta_n(\widetilde S_{n+1}-\widetilde S_n),
$$
then $(\widetilde V_n)$ is a martingale under suitable integrability assumptions.
:::
This theorem is the martingale version of the no-free-lunch idea. If discounted asset prices have no predictable drift, then predictable self-financing trading cannot create predictable discounted profit.
## 5.13 Optional Stopping: Why Doubling Strategies Do Not Create Arbitrage
A common misunderstanding is that a martingale can be beaten by stopping at the right time. For example, in a fair coin-tossing game, one might try to keep playing until the first win. This can appear to guarantee profit, but it usually requires unbounded losses, unbounded capital, or an unbounded stopping time.
::: {.definition}
### Definition 5.6: Stopping time
A random time $\tau$ taking values in $\{0,1,\ldots,N\}$ is a stopping time with respect to $(\mathcal F_n)$ if the event
$$
\{\tau\le n\}
$$
belongs to $\mathcal F_n$ for every $n$.
:::
The event $\{\tau\le n\}$ must be decidable using the information available by time $n$. For example, the first time a stock price exceeds a barrier is a stopping time. The last time before maturity that a stock reaches its maximum is generally not a stopping time, because knowing it requires future information.
::: {.theorem}
### Theorem 5.5: Optional stopping in a bounded discrete-time setting
Let $(X_n)_{n=0}^N$ be a martingale and let $\tau$ be a stopping time taking values in $\{0,1,\ldots,N\}$. Then
$$
\mathbb E[X_\tau]=\mathbb E[X_0].
$$
:::
The boundedness of the time horizon is important. More general optional stopping theorems require additional assumptions.
::: {.proof}
For each $k$, define
$$
I_k=\mathbf 1_{\{\tau\ge k\}}.
$$
Since $\{\tau\ge k\}$ is known at time $k-1$, $I_k$ is $\mathcal F_{k-1}$-measurable. We can write the stopped increment sum as
$$
X_\tau-X_0=\sum_{k=1}^N I_k(X_k-X_{k-1}).
$$
Taking expectations and using the martingale property,
$$
\mathbb E[I_k(X_k-X_{k-1})]
=
\mathbb E\left[I_k\mathbb E[X_k-X_{k-1}\mid\mathcal F_{k-1}]\right]
=0.
$$
Summing over $k$ gives
$$
\mathbb E[X_\tau-X_0]=0.
$$
Therefore $\mathbb E[X_\tau]=\mathbb E[X_0]$.
:::
In finance, optional stopping supports the idea that a predictable rule for when to stop trading cannot create arbitrage if prices are properly discounted martingales and strategies satisfy admissibility conditions.
## 5.14 Interactive Demo: Stopping a Fair Game
The next simulation shows a simple symmetric random walk. We stop the process the first time it reaches an upper barrier, a lower barrier, or a fixed maximum time. With a bounded stopping rule, the average stopped value remains close to the initial value.
::: {.interactive-card}
### Simulate optional stopping for a bounded random walk
<div class="mf-controls">
<label for="ch5-upper">upper barrier</label>
<input id="ch5-upper" type="range" min="2" max="12" step="1" value="5">
<label for="ch5-lower">lower barrier magnitude</label>
<input id="ch5-lower" type="range" min="2" max="12" step="1" value="5">
<label for="ch5-steps">maximum steps</label>
<input id="ch5-steps" type="range" min="10" max="150" step="10" value="60">
</div>
<div id="ch5-stopping-demo" class="plotly-demo"></div>
<div id="ch5-stopping-output" class="mf-output"></div>
<script>
(function(){
function $(id){ return document.getElementById(id); }
function simulatePath(upper, lower, maxSteps){
let x = 0;
const path = [0];
for(let n=1; n<=maxSteps; n++){
x += (Math.random() < 0.5 ? 1 : -1);
path.push(x);
if(x >= upper || x <= -lower) break;
}
return path;
}
function update(){
if (typeof Plotly === "undefined") return;
const upper = parseInt($("ch5-upper").value);
const lower = parseInt($("ch5-lower").value);
const maxSteps = parseInt($("ch5-steps").value);
const samplePaths = [];
const stoppedValues = [];
for(let i=0; i<400; i++){
const path = simulatePath(upper, lower, maxSteps);
stoppedValues.push(path[path.length-1]);
if(i < 12){
samplePaths.push({
x: path.map((_, j) => j),
y: path,
type:"scatter",
mode:"lines",
line:{width:1},
showlegend:false
});
}
}
const meanStopped = stoppedValues.reduce((a,b)=>a+b,0)/stoppedValues.length;
const layout = {
title:"Sample stopped random-walk paths",
xaxis:{title:"time"},
yaxis:{title:"stopped random walk"},
margin:{t:55,l:55,r:25,b:50},
shapes:[
{type:"line", xref:"paper", x0:0, x1:1, y0:upper, y1:upper, line:{dash:"dot"}},
{type:"line", xref:"paper", x0:0, x1:1, y0:-lower, y1:-lower, line:{dash:"dot"}}
]
};
Plotly.react("ch5-stopping-demo", samplePaths, layout, {responsive:true});
$("ch5-stopping-output").innerHTML = `Across 400 simulated stopped paths, the average stopped value is <strong>${meanStopped.toFixed(3)}</strong>. It fluctuates randomly but should remain near 0 for a bounded fair game.`;
}
["ch5-upper","ch5-lower","ch5-steps"].forEach(id => $(id).addEventListener("input", update));
update();
})();
</script>
:::
## 5.15 Python Example: Optional Stopping Simulation
```{python}
rng = np.random.default_rng(7243)
def stopped_random_walk(upper=5, lower=-5, max_steps=100, rng=None):
if rng is None:
rng = np.random.default_rng()
x = 0
for n in range(1, max_steps + 1):
x += 1 if rng.random() < 0.5 else -1
if x >= upper or x <= lower:
return x, n
return x, max_steps
num_sims = 20_000
upper = 5
lower = -5
max_steps = 100
results = np.array([
stopped_random_walk(upper, lower, max_steps, rng)
for _ in range(num_sims)
])
stopped_values = results[:, 0]
stopping_times = results[:, 1]
pd.DataFrame({
"quantity": ["mean stopped value", "standard error", "mean stopping time"],
"estimate": [
stopped_values.mean(),
stopped_values.std(ddof=1) / np.sqrt(num_sims),
stopping_times.mean(),
]
})
```
The simulated mean stopped value should be close to zero. The exact value changes with the random seed, but the standard error gives a sense of the Monte Carlo uncertainty.
## 5.16 Doob Decomposition: Drift Plus Martingale Noise
Many stochastic processes are not martingales. However, in discrete time, an adapted integrable process can be decomposed into a predictable finite-variation part and a martingale part.
For an adapted process $(X_n)$, define the predictable drift increments
$$
A_{n+1}-A_n
=
\mathbb E[X_{n+1}-X_n\mid\mathcal F_n],
\qquad A_0=0.
$$
Then define
$$
M_n=X_n-A_n.
$$
The process $M_n$ is a martingale. Indeed,
$$
\begin{aligned}
\mathbb E[M_{n+1}-M_n\mid\mathcal F_n]
&=\mathbb E[X_{n+1}-X_n\mid\mathcal F_n]
-\mathbb E[A_{n+1}-A_n\mid\mathcal F_n]\\
&=\mathbb E[X_{n+1}-X_n\mid\mathcal F_n]
-(A_{n+1}-A_n)\\
&=0.
\end{aligned}
$$
Therefore
$$
X_n=X_0+M_n+A_n
$$
is a decomposition into martingale noise and predictable drift.
::: {.example}
### Example 5.5: Stock under physical probability
In a binomial model under the physical probability $p$, the discounted stock satisfies
$$
\mathbb E^{\mathbb P}[\widetilde S_{n+1}-\widetilde S_n\mid\mathcal F_n]
=\widetilde S_n\left(\frac{p\nu+(1-p)d}{R}-1\right).
$$
Unless
$$
p\nu+(1-p)d=R,
$$
this drift is not zero. The Doob decomposition separates this predictable physical drift from the martingale innovation.
:::
## 5.17 Python Example: Decomposing a Process
The following simulation decomposes a random walk with drift into predictable drift plus martingale residual.
```{python}
rng = np.random.default_rng(5110)
num_paths = 5_000
N = 50
p_up = 0.56
# increments are +1 with probability p_up and -1 otherwise
increments = np.where(rng.random((num_paths, N)) < p_up, 1.0, -1.0)
X = np.column_stack([np.zeros(num_paths), increments.cumsum(axis=1)])
# predictable drift per step
mean_increment = 2 * p_up - 1
A = np.arange(N + 1) * mean_increment
M = X - A
summary = pd.DataFrame({
"time": np.arange(N + 1),
"E[X_n] empirical": X.mean(axis=0),
"A_n predictable drift": A,
"E[M_n] empirical": M.mean(axis=0),
})
summary.tail()
```
The empirical mean of $M_n$ should remain close to zero, while $A_n$ captures the linear drift.
## 5.18 Martingale Pricing and Backward Induction
In a binomial tree, the martingale pricing formula and backward induction are the same method written in two languages.
Suppose a derivative has value $V_{n+1}^u$ at the up successor node and $V_{n+1}^d$ at the down successor node. Then the time-$n$ value is
$$
V_n
=\frac{1}{R}\left(qV_{n+1}^u+(1-q)V_{n+1}^d\right).
$$
This is exactly the conditional-expectation formula
$$
V_n
=\frac{1}{R}\mathbb E^{\mathbb Q}[V_{n+1}\mid\mathcal F_n].
$$
Equivalently,
$$
\frac{V_n}{B_n}
=\mathbb E^{\mathbb Q}\left[\frac{V_{n+1}}{B_{n+1}}\mid\mathcal F_n\right].
$$
Thus the discounted derivative value is a martingale.
## 5.19 Python Example: Martingale Option-Value Process
The following code computes the full binomial value tree for a European call and verifies the discounted martingale recursion at every node.
```{python}
def binomial_call_value_tree(S0, K, u, d, R, N):
q = (R - d) / (u - d)
stock = []
value = []
for n in range(N + 1):
stock.append(np.array([S0 * (u ** j) * (d ** (n - j)) for j in range(n + 1)]))
terminal = np.maximum(stock[N] - K, 0.0)
value = [None] * (N + 1)
value[N] = terminal
for n in range(N - 1, -1, -1):
value[n] = (q * value[n + 1][1:] + (1 - q) * value[n + 1][:-1]) / R
return stock, value, q
S0 = 100
K = 100
u = 1.2
d = 0.8
R = 1.05
N = 4
stock, value, q = binomial_call_value_tree(S0, K, u, d, R, N)
checks = []
for n in range(N):
for j in range(n + 1):
discounted_now = value[n][j] / (R ** n)
discounted_next_conditional = (
q * value[n + 1][j + 1] / (R ** (n + 1))
+ (1 - q) * value[n + 1][j] / (R ** (n + 1))
)
checks.append({
"time": n,
"node j": j,
"discounted value now": discounted_now,
"conditional expected discounted next": discounted_next_conditional,
"difference": discounted_next_conditional - discounted_now,
})
pd.DataFrame(checks)
```
This computation should show that the discounted derivative value process is a martingale under $\mathbb Q$.
## 5.20 AI-Assisted Learning Components
::: {.ai-box}
### AI Prompt 5.1: Explain conditional expectation on a tree
Use an AI assistant to explain the following statement in three levels: intuitive, finite-state mathematical, and financial.
> $\mathbb E[X\mid\mathcal F_n]$ is the best estimate of $X$ using the information available at time $n$.
Then check whether the explanation clearly distinguishes unconditional expectation from conditional expectation.
:::
::: {.ai-box}
### AI Prompt 5.2: Audit a martingale proof
Give an AI assistant the proof of Theorem 5.2 and ask:
1. Where is the no-arbitrage condition $d<R<u$ used?
2. Where is the risk-neutral probability $q=(R-d)/(u-d)$ used?
3. Why is it important that $S_n$ is known at time $n$?
4. Does the proof still work under the physical probability $p$?
A correct answer should identify that $d<R<u$ guarantees $0<q<1$, and that the martingale property generally fails under $p$.
:::
::: {.ai-box}
### AI Prompt 5.3: Find the bug in martingale-checking code
Ask an AI assistant to review Python code that checks
$$
\mathbb E^{\mathbb Q}[\widetilde S_{n+1}\mid\mathcal F_n]=\widetilde S_n.
$$
Tell it to look specifically for:
- using $p$ instead of $q$;
- forgetting to divide by $R^{n+1}$;
- reversing the order of up and down children in the tree;
- checking unconditional expectation only instead of nodewise conditional expectation.
:::
::: {.ai-box}
### AI Prompt 5.4: Generate a counterexample
Ask an AI assistant to construct a one-step model where the undiscounted stock price is not a martingale but the discounted stock price is a martingale under $\mathbb Q$. Then verify the example by hand.
:::
## 5.21 Common Mistakes
1. **Confusing $\mathbb P$ and $\mathbb Q$.** The physical probability $\mathbb P$ describes real-world frequencies. The risk-neutral probability $\mathbb Q$ prices assets under no arbitrage.
2. **Forgetting the filtration.** Conditional expectation is always conditional on a specific information set. A statement such as $\mathbb E[X_{n+1}]=X_n$ is not the martingale property.
3. **Forgetting discounting.** Stock prices are usually not martingales under $\mathbb Q$. Discounted stock prices are martingales under $\mathbb Q$.
4. **Using future information in a trading strategy.** A trading strategy must be predictable or adapted in the appropriate sense. Strategies that see the future are not admissible.
5. **Misusing optional stopping.** Optional stopping requires assumptions. Unbounded doubling strategies are not valid arbitrage arguments.
6. **Checking only averages across all paths.** A martingale condition is nodewise and conditional. The correct check must be performed at each information cell.
## 5.22 Exercises
### Conceptual Exercises
1. Explain in your own words why a filtration is needed in mathematical finance.
2. Give an example of a random variable that is $\mathcal F_2$-measurable but not $\mathcal F_1$-measurable in a two-step binomial tree.
3. Explain why the martingale property is a conditional statement, not merely an unconditional statement.
4. In a risk-neutral binomial model, is the undiscounted stock price usually a martingale? Explain.
5. Why does the risk-neutral probability generally differ from the physical probability?
### Computational Exercises
6. Consider a one-step binomial model with
$$
S_0=50,
\qquad
\nu=1.3,
\qquad
d=0.7,
\qquad
R=1.04.
$$
Compute the risk-neutral probability $q$ and verify the discounted martingale condition.
7. In the same model, price a European call with strike $K=55$ by risk-neutral expectation.
8. In a two-step tree with $S_0=100$, $\nu=1.1$, $d=0.9$, $R=1.02$, and $K=100$, compute the value process of a European put at every node.
9. For Exercise 8, verify explicitly that the discounted put-value process is a martingale under $\mathbb Q$.
10. Construct a three-state one-period model and compute a conditional expectation with respect to a nontrivial partition of the state space.
### Proof Exercises
11. Prove the tower property directly in a finite probability space using partitions.
12. Prove that if $X_n=\mathbb E[Y\mid\mathcal F_n]$, then $(X_n)$ is a martingale.
13. Prove that the sum of two martingales is a martingale.
14. Let $(X_n)$ be a martingale and let $a,b$ be constants. Prove that $(aX_n+b)$ is a martingale.
15. Let $(X_n)$ be a martingale and define the stopped process
$$
X_n^\tau=X_{n\wedge \tau}.
$$
Prove that $(X_n^\tau)$ is a martingale when $\tau$ is a bounded stopping time.
### Python Exercises
16. Write a Python function that takes a finite probability space, a random variable, and a partition, and returns the conditional expectation on each state.
17. Write a Python function that checks the discounted martingale property at every node of a binomial stock tree.
18. Simulate a biased random walk and numerically construct its Doob decomposition.
19. Simulate stopped symmetric random walks for several upper and lower barriers. Compare the sample mean of the stopped value with the optional stopping prediction.
20. Price a European call using backward induction and then independently verify the time-zero value using the binomial distribution formula.
### AI-Assisted Exercises
21. Ask an AI assistant to explain why discounting is necessary in martingale pricing. Critique whether it correctly distinguishes prices from discounted prices.
22. Ask an AI assistant to produce an example of a non-martingale process. Then compute the conditional drift yourself and check the answer.
23. Give an AI assistant a flawed optional stopping argument based on a doubling strategy. Ask it to identify the missing assumptions.
24. Ask an AI assistant to generate Python code for binomial martingale verification. Test the code on at least two parameter choices and identify any errors.
25. Ask an AI assistant to compare the martingale property with the Markov property. Write a short correction if it confuses the two.
## 5.23 Chapter Summary
This chapter introduced the discrete-time martingale framework that underlies no-arbitrage pricing.
The main ideas are:
- a filtration $(\mathcal F_n)$ models information available over time;
- conditional expectation averages over states consistent with current information;
- a martingale has zero conditional drift;
- under a risk-neutral measure $\mathbb Q$, discounted traded asset prices are martingales;
- derivative prices can be written as conditional expectations of discounted terminal payoffs;
- backward induction in a binomial tree is a concrete form of martingale pricing;
- self-financing strategies preserve the martingale property of discounted wealth;
- optional stopping prevents bounded fair games from being turned into arbitrage by stopping rules;
- Doob decomposition separates predictable drift from martingale noise.
The next chapter uses these ideas to state the discrete-time Fundamental Theorem of Asset Pricing more systematically. In that theorem, no arbitrage, equivalent martingale measures, and market completeness become one unified mathematical structure.