Diagnosing Arbitrage in a Cap and Floor Volatility Surface
Summary
The document addresses a QuantLib failure while stripping cap and floor volatilities into individual optionlet volatilities. The reported error says a parameter falls outside its allowed range during bootstrap, at a particular strike and expiry. The answer interprets this as a likely arbitrage inconsistency in the input cap or floor surface that prevents the stripping procedure from producing valid optionlet prices.
One example of the kind of inconsistency is a longer-maturity cap costing less than a shorter-maturity cap at the same strike. The proposed diagnostic is to inspect the surface around the reported strike and the relevant shorter maturities, then adjust inconsistent volatility inputs and retry, recognizing that nearby prices can also change. The post does not provide a complete arbitrage test, a corrected surface, or a reproducible fix. The evaluation date is also absent from the question, which limits how precisely the cited expiry can be mapped to a surface tenor.
Key ideas
- Optionlet stripping can fail when the input cap or floor surface contains arbitrage inconsistencies.
- A longer-maturity cap priced below a shorter-maturity cap at the same strike is a possible warning sign.
- The error message can help locate the problematic strike and expiry region.
- Adjusting nearby volatilities may affect other surface prices and can require iteration.
Tags
Full text
# QuantLib in Python - RuntimeError: could not bootstrap optionlet: # QuantLib in Python - RuntimeError: could not bootstrap optionlet: I receiving the following error when I try to compute a cap price. However, I'm not sure how to solve this error. > " error: nu (-1.00062) must be >= -1.0 expiry: June 4th, 2020 annuity: 0.0830405 price: -1.25183e-07 atm: 0.255034 % strike: 0.739166 % type: Call RuntimeError: could not bootstrap optionlet: I've transformed the normal vols into decimals. Below is the code how I set up the optionlet handle. ``` > cap_floor_vol = ql.CapFloorTermVolSurface(2, ql.UnitedStates(),ql.ModifiedFollowing, expiries, vol_strikes, vol_surface) > optionlet_surf = ql.OptionletStripper1(cap_floor_vol, ibor_index, ql.nullDouble(), 1e-6, 100, yts_handle_dis, type = ql.Normal) > ovs_handle = ql.OptionletVolatilityStructureHandle(ql.StrippedOptionletAdapter(optionlet_surf)) > ovs_handle.enableExtrapolation() ``` Can someone point me in the right direction? Thanks. ## Answer by user35980 (score 1) https://quant.stackexchange.com/a/55682 This error usually means there is an arbitrage in your cap/floor surface and quantlib is unable to strip out caplets/floorlets from the data in your input surface. So for example a same strike longer maturity cap is costing less than a shorter one. The error info has narrowed down where the arb is occurring (strike column 0.739% and maturity looks to be one of the shorter tenors - but you haven't specified the evaluation date in your code so it's not clear). Try adjusting the vols around there. This can be an iterative process as nearby prices on your surface will be impacted.
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.