43 {
44
45 Calendar cal =
yoyIndex_->yoyInflationTermStructure()->calendar();
46 Period obsLag =
yoyIndex_->yoyInflationTermStructure()->observationLag();
48 DayCounter dc =
yoyIndex_->yoyInflationTermStructure()->dayCounter();
49 BusinessDayConvention bdc =
volSurface_->businessDayConvention();
50
51 Frequency frequency =
yoyIndex_->frequency();
52
54 std::vector<Period> terms =
volSurface_->optionTenors();
55 std::vector<Time> times =
volSurface_->optionTimes();
56
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));
61 }
62
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>());
65
66
67 for (Size i = 0; i < optionletTerms.size(); i++) {
68 for (Size j = 0; j <
strikes.size(); j++) {
70
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_);
79 } else {
80 pe = QuantLib::ext::make_shared<YoYInflationUnitDisplacedBlackCapFloorEngine>(
yoyIndex_, hovs,
nominalTs_);
81 }
82 }
else if (
type_ == Normal) {
83 pe = QuantLib::ext::make_shared<YoYInflationBachelierCapFloorEngine>(
yoyIndex_, hovs,
nominalTs_);
84 } else {
85 QL_FAIL(
"unknown volatility type: " <<
type_);
86 }
87
88 YoYInflationCapFloor cap = YoYInflationCapFloor(
89 MakeYoYInflationCapFloor(YoYInflationCapFloor::Cap,
yoyIndex_, optionletTerms[i].length(), cal, obsLag)
91 .withPricingEngine(pe)
92 .withNominal(10000));
93 cPrice[j][i] = cap.NPV();
94
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();
102 }
103 }
104
105
106
107 int jCritical = 0;
108 while (jCritical <
static_cast<int>(
strikes.size()) &&
109 fPrice[jCritical][optionletTerms.size() - 1] < cPrice[jCritical][optionletTerms.size() - 1])
110 ++jCritical;
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];
119 }
121 }
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];
125 }
126 fStrikes.push_back(
strikes[j]);
127 }
128
129 Rate baseRate =
yoyIndex_->yoyInflationTermStructure()->baseRate();
132 optionletTerms, cPriceFinal, fPriceFinal);
133
134 QuantLib::ext::shared_ptr<QuantExt::InterpolatedYoYCapFloorTermPriceSurface<Bilinear, Linear>> yoySurface =
135 QuantLib::ext::make_shared<QuantExt::InterpolatedYoYCapFloorTermPriceSurface<Bilinear, Linear>>(ys);
136 yoySurface->enableExtrapolation();
137
138 QuantLib::ext::shared_ptr<InterpolatedYoYOptionletStripper<Linear>> yoyStripper =
139 QuantLib::ext::make_shared<InterpolatedYoYOptionletStripper<Linear>>();
140
141
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);
147
148 QuantLib::ext::shared_ptr<YoYInflationBachelierCapFloorEngine> cfEngine =
149 QuantLib::ext::make_shared<YoYInflationBachelierCapFloorEngine>(
yoyIndex_, hovs,
nominalTs_);
150
151 yoyOptionletVolSurface_ = QuantLib::ext::make_shared<QuantExt::KInterpolatedYoYOptionletVolatilitySurface<Linear>>(
152 settDays, cal, bdc, dc, obsLag, yoySurface, cfEngine, yoyStripper, 0, Linear(),
type_,
displacement_);
154}
Interpolated YoY Inflation Cap floor term price surface.