Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Classes | Public Member Functions | List of all members
OptionletStripperWithAtm< TimeInterpolator, SmileInterpolator > Class Template Reference

#include <qle/termstructures/optionletstripperwithatm.hpp>

+ Inheritance diagram for OptionletStripperWithAtm< TimeInterpolator, SmileInterpolator >:
+ Collaboration diagram for OptionletStripperWithAtm< TimeInterpolator, SmileInterpolator >:

Classes

class  ObjectiveFunction
 Class that is used to imply the spreads at each tenor such that the ATM cap floor volatilities are retrieved. More...
 
class  ObjectiveFunctionOIS
 

Public Member Functions

 OptionletStripperWithAtm (const QuantLib::ext::shared_ptr< QuantExt::OptionletStripper > &osBase, const QuantLib::Handle< CapFloorTermVolCurve > &atmCurve, const QuantLib::Handle< QuantLib::YieldTermStructure > &discount=QuantLib::Handle< QuantLib::YieldTermStructure >(), const QuantLib::VolatilityType atmVolatilityType=QuantLib::ShiftedLognormal, QuantLib::Real atmDisplacement=0.0, QuantLib::Size maxEvaluations=10000, QuantLib::Real accuracy=1.0e-12, const TimeInterpolator &ti=TimeInterpolator(), const SmileInterpolator &si=SmileInterpolator())
 Constructor. More...
 
Inspectors
std::vector< QuantLib::Rate > atmStrikes () const
 
std::vector< QuantLib::Real > atmPrices () const
 
std::vector< QuantLib::Volatility > volSpreads () const
 
- Public Member Functions inherited from OptionletStripper
const std::vector< Rate > & optionletStrikes (Size i) const override
 
const std::vector< Volatility > & optionletVolatilities (Size i) const override
 
const std::vector< Date > & optionletFixingDates () const override
 
const std::vector< Time > & optionletFixingTimes () const override
 
Size optionletMaturities () const override
 
const std::vector< Rate > & atmOptionletRates () const override
 
DayCounter dayCounter () const override
 
Calendar calendar () const override
 
Natural settlementDays () const override
 
BusinessDayConvention businessDayConvention () const override
 
const std::vector< Period > & optionletFixingTenors () const
 
const std::vector< Date > & optionletPaymentDates () const
 
const std::vector< Time > & optionletAccrualPeriods () const
 
ext::shared_ptr< CapFloorTermVolSurfacetermVolSurface () const
 
ext::shared_ptr< IborIndex > index () const
 
Real displacement () const override
 
VolatilityType volatilityType () const override
 
const Period & rateComputationPeriod () const
 

LazyObject interface

QuantLib::ext::shared_ptr< QuantExt::OptionletStripperosBase_
 Base optionlet stripper. More...
 
QuantLib::Handle< CapFloorTermVolCurveatmCurve_
 ATM volatility curve. More...
 
QuantLib::VolatilityType atmVolatilityType_
 ATM volatility type. More...
 
QuantLib::Real atmDisplacement_
 ATM volatility shift if the ATM volatility type is ShiftedLognormal. More...
 
QuantLib::Size maxEvaluations_
 Maximum number of evaluations when searching for spread to match ATM volatilities. More...
 
QuantLib::Real accuracy_
 Required accuracy when searching for spread to match ATM volatilities. More...
 
TimeInterpolator ti_
 The interpolation object in the time direction. More...
 
SmileInterpolator si_
 The interpolation object in the strike direction. More...
 
DayCounter dayCounter_
 The day counter for atmCurve_ and osBase_. More...
 
Size nAtmExpiries_
 The number of ATM instruments in the ATM curve, atmCurve_. More...
 
std::vector< QuantLib::Rate > atmStrikes_
 
std::vector< QuantLib::Real > atmPrices_
 
std::vector< QuantLib::Volatility > volSpreads_
 
std::vector< QuantLib::ext::shared_ptr< QuantLib::CapFloor > > caps_
 
std::vector< QuantLib::Leg > capsOIS_
 
void performCalculations () const override
 
std::vector< QuantLib::Volatility > volSpreads (const QuantLib::Handle< QuantLib::YieldTermStructure > &discount, const QuantLib::Handle< QuantLib::OptionletVolatilityStructure > &ovs, const bool isOis) const
 Return the implied optionlet spreads to retrieve the ATM cap floor term volatilities. More...
 

Additional Inherited Members

- Protected Member Functions inherited from OptionletStripper
 OptionletStripper (const ext::shared_ptr< QuantExt::CapFloorTermVolSurface > &, const ext::shared_ptr< IborIndex > &index, const Handle< YieldTermStructure > &discount=Handle< YieldTermStructure >(), const VolatilityType type=ShiftedLognormal, const Real displacement=0.0, const Period &rateComputationPeriod=0 *Days, const Size onCapSettlementDays=0)
 
virtual void populateDates () const
 Method to populate the dates, times and accruals that can be overridden in derived classes. More...
 
- Protected Attributes inherited from OptionletStripper
ext::shared_ptr< CapFloorTermVolSurfacetermVolSurface_
 
ext::shared_ptr< IborIndex > index_
 
Handle< YieldTermStructure > discount_
 
Size nStrikes_
 
Size nOptionletTenors_
 
std::vector< std::vector< Rate > > optionletStrikes_
 
std::vector< std::vector< Volatility > > optionletVolatilities_
 
std::vector< Time > optionletTimes_
 
std::vector< Date > optionletDates_
 
std::vector< Period > optionletTenors_
 
std::vector< Rate > atmOptionletRate_
 
std::vector< Date > optionletPaymentDates_
 
std::vector< Time > optionletAccrualPeriods_
 
std::vector< Period > capFloorLengths_
 
const VolatilityType volatilityType_
 
const Real displacement_
 
const Period rateComputationPeriod_
 
const Size onCapSettlementDays_
 

Detailed Description

template<class TimeInterpolator, class SmileInterpolator>
class QuantExt::OptionletStripperWithAtm< TimeInterpolator, SmileInterpolator >

Optionlet stripper that amends existing stripped optionlets to incorporate ATM cap floor term volatilities

Definition at line 50 of file optionletstripperwithatm.hpp.

Constructor & Destructor Documentation

◆ OptionletStripperWithAtm()

OptionletStripperWithAtm ( const QuantLib::ext::shared_ptr< QuantExt::OptionletStripper > &  osBase,
const QuantLib::Handle< CapFloorTermVolCurve > &  atmCurve,
const QuantLib::Handle< QuantLib::YieldTermStructure > &  discount = QuantLib::Handle<QuantLib::YieldTermStructure>(),
const QuantLib::VolatilityType  atmVolatilityType = QuantLib::ShiftedLognormal,
QuantLib::Real  atmDisplacement = 0.0,
QuantLib::Size  maxEvaluations = 10000,
QuantLib::Real  accuracy = 1.0e-12,
const TimeInterpolator &  ti = TimeInterpolator(),
const SmileInterpolator &  si = SmileInterpolator() 
)

Constructor.

Definition at line 149 of file optionletstripperwithatm.hpp.

155 : QuantExt::OptionletStripper(osBase->termVolSurface(), osBase->index(), discount, osBase->volatilityType(),
156 osBase->displacement(), osBase->rateComputationPeriod()),
157 osBase_(osBase), atmCurve_(atmCurve), atmVolatilityType_(atmVolatilityType), atmDisplacement_(atmDisplacement),
158 maxEvaluations_(maxEvaluations), accuracy_(accuracy), dayCounter_(osBase_->termVolSurface()->dayCounter()),
161
162 registerWith(osBase_);
163 registerWith(atmCurve_);
164
165 QL_REQUIRE(dayCounter_ == atmCurve_->dayCounter(),
166 "The ATM curve day counter should equal that of the underlying base optionlet stripper");
167}
QuantLib::VolatilityType atmVolatilityType_
ATM volatility type.
std::vector< QuantLib::Rate > atmStrikes_
std::vector< QuantLib::ext::shared_ptr< QuantLib::CapFloor > > caps_
DayCounter dayCounter_
The day counter for atmCurve_ and osBase_.
Size nAtmExpiries_
The number of ATM instruments in the ATM curve, atmCurve_.
std::vector< QuantLib::Volatility > volSpreads_
QuantLib::Real atmDisplacement_
ATM volatility shift if the ATM volatility type is ShiftedLognormal.
QuantLib::Real accuracy_
Required accuracy when searching for spread to match ATM volatilities.
QuantLib::Handle< CapFloorTermVolCurve > atmCurve_
ATM volatility curve.
QuantLib::Size maxEvaluations_
Maximum number of evaluations when searching for spread to match ATM volatilities.
QuantLib::ext::shared_ptr< QuantExt::OptionletStripper > osBase_
Base optionlet stripper.
std::vector< QuantLib::Real > atmPrices_

Member Function Documentation

◆ atmStrikes()

std::vector< QuantLib::Rate > atmStrikes

Definition at line 170 of file optionletstripperwithatm.hpp.

170 {
171 calculate();
172 return atmStrikes_;
173}

◆ atmPrices()

std::vector< QuantLib::Real > atmPrices

Definition at line 176 of file optionletstripperwithatm.hpp.

176 {
177 calculate();
178 return atmPrices_;
179}

◆ volSpreads() [1/2]

std::vector< QuantLib::Volatility > volSpreads

Definition at line 183 of file optionletstripperwithatm.hpp.

183 {
184 calculate();
185 return volSpreads_;
186}

◆ performCalculations()

void performCalculations
override

Definition at line 189 of file optionletstripperwithatm.hpp.

189 {
190
191 // Some localised typedefs and using declarations to make the code more readable
192 using QuantLib::BachelierCapFloorEngine;
193 using QuantLib::BlackCapFloorEngine;
194 using QuantLib::Handle;
195 using QuantLib::MakeCapFloor;
196 using QuantLib::OptionletVolatilityStructure;
197 using QuantLib::Period;
198 using QuantLib::Size;
199 using QuantLib::Time;
200 using QuantLib::Volatility;
201 using QuantLib::YieldTermStructure;
202 using std::vector;
203
204 bool isOis = QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(index_) != nullptr;
205
206 // Possible update based on underlying optionlet stripper data
207 optionletDates_ = osBase_->optionletFixingDates();
208 optionletPaymentDates_ = osBase_->optionletPaymentDates();
209 optionletAccrualPeriods_ = osBase_->optionletAccrualPeriods();
210 optionletTimes_ = osBase_->optionletFixingTimes();
211 atmOptionletRate_ = osBase_->atmOptionletRates();
212 for (Size i = 0; i < optionletTimes_.size(); ++i) {
213 optionletStrikes_[i] = osBase_->optionletStrikes(i);
214 optionletVolatilities_[i] = osBase_->optionletVolatilities(i);
215 }
216
217 // ATM curve tenors
218 const vector<Period>& atmTenors = atmCurve_->optionTenors();
219 vector<Time> atmTimes(atmTenors.size());
220 for (Size i = 0; i < atmTenors.size(); ++i) {
221 Date d = atmCurve_->optionDateFromTenor(atmTenors[i]);
222 atmTimes[i] = atmCurve_->timeFromReference(d);
223 }
224
225 // discount curve
226 const Handle<YieldTermStructure>& discountCurve = discount_.empty() ? index_->forwardingTermStructure() : discount_;
227
228 // Populate ATM strikes and prices
229 for (Size j = 0; j < nAtmExpiries_; ++j) {
230
231 if (isOis) {
232
233 Volatility atmVol = atmCurve_->volatility(atmTimes[j], 0.01);
234 auto pricer = QuantLib::ext::make_shared<BlackOvernightIndexedCouponPricer>(
235 Handle<OptionletVolatilityStructure>(QuantLib::ext::make_shared<ConstantOptionletVolatility>(
236 0, NullCalendar(), Unadjusted, atmVol, Actual365Fixed(), volatilityType(), false)));
237 capsOIS_[j] =
238 MakeOISCapFloor(CapFloor::Cap, atmTenors[j], QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(index_),
239 osBase_->rateComputationPeriod(), Null<Real>(), discountCurve)
240 .withCouponPricer(pricer);
241 QL_REQUIRE(!capsOIS_[j].empty(),
242 "OptionletStripperWithAtm: internal error: empty cap for expiry " << atmTenors[j]);
243 atmStrikes_[j] = getOisCapFloorStrikes(capsOIS_[j]).front().first;
244 atmPrices_[j] = QuantLib::CashFlows::npv(capsOIS_[j], **discountCurve, false);
245
246 } else {
247
248 // Create a cap for each pillar point on ATM curve and attach relevant pricing engine
249 Volatility atmVol = atmCurve_->volatility(atmTimes[j], 0.01);
250 QuantLib::ext::shared_ptr<PricingEngine> engine;
251 if (atmVolatilityType_ == ShiftedLognormal) {
252 engine = QuantLib::ext::make_shared<BlackCapFloorEngine>(discountCurve, atmVol, dayCounter_, atmDisplacement_);
253 } else if (atmVolatilityType_ == Normal) {
254 engine = QuantLib::ext::make_shared<BachelierCapFloorEngine>(discountCurve, atmVol, dayCounter_);
255 } else {
256 QL_FAIL("Unknown volatility type: " << atmVolatilityType_);
257 }
258
259 // Using Null<Rate>() as strike => strike will be set to ATM rate. However, to calculate ATM rate, QL
260 // requires a BlackCapFloorEngine to be set (not a BachelierCapFloorEngine)! So, need a temp
261 // BlackCapFloorEngine with a dummy vol to calculate ATM rate. Needs to be fixed in QL.
262 QuantLib::ext::shared_ptr<PricingEngine> tempEngine = QuantLib::ext::make_shared<BlackCapFloorEngine>(discountCurve, 0.01);
263 caps_[j] =
264 MakeCapFloor(CapFloor::Cap, atmTenors[j], index_, Null<Rate>(), 0 * Days).withPricingEngine(tempEngine);
265
266 // Now set correct engine and get the ATM rate and the price
267 caps_[j]->setPricingEngine(engine);
268 atmStrikes_[j] = caps_[j]->atmRate(**discountCurve);
269 atmPrices_[j] = caps_[j]->NPV();
270 }
271 }
272
273 // Create an optionlet volatility structure from the underlying stripped optionlet surface
274 QuantLib::ext::shared_ptr<OptionletVolatilityStructure> ovs =
275 QuantLib::ext::make_shared<QuantExt::StrippedOptionletAdapter<TimeInterpolator, SmileInterpolator> >(
276 atmCurve_->referenceDate(), osBase_);
277 ovs->enableExtrapolation();
278
279 // Imply the volatility spreads that match the ATM prices
280 volSpreads_ = volSpreads(discountCurve, Handle<OptionletVolatilityStructure>(ovs), isOis);
281
282 // This stripped optionlet surface is the underlying stripped optionlet surface modified by the implied spreads
283 for (Size j = 0; j < nAtmExpiries_; ++j) {
284 for (Size i = 0; i < optionletTimes_.size(); ++i) {
285 if (i < (isOis ? capsOIS_[j].size() : caps_[j]->floatingLeg().size())) {
286
287 Volatility unadjustedVol = ovs->volatility(optionletTimes_[i], atmStrikes_[j]);
288 Volatility adjustedVol = unadjustedVol + volSpreads_[j];
289
290 // insert ATM strike and adjusted volatility
291 vector<Rate>::const_iterator previous =
292 lower_bound(optionletStrikes_[i].begin(), optionletStrikes_[i].end(), atmStrikes_[j]);
293 Size insertIndex = previous - optionletStrikes_[i].begin();
294 optionletStrikes_[i].insert(optionletStrikes_[i].begin() + insertIndex, atmStrikes_[j]);
295 optionletVolatilities_[i].insert(optionletVolatilities_[i].begin() + insertIndex, adjustedVol);
296 }
297 }
298 }
299}
std::vector< Rate > atmOptionletRate_
std::vector< std::vector< Volatility > > optionletVolatilities_
Handle< YieldTermStructure > discount_
std::vector< Date > optionletPaymentDates_
std::vector< Time > optionletAccrualPeriods_
VolatilityType volatilityType() const override
std::vector< Time > optionletTimes_
std::vector< Date > optionletDates_
std::vector< std::vector< Rate > > optionletStrikes_
ext::shared_ptr< IborIndex > index_
std::vector< QuantLib::Volatility > volSpreads() const
std::vector< std::pair< Real, Real > > getOisCapFloorStrikes(const Leg &oisCapFloor)
get the (cap, floor) - strikes from an OIS cf
+ Here is the call graph for this function:

◆ volSpreads() [2/2]

std::vector< QuantLib::Volatility > volSpreads ( const QuantLib::Handle< QuantLib::YieldTermStructure > &  discount,
const QuantLib::Handle< QuantLib::OptionletVolatilityStructure > &  ovs,
const bool  isOis 
) const
private

Return the implied optionlet spreads to retrieve the ATM cap floor term volatilities.

Definition at line 302 of file optionletstripperwithatm.hpp.

304 {
305
306 // Some localised typedefs and using declarations to make the code more readable
307 using QuantLib::Size;
308 using QuantLib::Volatility;
309 using std::vector;
310
311 QuantLib::Brent solver;
312 vector<Volatility> result(nAtmExpiries_);
313 Volatility guess = 0.0001;
314 Volatility minSpread = -0.1;
315 Volatility maxSpread = 0.1;
316 solver.setMaxEvaluations(maxEvaluations_);
317
318 for (Size j = 0; j < nAtmExpiries_; ++j) {
319 if (isOis) {
320 ObjectiveFunctionOIS f(ovs, capsOIS_[j], atmPrices_[j], discount);
321 result[j] = solver.solve(f, accuracy_, guess, minSpread, maxSpread);
322 } else {
323 ObjectiveFunction f(ovs, caps_[j], atmPrices_[j], discount);
324 result[j] = solver.solve(f, accuracy_, guess, minSpread, maxSpread);
325 }
326 }
327
328 return result;
329}

Member Data Documentation

◆ osBase_

QuantLib::ext::shared_ptr<QuantExt::OptionletStripper> osBase_
private

Base optionlet stripper.

Definition at line 112 of file optionletstripperwithatm.hpp.

◆ atmCurve_

QuantLib::Handle<CapFloorTermVolCurve> atmCurve_
private

ATM volatility curve.

Definition at line 115 of file optionletstripperwithatm.hpp.

◆ atmVolatilityType_

QuantLib::VolatilityType atmVolatilityType_
private

ATM volatility type.

Definition at line 118 of file optionletstripperwithatm.hpp.

◆ atmDisplacement_

QuantLib::Real atmDisplacement_
private

ATM volatility shift if the ATM volatility type is ShiftedLognormal.

Definition at line 121 of file optionletstripperwithatm.hpp.

◆ maxEvaluations_

QuantLib::Size maxEvaluations_
private

Maximum number of evaluations when searching for spread to match ATM volatilities.

Definition at line 124 of file optionletstripperwithatm.hpp.

◆ accuracy_

QuantLib::Real accuracy_
private

Required accuracy when searching for spread to match ATM volatilities.

Definition at line 127 of file optionletstripperwithatm.hpp.

◆ ti_

TimeInterpolator ti_
private

The interpolation object in the time direction.

Definition at line 130 of file optionletstripperwithatm.hpp.

◆ si_

SmileInterpolator si_
private

The interpolation object in the strike direction.

Definition at line 133 of file optionletstripperwithatm.hpp.

◆ dayCounter_

DayCounter dayCounter_
private

The day counter for atmCurve_ and osBase_.

Definition at line 136 of file optionletstripperwithatm.hpp.

◆ nAtmExpiries_

Size nAtmExpiries_
private

The number of ATM instruments in the ATM curve, atmCurve_.

Definition at line 139 of file optionletstripperwithatm.hpp.

◆ atmStrikes_

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

Definition at line 141 of file optionletstripperwithatm.hpp.

◆ atmPrices_

std::vector<QuantLib::Real> atmPrices_
mutableprivate

Definition at line 142 of file optionletstripperwithatm.hpp.

◆ volSpreads_

std::vector<QuantLib::Volatility> volSpreads_
mutableprivate

Definition at line 143 of file optionletstripperwithatm.hpp.

◆ caps_

std::vector<QuantLib::ext::shared_ptr<QuantLib::CapFloor> > caps_
mutableprivate

Definition at line 144 of file optionletstripperwithatm.hpp.

◆ capsOIS_

std::vector<QuantLib::Leg> capsOIS_
mutableprivate

Definition at line 145 of file optionletstripperwithatm.hpp.