Adjoint Algorithmic Differentiation
Bumping each of a thousand risk factors one at a time and rerunning the pricer a thousand times is unusable in real time. Running the calculation backwards once gets every single sensitivity in about the same time as one forward pass.
Prerequisites: Monte Carlo Greeks: Pathwise And Likelihood Ratio, Backpropagation
A book with a thousand risk factors — one volatility per strike and expiry, one rate per tenor — needs a thousand Greeks. The bump-and-reprice approach, nudge one input, rerun the whole pricer, repeat for every factor, costs roughly a thousand full pricing runs. If one run takes even a second, that is over 16 minutes for a single risk snapshot — unusable intraday. Adjoint algorithmic differentiation (AAD) gets every one of those thousand sensitivities from roughly the cost of one extra pricing run.
Retracing a hike backwards to find every fork's effect
Imagine hiking a trail with a thousand forks, and you want to know: for each fork, how much would taking the other path have changed your final elevation? Walking the whole trail again a thousand times, once per fork, is bump-and-reprice. A cleverer way: walk the trail forward once as normal, then walk backwards from the end exactly once, at each fork combining how sensitive the final elevation was to everything downstream with how much that fork could have changed the path. One forward walk, one backward walk, and every fork's sensitivity falls out.
Forward mode versus reverse mode
Any calculation, including a pricing model, is a sequence of simple operations chained together. Forward-mode differentiation propagates a sensitivity with the calculation — cheap per input, but needs one full pass per input, the "bump and reprice" cost structure in disguise. Reverse-mode (the "adjoint") instead computes the output first, then propagates sensitivities backwards to every input in a single pass, using the chain rule at each step:
applied repeatedly, step by step, from the final output back through every intermediate quantity to every original input . In plain English: once you know how sensitive the price is to the last intermediate step, its sensitivity to the previous step is just one more multiplication, backwards through the whole calculation — and this sweep computes the sensitivity to every input at once, since each backward sensitivity is reused for every input that fed into it.
Worked example 1: a tiny three-step calculation, forward vs. adjoint
Compute with . Forward pass: , then .
Bump-and-reprice for : recompute with : , , so . Repeat separately for and — three recomputations for three sensitivities.
Adjoint, one backward pass: start from . Since : and . Since : , and likewise. All three sensitivities came from one forward pass plus one backward pass — no repeated recomputation, matching the bump-and-reprice answers exactly.
Worked example 2: the cost comparison at realistic scale
A Monte Carlo pricer with risk factors takes second per full pricing run.
Bump-and-reprice: one baseline run plus one bumped run per factor: seconds, about 16.7 minutes.
Adjoint: one forward pass plus one backward pass, where the backward pass typically costs a small constant multiple (commonly cited as roughly 2-4x) of the forward pass, say here: seconds total, for all 1,000 sensitivities.
That is a speedup of roughly for this factor count, and the gap only widens as the number of risk factors grows, since bump-and-reprice cost scales linearly with while adjoint cost stays roughly constant.
What this means in practice
Every major bank's front-office risk engine uses adjoint differentiation for full Greeks sets across books with thousands of risk factors, because it is the only approach that makes intraday, full-revaluation risk computationally feasible — the same core idea as Backpropagation in neural network training, reverse-mode differentiation through a network's layers instead of a pricer's calculation steps. It generalises the pathwise method to compute all Greeks from one simulation, not just delta.
Adjoint differentiation gives exact derivatives of the code as written, not automatically the derivative of the underlying financial quantity if the code contains a non-differentiable step — an if branch, a sort, a hard cutoff in a payoff. The common mistake is assuming AAD "just works" without checking for these; at a genuine kink, the derivative can be technically correct for that exact input yet wildly unrepresentative nearby, needing the same care that pathwise vs. likelihood-ratio methods require for non-smooth payoffs.
Reverse-mode (adjoint) differentiation computes sensitivities to every input from a single backward pass through the calculation, at roughly constant cost regardless of how many inputs there are — the opposite scaling from bump-and-reprice, which pays one full recomputation per input.
Related concepts
Practice in interviews
Further reading
- Giles & Glasserman (2006), Smoking Adjoints: Fast Monte Carlo Greeks
- Griewank & Walther, Evaluating Derivatives (Ch. 3-4)