The valuation algorithm has exactly three moves, repeated:
- Terminal condition. At maturity, the bond is worth its redemption value (par) at every node.
- Roll back one step. At node (t, i), take the two child values one step ahead, add the coupon paid at that date to each, average them with the 50/50 probabilities, and discount one period at the node's own rate:
V_raw[t, i] = 0.5 × ( (V[t+1, i+1] + C) + (V[t+1, i] + C) ) / (1 + r[t, i]) - Apply the exercise test, only on option dates. For a callable:
V[t, i] = min(V_raw[t, i], call price). For a putable:V[t, i] = max(V_raw[t, i], put price). On non-option dates,V[t, i] = V_raw[t, i].
Three details decide whether you get this right. The coupon travels with the roll-back, not with the node value, a node value is ex-coupon, and the coupon due at t+1 is added to the child values as you discount them. The exercise test applies to the ex-coupon value, because the holder receives the coupon due on the exercise date and then the bond is redeemed. And the option is applied at every option date on the way back, which is what makes it Bermudan and what produces the shadow effect.
In words: min(raw, 100) says the issuer refinances whenever the bond it owes you is worth more than the price at which it can buy it back. Not malice: arithmetic. A continuation value of 101.98 extinguishable for 100 saves 1.98 points, and a treasurer who declines is leaving money on the table. Symmetrically max(raw, 100) says you hand the bond back whenever it is worth less than what the issuer contractually owes you for it.
Advertisement
How does path enumeration give the same value?
There is a second route to the same number, and running it once is worth the half hour. Backward induction rolls a value back through the lattice. Path enumeration produces the identical number for a bond with no exercise, it shows what a tree value actually is, and it explains exactly why the coded track uses Monte Carlo for mortgages.
A three-period tree has four paths. Rates are r[0,0] from year 0 to 1, r[1,i] from 1 to 2, and r[2,i] from 2 to 3, so the path is fixed by the two branchings that happen before the final rate is read: down-down, down-up, up-down and up-up, each with probability 1/4 under the 50/50 tree measure. Along one path the bond is an ordinary certain cash-flow stream, discounted at a sequence of one-year rates you can read straight off the path:
V_path = Σ_t CF_t / [ (1 + r₀)(1 + r₁)…(1 + r_{t-1}) ]
V = (1/4) Σ_paths V_path
That average is exactly what backward induction computes, and the equality is not a coincidence of these numbers. Rolling back one step is a conditional expectation over the two children; iterating it is the tower property of expectations, so the lattice value is the expected discounted cash flow over all paths, computed by folding rather than by enumerating. Worked Example 9 runs both routes on the three-year 5.50% note and gets 102.199708126 each way, to nine decimals.
Enumeration is the wrong algorithm for a large tree, and knowing why is the point. A recombining tree with n steps has n+1 terminal nodes and roughly n²/2 nodes in total, so backward induction is quadratic in n. Path enumeration is 2ⁿ: a 30-step monthly tree has 496 nodes and 1.07 billion paths. Where enumeration earns its place is the other thing it shows you, the distribution rather than the mean, which is what a risk report needs when the average is not the interesting part.
Why does pathwise averaging break once exercise enters?
Pathwise averaging does break, and not gently. The moment an exercise test enters, averaging path values stops being valid. Along a single path the whole rate history is visible, so a naive rule ("redeem at whichever date leaves the issuer better off") hands the issuer perfect foresight it does not have. The real exercise test compares the call price against a continuation value, which is a conditional expectation over the sub-tree from that node forward, and a conditional expectation is not a property of any one path. Worked Example 9 measures the error. The same note callable at par at the end of year 1 is worth 101.141557 by backward induction and 101.096270 by the perfect-foresight pathwise route, a bias of 0.045287 points or about 4.5 basis points of price. The error always runs the same way: it over-values the option and therefore under-values the bond to its holder.
Why do mortgages need a different tool?
Mortgages need a different tool, and the reason is worth stating precisely. Everything above assumes the cash flows depend only on where the rate is, never on how it got there. A callable bond satisfies that. A mortgage pool does not. Prepayment responds to burnout, the observation that a pool which has already lived through one refinancing wave contains borrowers who did not take it and are less likely to take the next, so this month's speed depends on the path of rates to date and not only on today's level. A path-dependent cash flow cannot be folded back through a recombining lattice, because two paths arriving at the same node carry different remaining balances and the node no longer has a single value.
How does Monte Carlo replace the tree?
The Monte Carlo answer is the pathwise algorithm above with the enumeration replaced by sampling: simulate a few thousand rate paths from a calibrated model, run the prepayment model forward along each one carrying its own balance and burnout state, discount each path's realised cash flows at that path's own short rates, and average. The estimate converges at 1/√N, so four times the paths buys half the standard error. That is slow enough to make variance reduction standard rather than optional. Antithetic pairs run each path alongside its mirror image; control variates price an instrument you can value in closed form alongside the target, then correct the target by the known error. The single non-negotiable check is the same one the tree has: the simulation must reprice the benchmark bonds it was calibrated to, and an implementation that cannot return par on a par bond is not yet a valuation model. Building and vectorising that simulation belongs to the quant-code track, which owns the engine; what belongs here is the ability to say why a lattice was the right tool for the callable and the wrong one for the pool.