Calculating Swaption Greeks in QuantLib Python
Summary
This discussion explains why some QuantLib C++ result-access methods were initially unavailable in its Python wrapper and outlines ways to obtain swaption sensitivities. The accepted answer says the generic result and additional-results methods were not exported through SWIG, citing template and type-conversion limitations. For users able to rebuild the wrapper, it describes adding a dedicated vega method to the Swaption interface.
A later answer reports that vega is available directly in Python starting with QuantLib version 1.30, while gamma may require an indirect calculation. It illustrates comparing deltas after bumping the underlying swap, though the example’s gamma treatment is simplified and does not discuss bump size, scaling, or normalization. Availability therefore depends on the library version and interface, and finite-difference sensitivities require careful bump methodology. The examples are implementation guidance, not a general account of swaption risk conventions.
Key ideas
- Earlier QuantLib Python wrappers did not expose generic additional-result accessors available in C++.
- A custom SWIG extension can provide a dedicated vega method when rebuilding the wrapper.
- A later answer reports direct Python access to vega in QuantLib 1.30.
- The later answer estimates gamma by comparing deltas after changing the underlying swap, a finite-difference approach that needs careful bump choices.
Tags
Full text
# Calculating the greeks for Quantlib Python Swaptions
# Calculating the greeks for Quantlib Python Swaptions
So I have created a Swaption object and can get the premium with the NPV() function. However, I would also like to calculate the greeks (eg. delta, vega).
From some searching, I found that vega can be extracted from the additionalResults () function of the instrument class, but it doesn't seem to be defined for the Python version of Quantlib.
For example, let `swaption` be an initialized instance of a Swaption object.
`swaption.NPV()` gives me the value as expected, but `swaption.additionalResults()` and `swaption.result("Vega")` are not defined.
http://cogitolearning.co.uk/?p=490 This link shows the c++ analogue of these functions.
Otherwise, how could I calculate these values? I'm not sure if BlackCalculator is appropriate for these calculations on a `swaption`.
## Answer by Luigi Ballabio (score 3)
https://quant.stackexchange.com/a/27860
Neither the `additionalResults` nor the `result` method are exported to Python via SWIG. This is unlikely to change in the future: `result` is a template method, and it can't be exported to Python as such, whereas `additionalResults` would require a sensible way to export `boost::any` to Python and to convert it to a given data type.
If you can recompile the QuantLib Python module, though, you can add to the `Swaption` class a `vega` method that makes the call you cite in the link. Edit `swaption.i` in the `QuantLib-SWIG` distribution and add
```
Real vega() {
return self->result<Real>("vega");
}
```
to the `%extend` section of the `Swaption` interface (`self` is a variable used by SWIG to denote the current object, as in Python). This will add a `vega` method to the Python wrapper that executes the call above.
(A note: when you get it running, please consider opening a pull request with your change for the QuantLib-SWIG repository on Github.)
## Answer by Raja Krovvidi (score 0)
https://quant.stackexchange.com/a/75906
Vega calc on swaption is available in Quantlib version 1.30 in Python. I could not find Gamma, though. You could try the below if you want a slightly roundabout way of computing.
```
exercise_date = calendar.advance(calc_date, ql.Period('2y'))
exercise = ql.EuropeanExercise(exercise_date)
underlying_swap = construct_swap(libor3M_index, calendar, calc_date, exercise_date )
swaption = ql.Swaption(underlying_swap, exercise, ql.Settlement.Cash, ql.Settlement.ParYieldCurve)
blackEngine = ql.BlackSwaptionEngine(disc_curve, ql.QuoteHandle(ql.SimpleQuote(0.55)), ql.ActualActual(ql.ActualActual.ISMA))
bumped_underlying_swap = construct_swap(bumped_libor3M_index, calendar, calc_date, exercise_date )
swaption2 = ql.Swaption(bumped_underlying_swap, exercise, ql.Settlement.Cash, ql.Settlement.ParYieldCurve)
swaption.setPricingEngine(blackEngine)
swaption2.setPricingEngine(blackEngine)
swaption_npv = swaption.NPV()
swaption_delta = swaption.delta()
swaption_bumped_delta = swaption2.delta()
swaption_gamma = swaption_bumped_delta - swaption_delta
swaption_vega = swaption.vega()
print("swaption NPV is: " + str(swaption_npv))
print("swaption Delta is: " + str(swaption_delta))
print("swaption Gamma is: " + str(swaption_gamma))
print("swaption Vega is: " + str(swaption_vega))
swaption NPV is: 955352.6839294916
swaption Delta is: 37903752.77195477
swaption Gamma is: 36557.01650556922
swaption Vega is: 1623710.5849933475
```Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.