Chapter 14 Laboratory — Module 14: The Market Itself¶

Mathematical Foundations of Modern Finance · Part IV · Week 14

Four panels: the equilibrium panel, the Kyle price-impact auction, the margin spiral, and the capstone. This is the course's closing module — the committee's opening question, where do the prices come from?, answered with the full toolkit in hand.

Seeds: 20261401–20261404.

In [1]:
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams.update({"figure.figsize": (7, 4.2), "axes.grid": True,
                     "grid.alpha": 0.3, "font.size": 11})
BRASS, INK = "#B4884A", "#0F1E3D"
import mfmf_engine_ch14 as eng

E1 — Equilibrium: where prices come from (supports LOS 14.1–14.2)¶

Reverse-engineer Chapter 1's market to a representative agent's preferences: the state prices imply $(\gamma, \beta) = (1.41, 1.026)$. The valuation objects the whole book took as given are, in the end, outputs of the optimization the book described.

In [2]:
r1 = eng.E1_equilibrium()
print(f"Implied risk aversion gamma : {r1['gamma']:.3f}   (book: 1.41)")
print(f"Implied time preference beta: {r1['beta']:.3f}   (book: 1.026)")
print(f"Riskless rate Rf            : {r1['Rf']:.4f}")
print(f"Equity premium              : {r1['equity_premium']:.4f}")
Implied risk aversion gamma : 1.409   (book: 1.41)
Implied time preference beta: 1.026   (book: 1.026)
Riskless rate Rf            : 1.0500
Equity premium              : 0.0300

E2 — The Kyle auction (supports LOS 14.3)¶

With value uncertainty $\Sigma_0 = 5$ and noise $\sigma_u = 20$, the price-impact coefficient is $\lambda = 0.125$ — each unit of net flow moves price one-eighth of a point, and market depth is $1/\lambda = 8$. Trading at twice the equilibrium intensity strictly reduces the insider's profit.

In [3]:
r2 = eng.E2_kyle()
print(f"Price-impact lambda : {r2['lambda']:.4f}   (book: 0.125)")
print(f"Market depth 1/lambda: {r2['market_depth']:.1f}")
print(f"Transfer table (price move by net flow): {r2['transfer_table']}")
print(f"Informed profit, optimal : {r2['profit_optimal']:.3f}")
print(f"Informed profit, at 2*beta: {r2['profit_at_2beta']:.3f}")
print(f"Greed reduces profit: {r2['greed_reduces_profit']}")
Price-impact lambda : 0.1250   (book: 0.125)
Market depth 1/lambda: 8.0
Transfer table (price move by net flow): {50: 6.25, -50: -6.25, 0: 0.0}
Informed profit, optimal : 10.012
Informed profit, at 2*beta: 0.122
Greed reduces profit: True

E3 — The margin spiral (supports LOS 14.4–14.5)¶

A funding shock is amplified by the feedback factor $1/(1-k)$. As $k \to 1$ the amplification diverges — a liquidity regime change. Find the $k$ at which a 2% shock produces a 5% realized loss.

In [4]:
r3 = eng.E3_margin_spiral()
for k, d in r3['by_k'].items():
    print(f"k = {k}: amplification {d['amplification']:.2f}x, realized loss {d['realized_loss']:.1%}")
print(f"\nk for a 2% shock -> 5% loss: {r3['k_for_2pct_to_5pct']:.2f}")

ks = np.linspace(0, 0.95, 100)
amp = 1/(1-ks)
fig, ax = plt.subplots()
ax.plot(ks, amp, color=INK, lw=2)
ax.axvline(r3['k_for_2pct_to_5pct'], color=BRASS, ls="--", lw=1.5, label="2%->5%")
ax.set_xlabel("feedback k"); ax.set_ylabel("amplification 1/(1-k)")
ax.set_title("E3: the loss spiral diverges as k -> 1")
ax.legend(); plt.tight_layout(); plt.show()
k = 0.0: amplification 1.00x, realized loss 2.0%
k = 0.3: amplification 1.43x, realized loss 2.9%
k = 0.6: amplification 2.50x, realized loss 5.0%
k = 0.9: amplification 10.00x, realized loss 20.0%

k for a 2% shock -> 5% loss: 0.60
No description has been provided for this image

E4 — The capstone: the agenda as one problem family (supports LOS 14.6)¶

The course closes where it opened: the Meridian agenda, each item a configuration of the book's primitives, each resolved by an identifiable subset of chapters — with its number now in hand.

In [5]:
r4 = eng.E4_capstone()
print(f"The Meridian agenda ({r4['items']} items):\n")
for item, d in r4['agenda'].items():
    chs = ", ".join(f"Ch{c}" for c in d['chapters'])
    print(f"{item}")
    print(f"    -> {chs}: {d['answer']}\n")
The Meridian agenda (6 items):

1. Price and approve the collar
    -> Ch4, Ch5, Ch7, Ch8: -2.7574

2. Accept the private-asset valuation
    -> Ch3, Ch4, Ch12: 151.5

3. Rebalance toward policy weights
    -> Ch9, Ch10: 16.5/37/46.5

4. Commit now or wait
    -> Ch11: hurdle > NPV

5. Ratify the risk limit
    -> Ch13: ES, not VaR

(All) Where do prices come from?
    -> Ch14: (gamma,beta)=(1.41,1.026)

Validation checks¶

Every laboratory report must reproduce these; a report whose checks do not pass is returned ungraded.

In [6]:
checks = eng.validation_checks()
for k, v in checks.items():
    if k.startswith("_"): continue
    print(f"[{'PASS' if v else 'FAIL'}] {k}")
assert checks["ALL_PASS"], "Validation failed — do not submit."
print("\nAll Module validation checks pass.")
[PASS] V1_gamma_1.41
[PASS] V2_beta_1.026
[PASS] V3_kyle_lambda_0.125
[PASS] V4_greed_reduces_profit
[PASS] V5_spiral_diverges
[PASS] ALL_PASS

All Module validation checks pass.