Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Public Member Functions | List of all members
CPIPriceVolatilitySurface< InterpolatorStrike, InterpolatorTime > Class Template Reference

Stripped zero inflation volatility structure. More...

#include <qle/termstructures/inflation/cpipricevolatilitysurface.hpp>

+ Inheritance diagram for CPIPriceVolatilitySurface< InterpolatorStrike, InterpolatorTime >:
+ Collaboration diagram for CPIPriceVolatilitySurface< InterpolatorStrike, InterpolatorTime >:

Public Member Functions

 CPIPriceVolatilitySurface (PriceQuotePreference type, const QuantLib::Period &observationLag, const QuantLib::Calendar &cal, const QuantLib::BusinessDayConvention &bdc, const QuantLib::DayCounter &dc, const QuantLib::ext::shared_ptr< QuantLib::ZeroInflationIndex > index, QuantLib::Handle< QuantLib::YieldTermStructure > yts, const std::vector< QuantLib::Rate > &cStrikes, const std::vector< QuantLib::Rate > &fStrikes, const std::vector< QuantLib::Period > &cfMaturities, const QuantLib::Matrix &cPrice, const QuantLib::Matrix &fPrice, const QuantLib::ext::shared_ptr< QuantExt::CPICapFloorEngine > &engine, const bool quotedInstrumentsAreInterpolated=false, const QuantLib::Date &capFloorStartDate=QuantLib::Date(), bool ignoreMissingPrices=false, bool lowerStrikeConstExtrap=true, bool upperStrikeConstExtrap=true, const QuantLib::VolatilityType &volType=QuantLib::ShiftedLognormal, const double displacement=0.0, const QuantLib::Real &upperVolBound=CPIPriceVolatilitySurfaceDefaultValues::upperVolBound, const QuantLib::Real &lowerVolBound=CPIPriceVolatilitySurfaceDefaultValues::lowerVolBound, const QuantLib::Real &solverTolerance=CPIPriceVolatilitySurfaceDefaultValues::solverTolerance)
 
QL_DEPRECATED CPIPriceVolatilitySurface (PriceQuotePreference type, const QuantLib::Period &observationLag, const QuantLib::Calendar &cal, const QuantLib::BusinessDayConvention &bdc, const QuantLib::DayCounter &dc, const QuantLib::ext::shared_ptr< QuantLib::ZeroInflationIndex > index, QuantLib::Handle< QuantLib::YieldTermStructure > yts, const std::vector< QuantLib::Rate > &cStrikes, const std::vector< QuantLib::Rate > &fStrikes, const std::vector< QuantLib::Period > &cfMaturities, const QuantLib::Matrix &cPrice, const QuantLib::Matrix &fPrice, const QuantLib::ext::shared_ptr< QuantExt::CPICapFloorEngine > &engine, const QuantLib::Date &capFloorStartDate=QuantLib::Date(), bool ignoreMissingPrices=false, bool lowerStrikeConstExtrap=true, bool upperStrikeConstExtrap=true, const QuantLib::VolatilityType &volType=QuantLib::ShiftedLognormal, const double displacement=0.0, const QuantLib::Real &upperVolBound=CPIPriceVolatilitySurfaceDefaultValues::upperVolBound, const QuantLib::Real &lowerVolBound=CPIPriceVolatilitySurfaceDefaultValues::lowerVolBound, const QuantLib::Real &solverTolerance=CPIPriceVolatilitySurfaceDefaultValues::solverTolerance)
 
LazyObject interface
void performCalculations () const override
 
void update () override
 
Limits
QuantLib::Real minStrike () const override
 the minimum strike for which the term structure can return vols More...
 
QuantLib::Real maxStrike () const override
 the maximum strike for which the term structure can return vols More...
 
QuantLib::Date maxDate () const override
 maximum date for which the term structure can return vols More...
 
- Public Member Functions inherited from CPIVolatilitySurface
 CPIVolatilitySurface (QuantLib::Natural settlementDays, const QuantLib::Calendar &, QuantLib::BusinessDayConvention bdc, const QuantLib::DayCounter &dc, const QuantLib::Period &observationLag, QuantLib::Frequency frequency, bool indexIsInterpolated, const QuantLib::Date &capFloorStartDate=QuantLib::Date(), QuantLib::VolatilityType volType=QuantLib::ShiftedLognormal, double displacement=0.0)
 
QuantLib::Date optionDateFromTenor (const QuantLib::Period &tenor) const override
 Computes the expiry date from the capFloorStartDate() More...
 
QuantLib::Date baseDate () const override
 base date will be in the past More...
 
QuantLib::VolatilityType volatilityType () const
 Returns the volatility type. More...
 
double displacement () const
 Returns the displacement for lognormal volatilities. More...
 
bool isLogNormal () const
 
QuantLib::Volatility volatility (const QuantLib::Date &maturityDate, QuantLib::Rate strike, const QuantLib::Period &obsLag=QuantLib::Period(-1, QuantLib::Days), bool extrapolate=false) const override
 
virtual QuantLib::Real atmStrike (const QuantLib::Date &maturity, const QuantLib::Period &obsLag=QuantLib::Period(-1, QuantLib::Days)) const =0
 
QuantLib::Date capFloorStartDate () const
 

Inspectors

PriceQuotePreference preference_
 
QuantLib::ext::shared_ptr< QuantLib::ZeroInflationIndex > index_
 
QuantLib::Handle< QuantLib::YieldTermStructure > yts_
 
std::vector< double > capStrikes_
 
std::vector< double > floorStrikes_
 
QuantLib::ext::shared_ptr< QuantExt::CPICapFloorEngineengine_
 
bool ignoreMissingPrices_
 
bool lowerStrikeConstExtrap_
 
bool upperStrikeConstExtrap_
 
QuantLib::Real upperVolBound_
 
QuantLib::Real lowerVolBound_
 
QuantLib::Real solverTolerance_
 
std::vector< QuantLib::Period > expiries_
 
std::vector< QuantLib::Rate > strikes_
 
QuantLib::Matrix capPrices_
 
QuantLib::Matrix floorPrices_
 
std::vector< QuantLib::Date > fixingDates_
 
QuantLib::Matrix volData_
 
std::vector< std::vector< bool > > missingPrices_
 
std::vector< std::vector< bool > > failedPrices_
 
QuantLib::ext::shared_ptr< QuantExt::OptionInterpolator2d< InterpolatorStrike, InterpolatorTime > > volSurface_
 
const std::vector< QuantLib::Real > & strikes ()
 Returns the strikes. More...
 
const std::vector< QuantLib::Period > & maturities ()
 Returns the tenors. More...
 
const QuantLib::Matrix & volData () const
 
const std::vector< std::vector< bool > > & missingValues () const
 
const std::vector< std::vector< bool > > & pricesFailedToConvert () const
 
double baseCPI () const
 CPI fixing on the baseDate of the surface. More...
 
double atmGrowth (QuantLib::Period &tenor) const
 
double atmGrowth (const QuantLib::Date &date) const
 
QuantLib::Real atmStrike (const QuantLib::Date &maturity, const QuantLib::Period &obsLag=QuantLib::Period(-1, QuantLib::Days)) const override
 
virtual void validateInputParameters () const
 
virtual void initializeStrikes () const
 
double priceFromPutCallParity (double price, bool isCapPrice, double atm, double strikeGrowth, double df) const
 Computes a cap price from a floor price using the put-call parity and vice-versa. More...
 
double floorPrice (double strike, size_t tenorIdx, double atm, double strikeGrowth, double df) const
 Returns floor price for strike level (average annual inflation) and maturity index. More...
 
double capPrice (double strike, size_t tenorIdx, double atm, double strikeGrowth, double df) const
 Returns cap price for strike level (average annual inflation) and maturity index. More...
 
QuantLib::Volatility volatilityImpl (QuantLib::Time length, QuantLib::Rate strike) const override
 
bool chooseFloor (QuantLib::Real strike, QuantLib::Real atmRate) const
 
double implyVol (double strike, const QuantLib::Date &maturity, double price, bool isFloor) const
 

Additional Inherited Members

- Protected Member Functions inherited from CPIVolatilitySurface
virtual double fixingTime (const QuantLib::Date &maturityDate) const
 Computes the expiry time from the capFloorStartDate() More...
 
- Protected Attributes inherited from CPIVolatilitySurface
QuantLib::VolatilityType volType_
 
double displacement_
 

Detailed Description

template<class InterpolatorStrike, class InterpolatorTime>
class QuantExt::CPIPriceVolatilitySurface< InterpolatorStrike, InterpolatorTime >

Stripped zero inflation volatility structure.

The surface provides implied CPI Black volatilities for the union of strikes that occur in the underlying cap and floor price surface.

The type argument determines which kind of price quotes are used with priority when there is an overlap, i.e. strikes for which we have both cap and floor quotes: If type is Cap: Use cap quotes where available, floor quotes otherwise If type is Floor: Use floor quotes where available, cap quotes otherwise If type is CapFloor: In case of overlap, use floor quotes up to the ATM strike, cap quotes for strikes beyond ATM

Definition at line 56 of file cpipricevolatilitysurface.hpp.

Constructor & Destructor Documentation

◆ CPIPriceVolatilitySurface() [1/2]

CPIPriceVolatilitySurface ( PriceQuotePreference  type,
const QuantLib::Period &  observationLag,
const QuantLib::Calendar &  cal,
const QuantLib::BusinessDayConvention &  bdc,
const QuantLib::DayCounter &  dc,
const QuantLib::ext::shared_ptr< QuantLib::ZeroInflationIndex >  index,
QuantLib::Handle< QuantLib::YieldTermStructure >  yts,
const std::vector< QuantLib::Rate > &  cStrikes,
const std::vector< QuantLib::Rate > &  fStrikes,
const std::vector< QuantLib::Period > &  cfMaturities,
const QuantLib::Matrix &  cPrice,
const QuantLib::Matrix &  fPrice,
const QuantLib::ext::shared_ptr< QuantExt::CPICapFloorEngine > &  engine,
const bool  quotedInstrumentsAreInterpolated = false,
const QuantLib::Date &  capFloorStartDate = QuantLib::Date(),
bool  ignoreMissingPrices = false,
bool  lowerStrikeConstExtrap = true,
bool  upperStrikeConstExtrap = true,
const QuantLib::VolatilityType &  volType = QuantLib::ShiftedLognormal,
const double  displacement = 0.0,
const QuantLib::Real &  upperVolBound = CPIPriceVolatilitySurfaceDefaultValues::upperVolBound,
const QuantLib::Real &  lowerVolBound = CPIPriceVolatilitySurfaceDefaultValues::lowerVolBound,
const QuantLib::Real &  solverTolerance = CPIPriceVolatilitySurfaceDefaultValues::solverTolerance 
)

Definition at line 206 of file cpipricevolatilitysurface.hpp.

219 : QuantExt::CPIVolatilitySurface(0, cal, bdc, dc, observationLag, index->frequency(), quotedInstrumentsAreInterpolated,
221 preference_(type), index_(index), yts_(yts), capStrikes_(cStrikes), floorStrikes_(fStrikes), engine_(engine),
222 ignoreMissingPrices_(ignoreMissingPrices), lowerStrikeConstExtrap_(lowerStrikeConstExtrap),
223 upperStrikeConstExtrap_(upperStrikeConstExtrap), upperVolBound_(upperVolBound), lowerVolBound_(lowerVolBound),
224 solverTolerance_(solverTolerance), expiries_(cfMaturities), capPrices_(cPrice), floorPrices_(fPrice) {
227 QL_REQUIRE(!yts.empty(), "DiscountCurve not provided");
228 QL_REQUIRE(engine, "PricingEngine not provided");
229 QL_REQUIRE(index, "PricingEngine not provided");
230 registerWith(index_);
231 registerWith(yts_);
232}
QuantLib::ext::shared_ptr< QuantLib::ZeroInflationIndex > index_
QuantLib::ext::shared_ptr< QuantExt::CPICapFloorEngine > engine_
QuantLib::Handle< QuantLib::YieldTermStructure > yts_
std::vector< QuantLib::Period > expiries_
double displacement() const
Returns the displacement for lognormal volatilities.
QuantLib::Date capFloorStartDate() const
+ Here is the call graph for this function:

◆ CPIPriceVolatilitySurface() [2/2]

QL_DEPRECATED_DISABLE_WARNING CPIPriceVolatilitySurface ( PriceQuotePreference  type,
const QuantLib::Period &  observationLag,
const QuantLib::Calendar &  cal,
const QuantLib::BusinessDayConvention &  bdc,
const QuantLib::DayCounter &  dc,
const QuantLib::ext::shared_ptr< QuantLib::ZeroInflationIndex >  index,
QuantLib::Handle< QuantLib::YieldTermStructure >  yts,
const std::vector< QuantLib::Rate > &  cStrikes,
const std::vector< QuantLib::Rate > &  fStrikes,
const std::vector< QuantLib::Period > &  cfMaturities,
const QuantLib::Matrix &  cPrice,
const QuantLib::Matrix &  fPrice,
const QuantLib::ext::shared_ptr< QuantExt::CPICapFloorEngine > &  engine,
const QuantLib::Date &  capFloorStartDate = QuantLib::Date(),
bool  ignoreMissingPrices = false,
bool  lowerStrikeConstExtrap = true,
bool  upperStrikeConstExtrap = true,
const QuantLib::VolatilityType &  volType = QuantLib::ShiftedLognormal,
const double  displacement = 0.0,
const QuantLib::Real &  upperVolBound = CPIPriceVolatilitySurfaceDefaultValues::upperVolBound,
const QuantLib::Real &  lowerVolBound = CPIPriceVolatilitySurfaceDefaultValues::lowerVolBound,
const QuantLib::Real &  solverTolerance = CPIPriceVolatilitySurfaceDefaultValues::solverTolerance 
)

Definition at line 236 of file cpipricevolatilitysurface.hpp.

252 : QuantExt::CPIVolatilitySurface(0, cal, bdc, dc, observationLag, index->frequency(), index->interpolated(),
254 preference_(type), index_(index), yts_(yts), capStrikes_(cStrikes), floorStrikes_(fStrikes), engine_(engine),
255 ignoreMissingPrices_(ignoreMissingPrices), lowerStrikeConstExtrap_(lowerStrikeConstExtrap),
256 upperStrikeConstExtrap_(upperStrikeConstExtrap), upperVolBound_(upperVolBound), lowerVolBound_(lowerVolBound),
257 solverTolerance_(solverTolerance), expiries_(cfMaturities), capPrices_(cPrice), floorPrices_(fPrice) {
260 QL_REQUIRE(!yts.empty(), "DiscountCurve not provided");
261 QL_REQUIRE(engine, "PricingEngine not provided");
262 QL_REQUIRE(index, "PricingEngine not provided");
263 registerWith(index_);
264 registerWith(yts_);
265}
+ Here is the call graph for this function:

Member Function Documentation

◆ performCalculations()

QL_DEPRECATED_ENABLE_WARNING void performCalculations
override

Definition at line 269 of file cpipricevolatilitysurface.hpp.

269 {
270 volData_ = QuantLib::Matrix(strikes_.size(), expiries_.size(), QuantLib::Null<QuantLib::Real>());
271 missingPrices_ = std::vector<std::vector<bool>>(strikes_.size(), std::vector<bool>(expiries_.size(), false));
272 failedPrices_ = std::vector<std::vector<bool>>(strikes_.size(), std::vector<bool>(expiries_.size(), false));
273
274
275 std::vector<QuantLib::Date> dates;
276 std::vector<double> strikes;
277 std::vector<double> vols;
278
279 for (QuantLib::Size tenorIdx = 0; tenorIdx < expiries_.size(); tenorIdx++) {
280 QuantLib::Date maturityDate = optionDateFromTenor(expiries_[tenorIdx]);
281 QuantLib::Date fixingDate =
282 ZeroInflation::fixingDate(maturityDate, observationLag(), frequency(), indexIsInterpolated());
283 double atm = atmGrowth(maturityDate);
284 double df = yts_->discount(fixingDate);
285 double ttm =
286 QuantLib::inflationYearFraction(frequency(), indexIsInterpolated(), dayCounter(), baseDate(), fixingDate);
287 fixingDates_.push_back(fixingDate);
288 double atmAvgRate = std::pow(atm, 1.0 / ttm) - 1.0;
289 for (QuantLib::Size strikeIdx = 0; strikeIdx < strikes_.size(); strikeIdx++) {
290 double strike = strikes_[strikeIdx];
291 double strikeGrowth = std::pow(1.0 + strike, ttm);
292 bool useFloor = chooseFloor(strike, atmAvgRate);
293 double vol = QuantLib::Null<QuantLib::Real>();
294 QuantLib::Real priceToMatch = useFloor ? floorPrice(strike, tenorIdx, atm, strikeGrowth, df)
295 : capPrice(strike, tenorIdx, atm, strikeGrowth, df);
296 if (priceToMatch != QuantLib::Null<QuantLib::Real>()) {
297 try {
298 vol = implyVol(strike, maturityDate, priceToMatch, useFloor);
299 } catch (const std::exception&) {
300 // implied failed, we try to interpolate the failed values
301 vol = QuantLib::Null<QuantLib::Real>();
302 failedPrices_[strikeIdx][tenorIdx] = true;
303 }
304 } else {
305 missingPrices_[strikeIdx][tenorIdx] = true;
306 QL_REQUIRE(ignoreMissingPrices_, "Missing price for cpi capfloor vol for tenor "
307 << expiries_[tenorIdx] << " and strike " << strike);
308 }
309 if (vol != QuantLib::Null<QuantLib::Real>()) {
310 dates.push_back(fixingDate);
311 strikes.push_back(strike);
312 vols.push_back(vol);
313 }
314 }
315 }
316
317 volSurface_ = QuantLib::ext::make_shared<QuantExt::OptionInterpolator2d<InterpolatorStrike, InterpolatorTime>>(
318 referenceDate(), dayCounter(), dates, strikes, vols, lowerStrikeConstExtrap_, upperStrikeConstExtrap_,
319 InterpolatorStrike(), InterpolatorTime(), baseDate());
320
321 for (QuantLib::Size strikeIdx = 0; strikeIdx < strikes_.size(); strikeIdx++) {
322 for (QuantLib::Size tenorIdx = 0; tenorIdx < expiries_.size(); tenorIdx++) {
323 volData_[strikeIdx][tenorIdx] = volSurface_->getValue(fixingDates_[tenorIdx], strikes_[strikeIdx]);
324 }
325 }
326}
const std::vector< QuantLib::Real > & strikes()
Returns the strikes.
std::vector< std::vector< bool > > failedPrices_
QuantLib::ext::shared_ptr< QuantExt::OptionInterpolator2d< InterpolatorStrike, InterpolatorTime > > volSurface_
bool chooseFloor(QuantLib::Real strike, QuantLib::Real atmRate) const
double atmGrowth(QuantLib::Period &tenor) const
double capPrice(double strike, size_t tenorIdx, double atm, double strikeGrowth, double df) const
Returns cap price for strike level (average annual inflation) and maturity index.
double floorPrice(double strike, size_t tenorIdx, double atm, double strikeGrowth, double df) const
Returns floor price for strike level (average annual inflation) and maturity index.
std::vector< std::vector< bool > > missingPrices_
double implyVol(double strike, const QuantLib::Date &maturity, double price, bool isFloor) const
QuantLib::Date baseDate() const override
base date will be in the past
QuantLib::Date optionDateFromTenor(const QuantLib::Period &tenor) const override
Computes the expiry date from the capFloorStartDate()
QuantLib::Date fixingDate(const QuantLib::Date &d, const QuantLib::Period obsLag, const QuantLib::Frequency freq, bool interpolated)
Definition: inflation.cpp:183
+ Here is the call graph for this function:

◆ update()

void update ( )
override

Definition at line 102 of file cpipricevolatilitysurface.hpp.

102 {
103 CPIVolatilitySurface::update();
104 QuantLib::LazyObject::update();
105 }

◆ minStrike()

QuantLib::Real minStrike
override

the minimum strike for which the term structure can return vols

Definition at line 386 of file cpipricevolatilitysurface.hpp.

386 {
387 return strikes_.front() - QL_EPSILON;
388}

◆ maxStrike()

QuantLib::Real maxStrike
override

the maximum strike for which the term structure can return vols

Definition at line 391 of file cpipricevolatilitysurface.hpp.

391 {
392 return strikes_.back() + QL_EPSILON;
393}

◆ maxDate()

QuantLib::Date maxDate
override

maximum date for which the term structure can return vols

Definition at line 396 of file cpipricevolatilitysurface.hpp.

396 {
397 return optionDateFromTenor(expiries_.back());
398}

◆ strikes()

const std::vector< QuantLib::Real > & strikes ( )

Returns the strikes.

Definition at line 120 of file cpipricevolatilitysurface.hpp.

120{ return strikes_; }

◆ maturities()

const std::vector< QuantLib::Period > & maturities ( )

Returns the tenors.

Definition at line 123 of file cpipricevolatilitysurface.hpp.

123{ return expiries_; }

◆ volData()

const QuantLib::Matrix & volData ( ) const

Definition at line 125 of file cpipricevolatilitysurface.hpp.

125 {
126 calculate();
127 return volData_;
128 }

◆ missingValues()

const std::vector< std::vector< bool > > & missingValues ( ) const

Definition at line 130 of file cpipricevolatilitysurface.hpp.

130 {
131 calculate();
132 return missingPrices_;
133 }

◆ pricesFailedToConvert()

const std::vector< std::vector< bool > > & pricesFailedToConvert ( ) const

Definition at line 135 of file cpipricevolatilitysurface.hpp.

135 {
136 calculate();
137 return failedPrices_;
138 }

◆ baseCPI()

double baseCPI
protected

CPI fixing on the baseDate of the surface.

Definition at line 409 of file cpipricevolatilitysurface.hpp.

409 {
410 return ZeroInflation::cpiFixing(index_, capFloorStartDate(), observationLag(), indexIsInterpolated());
411}
QuantLib::Rate cpiFixing(const QuantLib::ext::shared_ptr< QuantLib::ZeroInflationIndex > &index, const QuantLib::Date &maturity, const QuantLib::Period &obsLag, bool interpolated)
Computes a CPI fixing giving an zeroIndex, with interpolation if needed.
Definition: inflation.cpp:166
+ Here is the call graph for this function:

◆ atmGrowth() [1/2]

double atmGrowth ( QuantLib::Period &  tenor) const
protected

Definition at line 414 of file cpipricevolatilitysurface.hpp.

414 {
415 return atmGrowth(optionDateFromTenor(tenor));
416}

◆ atmGrowth() [2/2]

double atmGrowth ( const QuantLib::Date &  date) const
protected

Definition at line 419 of file cpipricevolatilitysurface.hpp.

419 {
420 return ZeroInflation::cpiFixing(index_, date, observationLag(), indexIsInterpolated()) / baseCPI();
421}
double baseCPI() const
CPI fixing on the baseDate of the surface.
+ Here is the call graph for this function:

◆ atmStrike()

QuantLib::Real atmStrike ( const QuantLib::Date &  maturity,
const QuantLib::Period &  obsLag = QuantLib::Period(-1, QuantLib::Days) 
) const
overrideprotectedvirtual

Implements CPIVolatilitySurface.

Definition at line 564 of file cpipricevolatilitysurface.hpp.

565 {
566 QuantLib::Period lag = obsLag == -1 * QuantLib::Days ? observationLag() : obsLag;
567 QuantLib::Date fixingDate = ZeroInflation::fixingDate(maturity, lag, frequency(), indexIsInterpolated());
568 double forwardCPI = ZeroInflation::cpiFixing(index_, maturity, lag, indexIsInterpolated());
569 double atm = forwardCPI / baseCPI();
570 double ttm =
571 QuantLib::inflationYearFraction(frequency(), indexIsInterpolated(), dayCounter(), baseDate(), fixingDate);
572 return std::pow(atm, 1.0 / ttm) - 1.0;
573}
+ Here is the call graph for this function:

◆ validateInputParameters()

void validateInputParameters
privatevirtual

Definition at line 424 of file cpipricevolatilitysurface.hpp.

424 {
425 QL_REQUIRE(!expiries_.empty(), "Need at least one tenor");
426 QL_REQUIRE(!floorStrikes_.empty() || !capStrikes_.empty(), "cap and floor strikes can not be both empty");
427 QL_REQUIRE(capPrices_.rows() == capStrikes_.size() && capPrices_.columns() == (capStrikes_.empty() ? 0 : expiries_.size()),
428 "mismatch between cap price matrix dimension and number of strikes and tenors");
429 QL_REQUIRE(floorPrices_.rows() == floorStrikes_.size() &&
430 floorPrices_.columns() == (floorStrikes_.empty() ? 0 : expiries_.size()),
431 "mismatch between cap price matrix dimension and number of strikes and tenors");
432
433 // Some basic arbitrage checks
434 for (size_t tenorIdx = 0; tenorIdx < capPrices_.columns(); ++tenorIdx) {
435 double prevPrice = std::numeric_limits<double>::max();
436 for (size_t strikeIdx = 0; strikeIdx < capPrices_.rows(); ++strikeIdx) {
437 double currentPrice = capPrices_[strikeIdx][tenorIdx];
438 QL_REQUIRE(ignoreMissingPrices_ || currentPrice != QuantLib::Null<QuantLib::Real>(),
439 "Input prices can not be null");
440 QL_REQUIRE(!QuantLib::close_enough(0.0, currentPrice) && currentPrice > 0.0, "No zero cap prices allowd");
441 if (currentPrice != QuantLib::Null<Real>()) {
442 QL_REQUIRE(currentPrice <= prevPrice, "Non decreasing cap prices");
443 prevPrice = currentPrice;
444 }
445 }
446 }
447
448 for (size_t tenorIdx = 0; tenorIdx < floorPrices_.columns(); ++tenorIdx) {
449 double prevPrice = QL_EPSILON;
450 for (size_t strikeIdx = 0; strikeIdx < floorPrices_.rows(); ++strikeIdx) {
451 double currentPrice = floorPrices_[strikeIdx][tenorIdx];
452 QL_REQUIRE(ignoreMissingPrices_ || currentPrice != QuantLib::Null<QuantLib::Real>(),
453 "Input prices can not be null");
454 QL_REQUIRE(!QuantLib::close_enough(0.0, currentPrice) && currentPrice > 0.0, "No zero cap prices allowd");
455 if (currentPrice != QuantLib::Null<Real>()) {
456 QL_REQUIRE(currentPrice >= prevPrice, "Non increasing floor prices");
457 prevPrice = currentPrice;
458 }
459 }
460 }
461}
+ Here is the caller graph for this function:

◆ initializeStrikes()

void initializeStrikes
privatevirtual

Definition at line 464 of file cpipricevolatilitysurface.hpp.

464 {
465 strikes_.clear();
466 std::set<double> uniqueStrikes(floorStrikes_.begin(), floorStrikes_.end());
467 uniqueStrikes.insert(capStrikes_.begin(), capStrikes_.end());
468 std::unique_copy(uniqueStrikes.begin(), uniqueStrikes.end(), std::back_inserter(strikes_),
469 [](double a, double b) { return QuantLib::close_enough(a, b); });
470}
+ Here is the caller graph for this function:

◆ priceFromPutCallParity()

double priceFromPutCallParity ( double  price,
bool  isCapPrice,
double  atm,
double  strikeGrowth,
double  df 
) const
private

Computes a cap price from a floor price using the put-call parity and vice-versa.

Definition at line 474 of file cpipricevolatilitysurface.hpp.

475 {
476 if (isCapPrice) {
477 return price + atm - strikeGrowth * df;
478 } else {
479 return price + strikeGrowth * df - atm;
480 }
481}

◆ floorPrice()

double floorPrice ( double  strike,
size_t  tenorIdx,
double  atm,
double  strikeGrowth,
double  df 
) const
private

Returns floor price for strike level (average annual inflation) and maturity index.

Definition at line 485 of file cpipricevolatilitysurface.hpp.

487 {
488 auto close_enough = [&strike](const double& x) { return QuantLib::close_enough(strike, x); };
489 auto itCap = std::find_if(capStrikes_.begin(), capStrikes_.end(), close_enough);
490 auto itFloor = std::find_if(floorStrikes_.begin(), floorStrikes_.end(), close_enough);
491 if (itFloor != floorStrikes_.end()) {
492 size_t floorPriceIdx = std::distance(floorStrikes_.begin(), itFloor);
493 return floorPrices_[floorPriceIdx][tenorIdx];
494 } else if (itCap != capStrikes_.end()) {
495 size_t capPriceIdx = std::distance(capStrikes_.begin(), itCap);
496 double capPrice = capPrices_[capPriceIdx][tenorIdx];
497 return priceFromPutCallParity(capPrice, true, atm, strikeGrowth, df);
498 } else {
499 return QuantLib::Null<double>();
500 }
501}
double priceFromPutCallParity(double price, bool isCapPrice, double atm, double strikeGrowth, double df) const
Computes a cap price from a floor price using the put-call parity and vice-versa.
Filter close_enough(const RandomVariable &x, const RandomVariable &y)
+ Here is the call graph for this function:

◆ capPrice()

double capPrice ( double  strike,
size_t  tenorIdx,
double  atm,
double  strikeGrowth,
double  df 
) const
private

Returns cap price for strike level (average annual inflation) and maturity index.

Definition at line 505 of file cpipricevolatilitysurface.hpp.

507 {
508 auto close_enough = [&strike](const double& x) { return QuantLib::close_enough(strike, x); };
509 auto itCap = std::find_if(capStrikes_.begin(), capStrikes_.end(), close_enough);
510 auto itFloor = std::find_if(floorStrikes_.begin(), floorStrikes_.end(), close_enough);
511 if (itCap != capStrikes_.end()) {
512 size_t capPriceIdx = std::distance(capStrikes_.begin(), itCap);
513 return capPrices_[capPriceIdx][tenorIdx];
514 } else if (itFloor != floorStrikes_.end()) {
515 size_t floorPriceIdx = std::distance(floorStrikes_.begin(), itFloor);
516 double floorPrice = floorPrices_[floorPriceIdx][tenorIdx];
517 return priceFromPutCallParity(floorPrice, false, atm, strikeGrowth, df);
518 } else {
519 return QuantLib::Null<double>();
520 }
521}
+ Here is the call graph for this function:

◆ volatilityImpl()

QuantLib::Real volatilityImpl ( QuantLib::Time  length,
QuantLib::Rate  strike 
) const
overrideprivate

Definition at line 402 of file cpipricevolatilitysurface.hpp.

403 {
404 calculate();
405 return volSurface_->getValue(length, strike);
406}

◆ chooseFloor()

bool chooseFloor ( QuantLib::Real  strike,
QuantLib::Real  atmRate 
) const
private

Definition at line 329 of file cpipricevolatilitysurface.hpp.

330 {
331 if (floorStrikes_.empty()) {
332 return false;
333 }
334
335 if (capStrikes_.empty()) {
336 return true;
337 }
338
339 if (preference_ == Floor) {
340 if (strike <= floorStrikes_.back())
341 return true;
342 else
343 return false;
344 }
345
346 if (preference_ == Cap) {
347 if (strike < capStrikes_.front())
348 return true;
349 else
350 return false;
351 }
352
353 // else: Use floors where we have floor quotes only, caps where we have cap quotes only,
354 // and decide based on ATM where we have both cap and floor quotes
355
356 // 1) strike < maxFloorStrike < minCapStrike: Floor!
357 if (strike <= floorStrikes_.back() && strike < capStrikes_.front())
358 return true;
359 // 2) strike > maxFloorStrike and strike >= minCapStrike: Cap!
360 else if (strike > floorStrikes_.back() && strike >= capStrikes_.front())
361 return false;
362 // 3) Overlap, maxFloorStrike > minCapStrike and strike in between: Depends on atmRate which surface we pick
363 else if (strike <= floorStrikes_.back() && strike >= capStrikes_.front()) {
364 // we have overlapping strikes, decide depending on atm level
365 if (strike < atmRate)
366 return true;
367 else
368 return false;
369 // 4) Gap, maxFloorStrike < minCapStrike and strike in the gap: Depends on atmRate which surface we
370 // extrapolate
371 } else if (strike > floorStrikes_.back() && strike < capStrikes_.front()) {
372 // there is a gap between floor end and caps begin, decide again depending on strike level
373 if (strike < atmRate)
374 return true;
375 else
376 return false;
377 } else {
378 QL_FAIL("case not covered in StrippedCPIVolatilitySurface: strike="
379 << strike << " maxFloorStrike=" << floorStrikes_.back() << " minCapStrike=" << capStrikes_.front()
380 << " atm=" << atmRate);
381 return false;
382 }
383}

◆ implyVol()

double implyVol ( double  strike,
const QuantLib::Date &  maturity,
double  price,
bool  isFloor 
) const
private

Definition at line 524 of file cpipricevolatilitysurface.hpp.

526 {
527 QuantLib::Date startDate = capFloorStartDate();
528 QuantLib::Calendar cal = calendar();
529 auto bdc = businessDayConvention();
530 auto dc = dayCounter();
531 auto index = index_;
532 auto freq = frequency();
533 auto obsLag = observationLag();
534
535 QuantLib::CPICapFloor capFloor(isFloor ? QuantLib::Option::Put : QuantLib::Option::Call,
536 1.0, // unit nominal, because the price surface returns unit nominal prices
537 capFloorStartDate(), baseCPI(), maturity, calendar(), businessDayConvention(),
538 calendar(), businessDayConvention(), strike,
539 index_, observationLag(),
540 indexIsInterpolated() ? QuantLib::CPI::Linear : QuantLib::CPI::Flat);
541
542 QuantLib::ext::shared_ptr<QuantExt::CPICapFloorEngine> engine = engine_;
543
544 bool interpolated = indexIsInterpolated();
545 capFloor.setPricingEngine(engine);
546
547 auto targetFunction = [&engine, &cal, &dc, &bdc, &startDate, &obsLag, &freq, &price,
548 &capFloor, &interpolated](const double& guess) {
549 QuantLib::ext::shared_ptr<QuantExt::ConstantCPIVolatility> vol = QuantLib::ext::make_shared<QuantExt::ConstantCPIVolatility>(
550 guess, 0, cal, bdc, dc, obsLag, freq, interpolated, startDate);
551
552 engine->setVolatility(QuantLib::Handle<QuantLib::CPIVolatilitySurface>(vol));
553
554 QuantLib::Real npv = capFloor.NPV();
555 return price - npv;
556 };
557 QuantLib::Brent solver;
558 QuantLib::Real guess = (upperVolBound_ + lowerVolBound_) / 2.0;
559 return solver.solve(targetFunction, solverTolerance_, guess, lowerVolBound_, upperVolBound_);
560}

Member Data Documentation

◆ preference_

PriceQuotePreference preference_
private

Definition at line 176 of file cpipricevolatilitysurface.hpp.

◆ index_

QuantLib::ext::shared_ptr<QuantLib::ZeroInflationIndex> index_
private

Definition at line 177 of file cpipricevolatilitysurface.hpp.

◆ yts_

QuantLib::Handle<QuantLib::YieldTermStructure> yts_
private

Definition at line 178 of file cpipricevolatilitysurface.hpp.

◆ capStrikes_

std::vector<double> capStrikes_
private

Definition at line 179 of file cpipricevolatilitysurface.hpp.

◆ floorStrikes_

std::vector<double> floorStrikes_
private

Definition at line 180 of file cpipricevolatilitysurface.hpp.

◆ engine_

QuantLib::ext::shared_ptr<QuantExt::CPICapFloorEngine> engine_
private

Definition at line 182 of file cpipricevolatilitysurface.hpp.

◆ ignoreMissingPrices_

bool ignoreMissingPrices_
private

Definition at line 183 of file cpipricevolatilitysurface.hpp.

◆ lowerStrikeConstExtrap_

bool lowerStrikeConstExtrap_
private

Definition at line 184 of file cpipricevolatilitysurface.hpp.

◆ upperStrikeConstExtrap_

bool upperStrikeConstExtrap_
private

Definition at line 185 of file cpipricevolatilitysurface.hpp.

◆ upperVolBound_

QuantLib::Real upperVolBound_
private

Definition at line 186 of file cpipricevolatilitysurface.hpp.

◆ lowerVolBound_

QuantLib::Real lowerVolBound_
private

Definition at line 187 of file cpipricevolatilitysurface.hpp.

◆ solverTolerance_

QuantLib::Real solverTolerance_
private

Definition at line 188 of file cpipricevolatilitysurface.hpp.

◆ expiries_

std::vector<QuantLib::Period> expiries_
private

Definition at line 190 of file cpipricevolatilitysurface.hpp.

◆ strikes_

std::vector<QuantLib::Rate> strikes_
mutableprivate

Definition at line 191 of file cpipricevolatilitysurface.hpp.

◆ capPrices_

QuantLib::Matrix capPrices_
private

Definition at line 193 of file cpipricevolatilitysurface.hpp.

◆ floorPrices_

QuantLib::Matrix floorPrices_
private

Definition at line 194 of file cpipricevolatilitysurface.hpp.

◆ fixingDates_

std::vector<QuantLib::Date> fixingDates_
mutableprivate

Definition at line 195 of file cpipricevolatilitysurface.hpp.

◆ volData_

QuantLib::Matrix volData_
mutableprivate

Definition at line 196 of file cpipricevolatilitysurface.hpp.

◆ missingPrices_

std::vector<std::vector<bool> > missingPrices_
mutableprivate

Definition at line 197 of file cpipricevolatilitysurface.hpp.

◆ failedPrices_

std::vector<std::vector<bool> > failedPrices_
mutableprivate

Definition at line 198 of file cpipricevolatilitysurface.hpp.

◆ volSurface_

QuantLib::ext::shared_ptr<QuantExt::OptionInterpolator2d<InterpolatorStrike, InterpolatorTime> > volSurface_
mutableprivate

Definition at line 200 of file cpipricevolatilitysurface.hpp.