Chapter 11 Laboratory — Module 11: The Timing Desk¶
Mathematical Foundations of Modern Finance · Part III · Week 11
Four panels: the Snell envelope, the American-option panel, the smooth-pasting panel, and the platform (commit-or-wait) panel. Reproduces the American 90-put at 1.826 and the perpetual boundary at 66.0.
Seeds: 20261101–20261104.
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_ch11 as eng
E1 — The American put and the Snell envelope (supports LOS 11.2–11.3)¶
Pricing $\max(K - S, 0)$ with the right to exercise early gives the American 90-put at 1.826 — an early-exercise premium of 0.103 over the European value 1.7228.
r1 = eng.E1_american_put()
print(f"American 90-put : {r1['american_90put']:.4f} (book: 1.826)")
print(f"European 90-put : {r1['european_90put']:.4f}")
print(f"Early-exercise premium: {r1['early_exercise_premium']:.4f}")
American 90-put : 1.8258 (book: 1.826) European 90-put : 1.7228 Early-exercise premium: 0.1031
E2 — When does the call's exercise region appear? (supports LOS 11.4)¶
With no dividend, early exercise of an American call is never optimal (the region is empty). As the dividend rises, the exercise region materializes.
r2 = eng.E2_dividend_call()
print(f"Call region at delta=0 : {r2['call_region_at_delta_0']}")
print(f"Call region at delta=3% : {r2['call_region_at_delta_3pct']}")
print(f"Call price (no div / div) : {r2['call_price_no_div']:.4f} / {r2['call_price_div']:.4f}")
Call region at delta=0 : False Call region at delta=3% : True Call price (no div / div) : 4.4810 / 3.3847
E3 — Smooth pasting (supports LOS 11.5)¶
For the perpetual put, drag the exercise boundary and watch the attained value. It is maximized exactly at the smooth-pasting boundary $S^\* = 66.0$.
r3 = eng.E3_smooth_pasting()
print(f"Optimal boundary S* : {r3['optimal_boundary']:.2f} (book: 66.0)")
print("Attained values at trial boundaries:")
for b, v in r3['values_at_boundaries'].items():
print(f" boundary {b}: value {v:.4f}")
Optimal boundary S* : 66.03 (book: 66.0) Attained values at trial boundaries: boundary 60.0: value 7.3465 boundary 66.0: value 7.6415 boundary 75.0: value 6.7916
E4 — The platform: commit or wait (supports LOS 11.6)¶
The committee's item four. The option to wait carries a hurdle multiple above simple NPV: invest only when value exceeds $\beta_1/(\beta_1-1)$ times the cost.
r4 = eng.E4_platform()
print(f"beta1 : {r4['beta1']:.4f}")
print(f"Hurdle multiple : {r4['hurdle_multiple']:.4f}")
print(f"Investment trigger : ${r4['investment_trigger']:.1f}M")
print(f"Option value F : ${r4['option_value_F']:.1f}M")
print(f"NPV now : ${r4['npv_now']:.1f}M")
beta1 : 1.5684 Hurdle multiple : 2.7594 Investment trigger : $74.0M Option value F : $11.5M NPV now : $3.2M
Validation checks¶
Every laboratory report must reproduce these; a report whose checks do not pass is returned ungraded.
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_american_90put_1.826 [PASS] V2_early_exercise_premium [PASS] V3_perpetual_boundary_66 [PASS] V4_call_region_grows_with_div [PASS] ALL_PASS All Module validation checks pass.