Skip to content
All library documents

Pricing Swaptions with Negative Rates Using Normal Volatility

Article Quant Q&A · Author: Jorge Gisbert

Summary

The note addresses a QuantLib pricing error that occurs when a Black swaption engine is used with a negative forward rate. The error indicates that the Black model requires the forward rate, after any displacement, to be positive; with no displacement and a negative forward, that condition is not met.

The answer demonstrates using the Bachelier swaption engine with a normal volatility quote instead. This model supports negative rates and provides an alternative for valuing swaptions when the Black model’s positivity requirement is unsuitable. The example uses a vanilla EUR swaption and a flat yield curve, but the note does not compare the models, explain how to choose or calibrate normal volatility, or discuss other possible remedies such as a shifted Black model.

Key ideas

  • The standard Black swaption model requires a positive forward rate after displacement.
  • A negative forward can trigger a pricing error when Black is used without a suitable displacement.
  • The Bachelier model supports negative rates and can be used through QuantLib’s Bachelier swaption engine.
  • The example does not explain volatility calibration or compare alternative model choices.

Tags

Full text
# Evaluating swaptions with negative interest rates


# Evaluating swaptions with negative interest rates












Does anyone know if it is possible to evaluate swaptions with negative interest rates with Quantlib?

```
    blackEngine = ql.BlackSwaptionEngine(discountingTermStructure, ql.QuoteHandle(ql.SimpleQuote(vol)))
    swaption.setPricingEngine(blackEngine)
    swaptionnpv = swaption.NPV()
```

My vol value is an interpolated value from a volatility matrix which is equal to 0.34.

```
RuntimeError: forward + displacement (-0.00128788 + 0) must be positive
```

Thanks in advance

## Answer by David Duarte (score 3)

https://quant.stackexchange.com/a/68750

Here is an example on pricing the the Bachelier model (Normal vols):

```
import QuantLib as ql

yts = ql.YieldTermStructureHandle(ql.FlatForward(2, ql.TARGET(), 0.05, ql.Actual360()))

calendar = ql.TARGET()
today = ql.Date().todaysDate()
exerciseDate = calendar.advance(today, ql.Period('5y'))
exercise = ql.EuropeanExercise(exerciseDate)
swap = ql.MakeVanillaSwap(ql.Period('5y'), ql.Euribor6M(yts), 0.05, ql.Period('5y'))
swaption = ql.Swaption(swap, exercise)

bachelierEngine = ql.BachelierSwaptionEngine(yts, ql.QuoteHandle(ql.SimpleQuote(0.0055)))
swaption.setPricingEngine(bachelierEngine)
swaption.NPV()
```

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.