Exercise · m05_kyle.py
Kyle (1985) and Glosten-Milgrom (1985)
not run yet
Not saved: sign up to keep your code"""Exercise 5.2: Kyle (1985) and Glosten-Milgrom (1985) (notes.md §5.3-5.4).
Kyle, one period. v ~ N(p0, sigma_v^2) is the liquidation value, known only
to the insider. Noise traders submit u ~ N(0, sigma_u^2), independent of v.
The insider submits x = beta (v - p0). The market maker sees only total
order flow y = x + u and sets p = p0 + lam y = E[v | y].
Proposition 5.3: lam = sigma_v / (2 sigma_u), beta = sigma_u / sigma_v,
insider expected profit sigma_v sigma_u / 2, Var(v | y) = sigma_v^2 / 2.
Glosten-Milgrom, one trade. v in {v_low, v_high}, P(v_high) = theta. A
fraction mu of arriving traders is informed (buys iff v = v_high, else
sells); the others buy or sell with probability 1/2 each. A competitive
dealer quotes ask = E[v | buy] and bid = E[v | sell] (Proposition 5.2).
Check:
cd exercises && .venv/bin/python -m pytest modules/M05-intraday-execution/tests
"""
from __future__ import annotations
import numpy as np # noqa: F401
def kyle_equilibrium(sigma_v: float, sigma_u: float) -> dict:
"""Return {"lam", "beta", "insider_profit", "posterior_var"} from Proposition 5.3."""
raise NotImplementedError
def simulate_kyle(p0: float, sigma_v: float, sigma_u: float, n: int, seed: int = 0, beta: float | None = None, lam: float | None = None) -> dict:
"""Simulate n independent one-period games.
rng = np.random.default_rng(seed); draw Z1 then Z2 as two length-n standard
normal arrays; v = p0 + sigma_v Z1; u = sigma_u Z2; x = beta (v - p0);
y = x + u; p = p0 + lam y. beta and lam default to the equilibrium values
when None (use them to test off-equilibrium strategies).
Return a dict with numpy arrays "v", "u", "x", "y", "p" and
"profit" = (v - p) * x, the insider's realised profit per game.
"""
raise NotImplementedError
def estimate_lambda(v: np.ndarray, y: np.ndarray) -> float:
"""OLS slope, with intercept, of v on y: sum (y - ybar)(v - vbar) / sum (y - ybar)^2.
In data, v is the price after the information has come out, so this is the
empirical price-impact regression of later price on signed order flow.
"""
raise NotImplementedError
def glosten_milgrom_quotes(v_high: float, v_low: float, theta: float, mu: float) -> tuple[float, float]:
"""(bid, ask) = (E[v | sell], E[v | buy]) by Bayes' rule (Proposition 5.2)."""
raise NotImplementedError
def simulate_gm_dealer_pnl(v_high: float, v_low: float, theta: float, mu: float, n: int, seed: int = 0) -> tuple[float, float]:
"""Simulate n independent single-trade rounds at the Glosten-Milgrom quotes.
Each round: draw v (v_high w.p. theta), draw informed (w.p. mu); an informed
trader buys iff v = v_high; an uninformed one buys w.p. 1/2. The dealer's
P&L is ask - v on a buy and v - bid on a sell.
Return (mean P&L, standard error of the mean). Zero-profit quotes give a
mean indistinguishable from 0.
"""
raise NotImplementedError
No runs yet
The stub's functions raise
NotImplementedError until you write them. Fill in one, press
Run tests, and watch its tests turn green.Reference solution
Available after your first run, with an account approved for code runs.