What is adjoint AD, and why does a bank care?
The record-once, replay-twice idea behind every number this engine produces — the mental model, before a single line of code.
You run a desk with a book of options exposed to a few hundred market inputs — spot prices, volatilities, interest rates, correlations. Before you can hedge any of it, you need one more number for every single input: how much the book's value moves if that one input wiggles. Not for the three inputs someone happened to worry about this morning — for all of them, every morning, before the market opens.
So: how do you get the price of a trade and its sensitivity to every input that could move it, without pricing that trade hundreds of times over?
The whole story
Reverse-mode automatic differentiation isn't a machine-learning invention wearing a finance costume — it predates the deep-learning wave by decades. Quantitative finance had its own name for the same technique, "adjoint algorithmic differentiation" (AAD), popularized by Giles and Glasserman's 2006 paper Smoking Adjoints, years before "backprop" became a word every programmer knew.
The two ways to answer the question
1. The slow way: bump and revalue
For each input you care about, nudge it up a little and reprice the whole
trade; nudge it down and reprice again; subtract and divide by the size of
the nudge. Each nudge is a full Monte-Carlo valuation, so pricing N inputs
this way costs 1 + 2N valuations — one base case, plus two reprices per
input. Simple to understand, and it gets slower every time someone adds a
risk factor to the book.
2. The fast way: record once, replay twice
NablaTensor instead records the valuation exactly once. Every add, multiply,
exp, log your valuation code performs gets appended to a flat tape,
instead of being computed as a plain number and forgotten. One forward pass
over that tape, in the order the code actually ran, gives the price. One
reverse pass over the same tape — applying the chain rule backwards, one
recorded operation at a time — gives the sensitivity to every input that fed
into it, in a single pass, regardless of how many inputs there were.
On this engine's own published benchmark — an Asian call, 252 daily fixings, fp64, 2,000,000 scenarios — one reverse sweep for the price and five Greeks took 1.11 s. Bump-and-revalue for the same five Greeks took 10.76 s across 11 replays: 9.7× slower, and the gap only widens as more risk factors join the book.
Try it yourself
No code yet, just arithmetic: if this book had 500 risk factors instead of
5, how many full revaluations would bump-and-revalue need? (1 + 2×500 = 1,001.) How many would the reverse sweep need? Still one. That gap
— constant cost, no matter how many inputs you're differentiating with
respect to — is the entire reason this engine exists.
▶️ Run it
Not yet — there's no code on this page on purpose. Module 1 is where you record your first tape and price your first option. This page is the mental model everything after it builds on.
⚠️ What this doesn't do
This page is a mental model, not a proof. It doesn't show you what happens
inside a single + or × node during the reverse sweep — that's Module
13.1, once you've seen a real tape to inspect. It doesn't touch a real
market, option, or line of Java yet — that starts on the next page.
What's next
→ Next: A map of the engine, the picture every later module in this path points back to.