I am working with a vol surface that was created as a BlackVarianceSurface. Now I would like to compute the "vol" greeks for a product and as such I need to shift that surface by a small dVol uniformally so that I can then compute: Vega = [Price(shifted surface) - Price(base surface)] / shift

And along the same lines I'd need to compute the second derivative (volga) and cross spot/vol derivative (vanna).

So far the only thing I've been able to find was to extract a constant vol from the surface for a vanilla option, and then reprice not with the whole surface but with a constantvol. => This only works for vanilla options and won't work for other products using the entire surface => This method is highly inefficient as it considerably slows down all pricing

Has anyone come across a more efficient method ? Is there a utility that shifts the entire surface at once ?

Thank you

  • $\begingroup$ Just curious, why do you want to perturb the entire vol surface all at once, rather than break down the vega by perturbing selected parts of the vol surface? Also, this answer may help stackoverflow.com/questions/48535148/… $\endgroup$ Oct 11, 2022 at 18:02
  • 1
    $\begingroup$ @DimitriVulis it is best to work with a shifted surface altogether for products that require the entire curve (for example a barrier option or a conditional variance swap). The functionality you mention is also very useful, but more from a risk management standpoint than from a greeks calculation perspective. $\endgroup$
    – volPMNYC
    Oct 11, 2022 at 23:03

1 Answer 1


There's no such utility in the library right now, but it can be written in a page or two of code.

It would work like, for instance, the SpreadedSwaptionVolatility works for swaption volatility; the idea is to write a class that inherits from the base BlackVolTermStructure class and takes the desired base volatility and spread.

Like SpreadedSwaptionVolatility, it would provide most of the required interface by delegating to the base volatility, as in

inline DayCounter SpreadedSwaptionVolatility::dayCounter() const {
    return baseVol_->dayCounter();

while the methods returning the volatility would be implemented as

Volatility SpreadedSwaptionVolatility::volatilityImpl(const Date& d,
                                                      const Period& p,
                                                      Rate strike) const {
    return baseVol_->volatility(d, p, strike, true) + spread_->value();

If you do write it, please consider contributing it to the library; if, instead, you're not familiar with C++, you can open an issue on the QuantLib GitHub repository and request the feature.

  • $\begingroup$ Thanks Luigi. Unfortunately not good with C++, I'm using Python. $\endgroup$
    – volPMNYC
    Oct 11, 2022 at 23:00
  • $\begingroup$ Thanks Luigi !!! I would hope that rather than just one parallel shift, the caller be able to apply more targeted perturbation scenarios to the volatilities, e.g. bump one moneyness at a time @volPMNYC once a feature is in the underlying C++, exposing it in Python is usually very easy. $\endgroup$ Oct 12, 2022 at 13:26
  • 1
    $\begingroup$ @DimitriVulis same idea, the implementation would be more complex. As an example, the InterpolatedPiecewiseZeroSpreadedTermStructure class does it for interest rates. A similar class for volatilities would need to specify a grid in both time and moneyness. $\endgroup$ Oct 12, 2022 at 13:41
  • $\begingroup$ Yes @LuigiBallabio, precisely, thank you again. The ability to perturb a 3-dimensional vol cube (its dimensions being: moneyness, time to expiry of the swaption, and the tenor of the underlying swap) would be even cooler. I don't believe that calling more flexible code for the simple parallel bump that the OP had in mind would add material overhead. $\endgroup$ Oct 12, 2022 at 14:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.