A clean-room PyTorch replication of Han, Jentzen, E (PNAS 2018) — "Solving high-dimensional partial differential equations using deep learning" — applied to the multi-asset Black-Scholes PDE.
The headline: Monte Carlo's pricing variance scales as
| d | Deep BSDE |
MC oracle (10⁷ paths) | rel. err | train time | device |
|---|---|---|---|---|---|
| 1 | 10.4513 | 10.4524 ± 0.0064 | 0.011 % | 1555 s | CPU |
| 10 | 5.6387 | 5.6457 ± 0.0015 | 0.123 % | 790 s | CPU |
| 50 | 4.9134 | 4.9221 ± 0.0004 | 0.178 % | 461 s | GPU |
| 100 | 4.8705 | 4.8814 ± 0.0003 | 0.224 % | 552 s | GPU |
Against the brief's success criteria:
- 1-D Deep BSDE matches closed-form Black-Scholes to 0.011 % (target <0.5 %). ✔
- 100-D basket call matches 10⁷-path MC to 0.22 % (target <1 %). ✔
-
python eval/convergence_vs_dim.pyrenders the hero figure above. ✔ - Variance across three independent training seeds at
$d = 10$ : σ/μ = 0.03 %. ✔ - Delta hedge using learned
$Z$ reduces terminal P&L variance by 42–204 × across dimensions (see below). ✔
Under the risk-neutral measure the underlyings
The Deep BSDE algorithm parameterises the initial value
Full derivation with the Itô step and the martingale-representation
argument: docs/derivation.md.
Deep BSDE tracks the MC oracle to a fraction of 1 % across
Each marker is an independent Deep BSDE training run at the given
initial spot
Loss drops ~3 orders of magnitude over training. The learned
Animated version of the 100-D run:
docs/animations/training_100d.gif.
Three independent seeds at
The convergence table only checks
| d |
|
un-hedged |
hedged |
variance reduction |
|---|---|---|---|---|
| 1 | 0.637 (= |
15.55 | 1.09 | × 204 |
| 10 | 0.791 | 5.60 | 0.45 | × 156 |
| 100 | 0.996 | 2.12 | 0.33 | × 42 |
In 1-D the learned time-0 delta agrees with the closed-form
Black-Scholes delta
Ablation around the default schedule — learning rate, number of time
steps, mini-batch size. Deep BSDE is not balanced on a knife-edge:
across all three axes the relative error sits in a 0.1–0.3 % band,
except the one genuinely bad setting (lr = 1e-3, which is simply
too small for 4 000 iterations at
The whole point of the docs/derivation.md translation is that only
three callables change between PDEs: drift pde/allen_cahn.py + the
generic solver in bsde/generic_solver.py tackle the Allen-Cahn
benchmark from Han-Jentzen-E 2018 sec. 4.3:
The nonlinear term flips sign on transit to the BSDE generator
(pde/allen_cahn.py). Learned
Two practical lessons, worth naming for the next person:
-
Generator sign. The BSDE form of the PDE puts the nonlinearity
on the right-hand side of
∂_t u + ½ Tr(σσᵀ Hess u) + ∇u·μ = f. For Allen-Cahn this sendsu - u³over tou³ - u. Getting this backwards converges the solver to a physically wrong but loss-minimal solution (see commit history for the debug trail). -
BN in the Z-subnet. The paper's BN-heavy Z-subnet ZSubnet is fine
for Black-Scholes (linear
$f$ ) but is too unstable for$y^3 - y$ : BN at the output forces$Z \sim \mathcal{N}(0, I)$ per coordinate, which pushes$Y_n$ outside the stable region$|y| < 1$ on the first rollout step.SimpleZSubnet(no BN, Tanh activations) + tight gradient clipping stabilises training. Included as an opt-insubnet="plain"onGenericSolverConfig.
Side-by-side with a canonical Physics-Informed Neural Network
(Raissi, Perdikaris, Karniadakis 2019) on the same 1-D BS problem —
a
With normalised inputs, PINN converges to 0.02 % relative error
and is actually faster in wall-clock than Deep BSDE on this
problem (~2 min vs ~26 min). This is the honest finding: on a
smooth 1-D PDE with an easy terminal, PINN is hard to beat on raw
wall time. The documented fragility of PINN shows up elsewhere —
scale mismatch in inputs (without the
Deep BSDE training is dominated by per-iteration cost, not by a cost
that blows up with dimension. The right-hand panel shows the number of
MC paths needed to match each Deep BSDE relative error — the basket
average reduces per-path variance with
What this replication does not do, by design, and where it's weakest:
-
$Y_0$ is a point estimate, not a pricing surface. Each training run learns$u(0, S_0)$ at a single initial spot. The 1-D reconstruction plot above is five independent trainings — there is no amortised evaluation of$u(t, x)$ for arbitrary$(t, x)$ . A mesh-free extension (e.g. training with batched initial conditions) would fix this but is out of scope. -
Deep OTM is the hardest regime. At
$S_0 = 70$ (ATM strike 100) the relative error sits at 1.76 % even after tightening the$Y_0$ init range — the terminal-residual loss has little signal on$Y_0$ when$g(X_T)$ is zero on most paths. Deep BSDE prices OTM by path mass, and rare-payoff paths are under-represented in a 64–256-sample batch. -
Plain MC is very hard to beat on this payoff. An arithmetic basket
averages out per-path noise, so MC's variance shrinks with
$d$ rather than growing — see the right panel of the wall-clock plot. The method's true advantage lies on payoffs where MC's variance blows up (American options, path-dependent claims, nonlinear generators) — those are scope extensions, not covered here. -
Z-quality at large
$d$ is not as tight as$Y_0$ -quality. The delta-hedge study below validates the learned$Z$ against closed-form$N(d_1)$ in 1-D (agreement to 4 decimal places) and shows 156× variance reduction at$d = 10$ , but the$d = 100$ hedge only reaches 42× variance reduction — the$Z$ -subnetworks there are near-converged but still imperfect. Plausible improvements: larger batch size (currently 64 at$d = 100$ ), longer training after the$Y_0$ plateau, or finer time discretisation. -
Batch-norm during inference. The
$Z$ -subnetworks are trained intrain()mode with BN statistics; evaluation of$Y_0$ itself is a read of a learnable parameter and is unaffected, but using the learned$Z_n$ on new inputs would require careful BN-eval handling. -
Architecture and schedules are not tuned. Hidden width
$d+10$ and the LR milestones follow the paper; no search has been performed. The headline errors are likely sub-optimal by a factor of 2–3 with mild tuning.
deep-bsde-black-scholes/
├── pde/ Black-Scholes PDE: coefficients, payoffs, 1D closed form
├── bsde/ Euler-Maruyama forward SDE + Deep BSDE network
├── baselines/ Vanilla Monte-Carlo pricer (exact log-Euler, antithetic)
├── eval/ Convergence / variance / wall-clock / reconstruction
├── docs/ PDE → BSDE derivation, training-curve GIF
├── figures/ Rendered plots (hero figure, results table, etc.)
├── runs/ Cached training artifacts (JSON + state_dict)
├── tests/ Pytest suite (28 tests, all passing)
└── train.py CLI training entry point
python -m venv .venv
# Windows bash: source .venv/Scripts/activate
# macOS / Linux: source .venv/bin/activate
pip install -e ".[dev]"
# Unit tests — closed-form, SDE moments, MC, Deep BSDE loss / integration
pytest
# Single training run (1-D sanity)
python train.py --d 1 --iterations 2000 --output-dir runs/d1_seed0
# Regenerate every figure in the README from cached artifacts
# (auto-trains anything missing; ~1 h full fresh clone with a CUDA GPU)
python eval/make_all.pyEach training run is fully reproducible from --seed: the torch
global RNG, the per-batch path sampler, and the
- Han, J.; Jentzen, A.; E, W. (2018). Solving high-dimensional partial differential equations using deep learning. PNAS 115(34), 8505–8510.
- E, W.; Han, J.; Jentzen, A. (2017). Deep learning-based numerical methods for high-dimensional parabolic PDEs and BSDEs. arXiv:1706.04702.
- Black, F.; Scholes, M. (1973). The pricing of options and corporate liabilities. J. Polit. Econ. 81(3), 637–654.
- Pardoux, É.; Peng, S. (1990). Adapted solution of a backward stochastic differential equation. Systems Control Lett. 14, 55–61.
- El Karoui, N.; Peng, S.; Quenez, M. C. (1997). Backward stochastic differential equations in finance. Math. Finance 7(1), 1–71.
MIT. See LICENSE.








