In an earlier post, I have been quickly exploring adjoint differentiation in the context of analytical Black-Scholes. Today, I tried to mix it in a simple Black-Scholes Monte-Carlo as described in L. Capriotti paper, and measured the performance to compute delta compared to a numerical single sided finite difference delta.I was a bit surprised that even on a single underlying, without any real optimization, adjoint delta was faster by a factor of nearly 40%. I suspect this is mostly due to exp evaluations being /2.On a basket of 4 assets, the adjoint method was 3.25x faster.It’s quick to have such results on basic payoffs: it took me a few hours and worked on the first run, even though my Monte-Carlo is slightly different from the Capriotti paper. It is much more challenging to have it working across a wide variety of payoffs, and to automatize some of it.
Several papers show that the limit for large strikes of Heston is SVI.
Interestingly, I stumbled onto a surface where the Hagan SABR fit was perfect as well as the SVI fit, while the Heston fit was not.
Originally, I knew that, on this data, the SVI fit was perfect. Until today, I just never tried to fit a lognormal SABR on the same data. I did a small test with random values of the SABR parameters alpha, rho, nu, and found out that in deed, the SVI fit is always perfect on SABR.
Is this just because the Taylor expansion of SVI will match the Taylor expansion of SABR up to the fourth order? It seems that the wings are also not too far off in general so there could be more to it.
Gatheral actually devised an SVI formula that uses SABR like variables in a talk here.
Of course, the reverse is not true. SVI has more parameters and provides in general a better fit than SABR.
With a small time expansion, it is easy to derive a reasonable initial guess, without resorting to some global minimizer.
Like Forde did for Heston, one can find the 5 Schobel-Zhu parameters through 5 points at coordinates (0,0), (x0,t1), (-x0,t1), (x0,t2), (-x0,t2), where x0 is a chosen the log-moneyness, for example, 0.1 and t1, t2 relatively short expiries (for example, 0.1, 0.25).
We can truncate the small time expansion so that the polynomial in (x,t) is fully captured by those 5 points. In practice, I have noticed that using a more refined expansion with more terms resulted not only in more complex formulas to lookup the original stochastic volatility parameters, but also in an increased error, because of the redundancy of parameters in the polynomial expansion. My previous Schobel-Zhu expansion becomes just:
In practice, I have found that the procedure works rather well.
On some more extreme surfaces, where theta=0, the error in kappa and theta is higher. Interestingly, I received a few real world surfaces like this, where theta=0, which I found a bit puzzling. I wondered if it was because those surfaces were preprocessed with SABR, that has no mean reversion, but I could not fit those exactly with SABR.
Small time expansions for Heston can be useful during the calibration of the implied volatility surface, in order to find an initial guess for a local minimizer (for example, Levenberg-Marquardt). Even if they are not so accurate, they capture the dynamic of the model parameters, and that is often enough.
I noticed, however, that on some surfaces, the Lorig expansion was quickly very inaccurate (LPP1 for order-1, LPP2 for order-2, LPP3 for order-3). Those surfaces seem to be the ones were the Feller condition is largely violated. In practice, in my set of volatility surfaces for 10 different equities/indices, the best fit is always produced by Heston parameters where the Feller condition is violated.
Out of curiosity, I calibrated my surfaces feeding the order-1 approximation to the differential evolution, in order to find my initial guess, and it worked for all surfaces.
The order-3 formula, even though it is more precise at the money, was actually more problematic for calibration: it failed to find a good enough initial guess in some cases, maybe because the reference data should be truncated, to possibly keep the few shortest expiries, and close to ATM strikes.
The paper implied vol for any local stochastic vol model from Lorig et al. presents a very generic and simple formula to compute implied volatility expansions up to order-2 (there is actually an order-3 formula available in their Mathematica CDF file).
I tried it on the Schobel-Zhu stochastic volatility model. This model is an interesting alternative to Heston. I found that, in practice, the implied volatility surface fit was as good, while the simulation under the QE scheme is quite faster (and simpler) than Heston. Here is the result of applying their technique on Schobel-Zhu:
And this is how it behaves on some realistic input:
In practice, while not extremely good, it seems to be enough for Calibration to find an initial guess via differential evolution.
Last week, my work laptop died after spilling out some water on its keyboard inadvertently. Fortunately, its SSD was intact.
As the laptop SSD connector (SATA) and power follow the desktop computers standards, and as I use Linux, I just plugged the SSD to my home desktop and booted off the SSD. I had to change slightly the X configuration but otherwise everything worked. Linux is great for that
The same way, I just plugged the SSD to the desktop at work and it worked. Instead of carrying a laptop, I carry now my small and ultra-light SSD.
The experience is so good, that it seems to me it should be an option to everybody. Before, hard drives were very sensitive to travel, but now with SSDs, I don’t really see why we should carry a screen and a keyboard unless we use them (for example in a travel). Also I find that I actually notice the speed difference between my desktops and former laptop, which I never really paid too much attention to before.
At first I did not make use of the Brownian Bridge technique in Heston QMC, because the variance process is not simulated like a Brownian Motion under the Quadratic Exponential algorithm from Andersen.
It is, however, perfectly possible to use the Brownian Bridge on the asset process. Does it make a difference? In my small test, it does not seem to make a difference. An additional question would be, is it better to take first N for the asset and next N for the variance or vice versa or intertwined? Intertwined would seem the most natural (this is what I used without Brownian Bridge, but for simplicity I did Brownian bridge on first N).
By contrast, Schobel-Zhu QE scheme can make full use of the Brownian Bridge technique, in the asset process as well as in the variance process. Here is a summary of the volatility process under the QE scheme from van Haastrecht:
Another nice property of Schobel-Zhu is that the QE simulation is as fast as Euler, and therefore 2.5x faster than the Heston QE.
I calibrated the model to the same surface, and the QMC price of a ATM call option seems to have a similar accuracy as Heston QMC. But we can see that the Brownian Bridge does increase accuracy in this case. I was surprised that accuracy was not much better than Heston, but maybe it is because I did yet not implement the Martingale correction, while I did so in the Heston case.
Adjoint algorithmic differentiation is particularly interesting in finance as we often encounter the case of a function that takes many input (the market data) and returns one output (the price) and we would like to also compute sensitivities (greeks) to each input.
As I am just starting around it, to get a better grasp, I first tried to apply the idea to the analytic knock out barrier option formula, by hand, only to find out I was making way too many errors by hand to verify anything. So I tried the simpler vanilla Black-Scholes formula. I also made various errors, but managed to fix all of them relatively easily.
I decided to compare how much time it took to compute price, delta, vega, theta, rho, rho2 between single sided finite difference and the adjoint approach. Here are the results for 1 million options:
FD time=2.13s Adjoint time=0.63s
It works well, but doing it by hand is crazy and too error prone. It might be simpler for Monte-Carlo payoffs however.
There are not many Java tools that can do reverse automatic differentiation, I found some thesis on it, with an interesting byte code oriented approach (one difficulty is that you need to reverse loops, while statements).
At the same time, Tavella and Randall show in their book that numerically, placing the strike in the middle of two nodes leads to a more accurate result. My own numerical experiments confirm Tavella and Randall suggestion.
In reality, what Pooley et al. really mean, is that quadratic convergence is maintained if the strike is on the grid for vanilla payoffs, contrary to the case of discontinuous payoffs (like digital options) where the convergence decreases to order 1. So it's ok to place the strike on the grid for a vanilla payoff, but it's not optimal, it's still better to place it in the middle of two nodes. Here are absolute errors in a put option price:
on grid, no smoothing 0.04473021824995271 on grid, Simpson smoothing 0.003942854282069419 on grid, projection smoothing 0.044730218065351934 middle, no smoothing 0.004040359609906119
As expected (and mentioned in Pooley et al.), the projection does not do anything here. When the grid size is doubled, the convergence ratio of all methods is the same (order 2), but placing the strike in the middle still increases accuracy significantly.
Here is are the same results, but for a digital put option: on grid, no smoothing 0.03781319921461046 on grid, Simpson smoothing 8.289052335705427E-4 on grid, projection smoothing 1.9698293587372406E-4 middle, no smoothing 3.5122153011418744E-4
Here only the 3 last methods are of order-2 convergence, and projection is in deed the most accurate method, but placing the strike in the middle is really not that much worse, and much simpler.
Recently, I noticed how close are the two PDE based approaches from Andreasen-Huge and Hagan for an arbitrage free SABR. Hagan gives a local volatility very close to the one Andreasen-Huge use in the forward PDE in call prices. A multistep Andreasen-Huge (instead of their one step PDE method) gives back prices and densities nearly equal to Hagan density based approach.
Hagan proposed in some unpublished paper a coordinate transformation for two reasons: the ideal range of strikes for the PDE can be very large, and concentrating the points where it matters should improve stability and accuracy. The transform itself can be found in the Andersen-Piterbarg book “Interest Rate Modeling”, and is similar to the famous log transform, but for a general local volatility function (phi in the book notation).
There are two ways to transform Andreasen Huge PDE:
through a non-uniform grid: the input strikes are directly transformed based on a uniform grid in the inverse transformed grid (paying attention to still put the strike in the middle of two points). This is detailed in the Andersen-Piterbarg book.
through a variable transform in the PDE: this gives a slightly different PDE to solve. One still needs to convert then a given strike, to the new PDE variable. This kind of transform is detailed in the Tavella-Randall book “Pricing Financial Instruments: the Finite Difference Method”, for example.
Both are more or less equivalent. I would expect the later to be slightly more precise but I tried the former as it is simpler to test if you have non uniform parabolic PDE solvers.
It works very well, but I found an interesting issue when computing the density (second derivative of the call price): if one relies on a Hermite kind of spline (Bessel/Parabolic or Harmonic), the density wiggles around. The C2 cubic spline solves this problem as it is C2. Initially I thought those wiggles could be produced because the interpolation did not respect monotonicity and I tried a Hyman monotonic cubic spline out of curiosity, it did not change anything (in an earlier version of this post I had a bug in my Hyman filter) as it preserves monotonicity but not convexity. The wiggles are only an effect of the approximation of the derivatives value.
Initially, I did not notice this on the uniform discretization mostly because I used a large number of strikes in the PDE (here I use only 50 strikes) but also because the effect is somewhat less pronounced in this case.
I also discovered a bug in my non uniform implementation of Hagan Density PDE, I forgot to take into account an additional dF/dz factor when the density is integrated. As a result, the density was garbage when computed by a numerical difference.