A portfolio of 100 loans
Each loan either defaults this year or does not: a Bernoulli trial with (lesson 5.2.2). Assume for now that the loans default independently of each other. Then the number of defaults is .
Many trials, each with a small chance: the Poisson approximation of lesson 5.2.3 applies, with . Both pmfs, to four decimals:
| defaults | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|---|---|---|---|---|---|---|---|---|---|
| binomial | 0.1326 | 0.2707 | 0.2734 | 0.1823 | 0.0902 | 0.0353 | 0.0114 | 0.0031 | 0.0007 |
| Poisson | 0.1353 | 0.2707 | 0.2707 | 0.1804 | 0.0902 | 0.0361 | 0.0120 | 0.0034 | 0.0009 |
A year with no defaults has probability . One or two defaults are the most likely counts, and the two rows never differ by more than 0.003.
Five or more defaults
Suppose the bank recovers 40% of a defaulted loan, so each default loses $600,000; desks call the 60% the loss given default. Then five or more defaults lose $3,000,000 or more.
By lesson 5.2.1, . The binomial gives 0.0508 and the Poisson 0.0527. The Poisson has no upper limit and a slightly longer tail, so here it errs on the cautious side.
Try it
The first two lines print the table. The third gives as sf(4) for both distributions.
The last line is the off-by-one trap of lesson 5.2.2: binom.sf(5, …) is , which leaves out .
How many defaults to plan for
A risk manager asks the question the other way round: what is the smallest count exceeded in at most one year in a hundred? That is the smallest with , the 99% quantile of .
Here falls short and does not, so the answer is 6 defaults, or $3,600,000 of losses. The Poisson gives 6 as well. Case study 5.3.5 reads quantiles of daily returns the same way, as value at risk.
Try it
The cell simulates 100,000 years of the 100 loans with a fixed seed. In this run 0.0502 of the years have five or more defaults, against the exact 0.0508.
binom.ppf(0.99, …) returns the 99% quantile. The cell prints the distribution function on both sides of it, the Poisson's quantile and the loss.
When defaults are not independent
Real defaults are not independent: in a recession many borrowers struggle at once. Here is a simple model of that. The year is good with probability 0.8, and then each loan defaults with probability 1%; it is bad with probability 0.2, and then 6%.
Within each kind of year the loans default independently, so is in a good year and in a bad one. The average default probability is , the same 2% as before.
The law of total probability (lesson 5.1.3) splits on the kind of year:
That is almost three times the independent 0.0508. Quiet years become more likely too: no defaults at all has probability 0.2932, against 0.1326. The 99% quantile moves from 6 defaults to 10.
Defaults among 100 loans with the same 2% average. Independent, five or more happen with probability 0.051. Clustered in bad years, the pmf is taller at 0 and has a long tail: five or more has probability 0.147.
The strength of the dependence between defaults is measured by their correlation, which module 5.5 defines. A model that assumes independence understates the chance of many defaults together, which is the event that matters most to the bank.
Try it
The first lines check the 2% average and compute the tail by total probability. np.cumsum builds the distribution function of the clustered count, and argmax finds the first where it reaches 0.99.
The simulation first draws the kind of year, then the defaults. In this seeded run 0.1471 of the years have five or more, and the years still average 2.0 defaults.
A stock that goes up or down
The same tools price an option. Take the call of case study 2.4.6: stock price , strike , years, a continuous rate and volatility .
In the one-period binomial model, the stock has two possible prices at : if it goes up, if it goes down. A common choice, which case study 5.11.4 also uses, is and . Here and , so the stock ends at 115.19 or 86.81.
A bond pays $1 at and costs today, by continuous discounting (case study 1.4.6). The call pays (case study 1.1.5): 15.19 if the stock goes up, nothing if it goes down.
One step of half a year. The branch labels are the risk-neutral probabilities found below; the call's price today, 7.75, comes from replication.
Replicating the call
Case study 3.3.4 priced a payoff by copying it with assets that trade. Here two assets cover two states. With rows down and up and columns the bond and the stock, the payoff matrix is
Hold bonds and (delta) shares. Copying the call means and . Subtracting the first equation from the second gives , and then : borrow by selling bonds.
Rule: Replicating a one-step payoff
and are the payoffs in the up and down states. shares and bonds pay exactly and . By the law of one price (case study 3.3.4), the payoff costs what they cost.
The portfolio costs . So the call is worth $7.75. Desks call the option's delta, the number of shares that hedges it.
Try it
D has one row per state and one column per asset, as in case study 3.3.4. np.linalg.solve finds the bonds and shares that copy the call, and prices @ h is their cost today.
The risk-neutral probability
Case study 3.3.4 also found state prices, the price today of $1 paid in one state only, by solving . Here they are and . They add up to 0.985112, the bond's price.
Divided by the bond's price, they become and .
Both are positive and they add up to 1, so they form a pmf on the two states (lesson 5.2.1). It is a Bernoulli distribution for an up move (lesson 5.2.2). These are the risk-neutral probabilities.
Rule: One-step risk-neutral pricing
The price is a probability-weighted average of the payoffs, with weights and , discounted at the risk-free rate. It equals the cost of the replicating portfolio. lies between 0 and 1 only when .
The formula for comes from the stock's own price: . With the weights and , the stock grows on average like money in the bond: 101.5113 at .
For the call, , as replication found. Lesson 5.3.1 calls such a weighted average an expectation, and later courses write the price as , with for the risk-neutral probabilities.
Try it
The cell solves for the state prices, divides by their sum, and compares with the formula for .
The last lines price the call with and check that the weights reproduce the stock's growth at the risk-free rate.
Case study 3.3.4's three-state market had risk-neutral probabilities 0.2577, 0.4639 and 0.2784, a pmf on three states. Its exercise has a two-state market: the stock at 80 or 125 from 98.75, and the bond at 0.97. The same rule gives and a call price of 11.75.
Try it
The two-state market of case study 3.3.4's exercise: the bond and the stock, with no call. The call with strike 100 pays 25 in the up state only, so it costs 25 times that state's price.
The real chance of an up move does not enter
Neither replication nor used the probability that the stock actually goes up. Suppose it is 0.6. Discounting the average payoff with that weight gives , which is not the price.
If the call traded at $8.98, you could sell it and buy the replicating portfolio for 7.7512, keeping 1.2288 today. At the portfolio pays exactly what the call sold owes, in both states. The view on the stock's direction is already in its price ; the option adds nothing to it.
The put, and put–call parity
The put with strike 100 pays nothing if the stock goes up and if it goes down. Its price is . Its replicating portfolio is short 0.4647 shares and long 53.53 bonds.
Put–call parity from case study 3.3.4 holds: , and .
One step is not enough
Case study 2.4.6 priced the same call by Black–Scholes at 6.3710. The one-step price, 7.7512, is 1.3801 too high: two final prices are a crude picture of a stock over six months.
The cure is more steps. Split the half year into steps, each up or down with probability : the number of up moves is then (lesson 5.2.2). Case study 5.11.4 builds that tree and shows the price closing in on 6.3710 as grows.
Try it
The first line compares the call's price with the discounted average under the real probability 0.6. The next lines price the put, check parity and give the put's shares and bonds.
The last line is the Black–Scholes price of case study 2.4.6.
Try it
The first line is the bad quote: , then the "probability" it implies. The second shows nan from a probability typed as 2. The third is the that gives.
One-step binomial pricing
Write two functions.
risk_neutral_q(u, d, r, T)returns . RaiseValueErrorunless : otherwise the bond or the stock wins in both states, and is not a probability.one_step(S0, u, d, r, T, payoff)prices a payoff paid at , given as a function of the final stock price. It returns(price, shares, bonds): the price today and the replicating portfolio, with bonds that pay 1 at . It raisesValueErrorin the same cases.
The tests use this case study's call and put, put–call parity, and the stock and the bond themselves. They add a payoff of 1 when the stock ends above 100, case study 3.3.4's two-state market, and moves that allow an arbitrage.
See the tests
import math
U = math.exp(0.2 * math.sqrt(0.5)) # the call of case study 2.4.6: sigma = 0.2, T = 0.5
D = 1 / U
def call(S):
return max(S - 100, 0)
def put(S):
return max(100 - S, 0)
def test_q():
"""With u = e^(0.2√0.5), d = 1/u, r = 3% and T = 0.5, q is about 0.5180"""
expect_close(risk_neutral_q(U, D, 0.03, 0.5), 0.5179585268029778, what="risk_neutral_q", rel=1e-9)
def test_call():
"""The one-step call costs 7.7512: 0.5353 shares and −46.4703 bonds"""
price, shares, bonds = one_step(100, U, D, 0.03, 0.5, call)
expect_close(price, 7.751159552620581, what="price of the call", rel=1e-9)
expect_close(shares, 0.5352965311073328, what="shares", rel=1e-9)
expect_close(bonds, -46.47034688926673, what="bonds", rel=1e-9)
def test_put_and_parity():
"""The put costs 6.2624, short 0.4647 shares, and C − P = S₀ − Ke^(−rT)"""
p, shares, bonds = one_step(100, U, D, 0.03, 0.5, put)
expect_close(p, 6.26235351292685, what="price of the put", rel=1e-9)
expect_close(shares, -0.4647034688926673, what="shares in the put's portfolio", rel=1e-9)
c = one_step(100, U, D, 0.03, 0.5, call)[0]
expect_close(c - p, 100 - 100 * math.exp(-0.015), what="C - P", rel=1e-9)
def test_stock_and_bond():
"""The stock's own payoff costs S₀ (1 share, 0 bonds); a payoff of 1 costs e^(−rT) (1 bond)"""
price, shares, bonds = one_step(100, U, D, 0.03, 0.5, lambda S: S)
expect_close((price, shares, bonds), (100.0, 1.0, 0.0), what="(price, shares, bonds) of the stock", abs_tol=1e-9)
price, shares, bonds = one_step(100, U, D, 0.03, 0.5, lambda S: 1.0)
expect_close((price, shares, bonds), (math.exp(-0.015), 0.0, 1.0), what="(price, shares, bonds) of the bond", abs_tol=1e-9)
def test_case_study_334():
"""Case study 3.3.4's two-state market (stock 80 or 125 from 98.75, bond 0.97): the call costs 11.75"""
price, shares, bonds = one_step(98.75, 125 / 98.75, 80 / 98.75, -math.log(0.97), 1.0, call)
expect_close(price, 11.75, what="price of the call", rel=1e-9)
expect_close(shares, 25 / 45, what="shares", rel=1e-9)
expect_close(bonds, -80 * 25 / 45, what="bonds", rel=1e-9)
def test_digital():
"""A payoff of 1 when the stock ends above 100 costs e^(−rT)·q = 0.5102"""
price, _, _ = one_step(100, U, D, 0.03, 0.5, lambda S: 1.0 if S > 100 else 0.0)
expect_close(price, 0.5102471289728264, what="price of the digital payoff", rel=1e-9)
def test_bond_beats_stock():
"""u = 1.01 and d = 0.99 with e^(rT) = 1.0151: the bond beats the stock in both states, so ValueError"""
try:
risk_neutral_q(1.01, 0.99, 0.03, 0.5)
except ValueError:
return
raise AssertionError("expected ValueError: q would be 1.2557, not a probability")
def test_stock_beats_bond():
"""u = 1.2 and d = 1.05 with e^(rT) = 1.0151: the stock beats the bond in both states, so ValueError"""
try:
one_step(100, 1.2, 1.05, 0.03, 0.5, call)
except ValueError:
return
raise AssertionError("expected ValueError: q would be negative")
def test_bad_moves():
"""d at or above u, or d at or below 0, raises ValueError"""
for u, d in ((1.1, 1.1), (0.9, 1.1), (1.2, 0.0), (1.2, -0.5)):
try:
risk_neutral_q(u, d, 0.03, 0.5)
except ValueError:
continue
raise AssertionError(f"expected ValueError for u = {u}, d = {d}")
Summary card
- With independent defaults, each with probability , the number of defaults among loans is , close to when is small. For 100 loans at 2%, five or more has probability 0.0508 (Poisson 0.0527), and the 99% quantile is 6 defaults.
- With the same 2% average but defaults clustered in bad years, five or more has probability 0.1474: independence understates joint defaults.
- One-period binomial model: the stock ends at or . A payoff is copied by shares and bonds, and its price is with .
- The real probability of an up move does not enter the price; is a probability only when .
- For the call of case study 2.4.6, one step gives 7.7512 against Black–Scholes 6.3710; more steps (case study 5.11.4) close the gap.