21#include <ql/experimental/inflation/interpolatedyoyoptionletstripper.hpp>
22#include <ql/instruments/makeyoyinflationcapfloor.hpp>
23#include <ql/math/interpolations/bilinearinterpolation.hpp>
24#include <ql/math/interpolations/linearinterpolation.hpp>
28#include <boost/make_shared.hpp>
31using QuantLib::ext::shared_ptr;
36 const QuantLib::ext::shared_ptr<CapFloorTermVolSurface>& volSurface,
const QuantLib::ext::shared_ptr<YoYInflationIndex>& index,
37 const Handle<YieldTermStructure>& nominalTs, VolatilityType type, Real displacement)
38 : volSurface_(volSurface), yoyIndex_(index), nominalTs_(nominalTs), type_(type), displacement_(displacement) {
45 Calendar cal =
yoyIndex_->yoyInflationTermStructure()->calendar();
46 Period obsLag =
yoyIndex_->yoyInflationTermStructure()->observationLag();
48 DayCounter dc =
yoyIndex_->yoyInflationTermStructure()->dayCounter();
49 BusinessDayConvention bdc =
volSurface_->businessDayConvention();
51 Frequency frequency =
yoyIndex_->frequency();
54 std::vector<Period> terms =
volSurface_->optionTenors();
55 std::vector<Time> times =
volSurface_->optionTimes();
57 std::vector<Period> optionletTerms;
58 optionletTerms.push_back(terms.front());
59 while (optionletTerms.back() != terms.back()) {
60 optionletTerms.push_back(optionletTerms.back() + Period(1, Years));
63 Matrix cPrice(
strikes.size(),
strikes.size() == 0 ? 0 : optionletTerms.size(), Null<Real>()),
64 fPrice(
strikes.size(),
strikes.size() == 0 ? 0 : optionletTerms.size(), Null<Real>());
67 for (Size i = 0; i < optionletTerms.size(); i++) {
68 for (Size j = 0; j <
strikes.size(); j++) {
72 QuantLib::ext::shared_ptr<ConstantYoYOptionletVolatility> ovs(
73 new ConstantYoYOptionletVolatility(vol, settDays, cal, bdc, dc, obsLag, frequency,
false, -1.0, 3.0));
74 QuantLib::ext::shared_ptr<PricingEngine> pe;
75 Handle<QuantLib::YoYOptionletVolatilitySurface> hovs(ovs);
76 if (
type_ == ShiftedLognormal) {
78 pe = QuantLib::ext::make_shared<YoYInflationBlackCapFloorEngine>(
yoyIndex_, hovs,
nominalTs_);
80 pe = QuantLib::ext::make_shared<YoYInflationUnitDisplacedBlackCapFloorEngine>(
yoyIndex_, hovs,
nominalTs_);
82 }
else if (
type_ == Normal) {
83 pe = QuantLib::ext::make_shared<YoYInflationBachelierCapFloorEngine>(
yoyIndex_, hovs,
nominalTs_);
85 QL_FAIL(
"unknown volatility type: " <<
type_);
88 YoYInflationCapFloor cap = YoYInflationCapFloor(
89 MakeYoYInflationCapFloor(YoYInflationCapFloor::Cap,
yoyIndex_, optionletTerms[i].length(), cal, obsLag)
91 .withPricingEngine(pe)
93 cPrice[j][i] = cap.NPV();
95 YoYInflationCapFloor floor =
96 YoYInflationCapFloor(MakeYoYInflationCapFloor(YoYInflationCapFloor::Floor,
yoyIndex_,
97 optionletTerms[i].length(), cal, obsLag)
99 .withPricingEngine(pe)
100 .withNominal(10000));
101 fPrice[j][i] = floor.NPV();
108 while (jCritical <
static_cast<int>(
strikes.size()) &&
109 fPrice[jCritical][optionletTerms.size() - 1] < cPrice[jCritical][optionletTerms.size() - 1])
111 int numberOfFloors = std::max(1, jCritical - 1);
112 int numberOfCaps = std::max(1,
static_cast<int>(
strikes.size()) - jCritical + 1);
113 Matrix cPriceFinal(numberOfCaps,
strikes.size() == 0 ? 0 : optionletTerms.size());
114 Matrix fPriceFinal(numberOfFloors,
strikes.size() == 0 ? 0 : optionletTerms.size());
115 std::vector<Real> fStrikes, cStrikes;
116 for (
int j = 0; j < numberOfCaps; ++j) {
117 for (
int i = 0; i < static_cast<int>(optionletTerms.size()); ++i) {
118 cPriceFinal(j, i) = cPrice[
strikes.size() - numberOfCaps + j][i];
122 for (
int j = 0; j < numberOfFloors; ++j) {
123 for (
int i = 0; i < static_cast<int>(optionletTerms.size()); ++i) {
124 fPriceFinal(j, i) = fPrice[j][i];
126 fStrikes.push_back(
strikes[j]);
129 Rate baseRate =
yoyIndex_->yoyInflationTermStructure()->baseRate();
132 optionletTerms, cPriceFinal, fPriceFinal);
134 QuantLib::ext::shared_ptr<QuantExt::InterpolatedYoYCapFloorTermPriceSurface<Bilinear, Linear>> yoySurface =
135 QuantLib::ext::make_shared<QuantExt::InterpolatedYoYCapFloorTermPriceSurface<Bilinear, Linear>>(ys);
136 yoySurface->enableExtrapolation();
138 QuantLib::ext::shared_ptr<InterpolatedYoYOptionletStripper<Linear>> yoyStripper =
139 QuantLib::ext::make_shared<InterpolatedYoYOptionletStripper<Linear>>();
142 QuantLib::ext::shared_ptr<QuantLib::YoYOptionletVolatilitySurface> ovs =
143 QuantLib::ext::dynamic_pointer_cast<QuantLib::YoYOptionletVolatilitySurface>(
144 QuantLib::ext::make_shared<QuantLib::ConstantYoYOptionletVolatility>(0.0, settDays, cal, bdc, dc, obsLag, frequency,
145 yoySurface->indexIsInterpolated()));
146 Handle<QuantLib::YoYOptionletVolatilitySurface> hovs(ovs);
148 QuantLib::ext::shared_ptr<YoYInflationBachelierCapFloorEngine> cfEngine =
149 QuantLib::ext::make_shared<YoYInflationBachelierCapFloorEngine>(
yoyIndex_, hovs,
nominalTs_);
151 yoyOptionletVolSurface_ = QuantLib::ext::make_shared<QuantExt::KInterpolatedYoYOptionletVolatilitySurface<Linear>>(
152 settDays, cal, bdc, dc, obsLag, yoySurface, cfEngine, yoyStripper, 0, Linear(),
type_,
displacement_);
Interpolated YoY Inflation Cap floor term price surface.
QuantLib::ext::shared_ptr< QuantLib::CapFloorTermVolSurface > volSurface_
Handle< YieldTermStructure > nominalTs_
QuantLib::ext::shared_ptr< QuantExt::YoYOptionletVolatilitySurface > yoyOptionletVolSurface_
QuantLib::ext::shared_ptr< YoYInflationIndex > yoyIndex_
void performCalculations()
YoYInflationOptionletVolStripper(const QuantLib::ext::shared_ptr< QuantLib::CapFloorTermVolSurface > &volSurface, const QuantLib::ext::shared_ptr< YoYInflationIndex > &index, const Handle< YieldTermStructure > &nominalTs, VolatilityType type=ShiftedLognormal, Real displacement=0.0)
Interpolated YoY Inflation Cap floor term price surface - extends QuantLib InterpolatedYoYCapFloorTer...
fixed version of ql class (see patch 1,2,3 in the comments below)
YoY Inflation Optionlet (caplet/floorlet) volatility strippers.