27#ifndef quantext_interpolated_yoy_capfloor_term_pricesurface_hpp
28#define quantext_interpolated_yoy_capfloor_term_pricesurface_hpp
30#include <ql/experimental/inflation/yoycapfloortermpricesurface.hpp>
38template <
class Interpolator2D,
class Interpolator1D>
43 const QuantLib::ext::shared_ptr<YoYInflationIndex>& yii, Rate baseRate,
44 const Handle<YieldTermStructure>& nominal,
const DayCounter& dc,
45 const Calendar& cal,
const BusinessDayConvention& bdc,
46 const std::vector<Rate>& cStrikes,
const std::vector<Rate>& fStrikes,
47 const std::vector<Period>& cfMaturities,
const Matrix& cPrice,
49 const Interpolator2D& interpolator2d = Interpolator2D(),
50 const Interpolator1D& interpolator1d = Interpolator1D());
54 virtual Date
maxDate()
const override {
return yoy_->maxDate(); }
55 virtual Date
baseDate()
const override {
return yoy_->baseDate(); }
57 virtual Natural
fixingDays()
const override {
return fixingDays_; }
62 return atmYoYSwapTimeRates_;
65 return atmYoYSwapDateRates_;
67 virtual QuantLib::ext::shared_ptr<YoYInflationTermStructure>
YoYTS()
const override {
68 return yoyIndex_->yoyInflationTermStructure().empty() ? yoy_
69 : yoyIndex_->yoyInflationTermStructure().currentLink();
72 virtual Rate
price(
const Date& d,
const Rate k)
const override;
73 virtual Real
floorPrice(
const Date& d,
const Rate k)
const override;
74 virtual Real
capPrice(
const Date& d,
const Rate k)
const override;
75 virtual Rate
atmYoYSwapRate(
const Date& d,
bool extrapolate =
true)
const override {
78 virtual Rate
atmYoYRate(
const Date& d,
const Period& obsLag = Period(-1, Days),
bool extrapolate =
true)
const override {
82 return yoy_->yoyRate(d, obsLag,
false, extrapolate);
95 void setMaturities(std::vector<Period>& overrideMaturities) { cfMaturities_ = overrideMaturities; }
113 bool operator()(
const Real w)
const {
return QuantLib::close_enough(
v_, w); }
119template <
class Interpolator2D,
class Interpolator1D>
121 Natural fixingDays,
const Period& yyLag,
const QuantLib::ext::shared_ptr<YoYInflationIndex>& yii, Rate baseRate,
122 const Handle<YieldTermStructure>& nominal,
const DayCounter& dc,
const Calendar& cal,
123 const BusinessDayConvention& bdc,
const std::vector<Rate>& cStrikes,
const std::vector<Rate>& fStrikes,
124 const std::vector<Period>& cfMaturities,
const Matrix& cPrice,
const Matrix& fPrice,
125 const Interpolator2D& interpolator2d,
const Interpolator1D& interpolator1d)
126 :
YoYCapFloorTermPriceSurface(fixingDays, yyLag, yii, baseRate, nominal, dc, cal, bdc, cStrikes, fStrikes,
127 cfMaturities, cPrice, fPrice),
128 interpolator2d_(interpolator2d), interpolator1d_(interpolator1d) {
136 cfMaturityTimes_.clear();
137 for (Size i = 0; i < cfMaturities_.size(); i++) {
138 cfMaturityTimes_.push_back(timeFromReference(yoyOptionDateFromTenor(cfMaturities_[i])));
141 Interpolation2D capPriceTemp, floorPriceTemp;
142 capPriceTemp = interpolator2d_.interpolate(cfMaturityTimes_.begin(), cfMaturityTimes_.end(), cStrikes_.begin(),
143 cStrikes_.end(), cPrice_);
144 capPriceTemp.enableExtrapolation();
146 floorPriceTemp = interpolator2d_.interpolate(cfMaturityTimes_.begin(), cfMaturityTimes_.end(), fStrikes_.begin(),
147 fStrikes_.end(), fPrice_);
148 floorPriceTemp.enableExtrapolation();
151 if (yoyIndex_->yoyInflationTermStructure().empty()) {
154 std::vector<Real> overlappingStrikes;
155 for (Size i = 0; i < fStrikes_.size(); i++) {
156 for (Size j = 0; j < cStrikes_.size(); j++) {
157 if (fStrikes_[i] == cStrikes_[j]) {
158 overlappingStrikes.push_back(fStrikes_[i]);
162 QL_REQUIRE(overlappingStrikes.size(),
"No overlapping strikes between caps and floors for "
163 <<
"yoycapfloortermpricesurface " << yoyIndex_->name());
170 QuantLib::ext::shared_ptr<YoYInflationIndexWrapper> yiiWrapper =
171 QuantLib::ext::dynamic_pointer_cast<YoYInflationIndexWrapper>(yoyIndex_);
172 QuantLib::ext::shared_ptr<ZeroInflationTermStructure> zeroTs =
173 yiiWrapper->zeroIndex()->zeroInflationTermStructure().currentLink();
174 Real fairSwap1Y = zeroTs->zeroRate(yoyOptionDateFromTenor(Period(1, Years)));
176 Real k = Null<Real>();
177 if (fairSwap1Y < overlappingStrikes.back()) {
178 for (Size i = 0; i < overlappingStrikes.size(); i++) {
179 if (overlappingStrikes[i] > fairSwap1Y) {
180 k = overlappingStrikes[i];
185 k = overlappingStrikes.back();
188 for (Size i = 0; i < cfMaturities_.size(); i++) {
189 Time t = cfMaturityTimes_[i];
191 Size numYears = (Size)(t + 0.5);
194 fairSwap = fairSwap1Y;
196 Real sumDiscount = 0.0;
197 for (Size j = 0; j < numYears; ++j)
198 sumDiscount += nominalTS_->discount(j + 1.0);
200 Real capPrice = capPriceTemp(t, k);
201 Real floorPrice = floorPriceTemp(t, k);
203 fairSwap = ((capPrice - floorPrice) / 10000 + k * sumDiscount) / sumDiscount;
206 atmYoYSwapDateRates_.first.push_back(referenceDate() + cfMaturities_[i]);
207 atmYoYSwapTimeRates_.first.push_back(t);
208 atmYoYSwapTimeRates_.second.push_back(fairSwap);
209 atmYoYSwapDateRates_.second.push_back(fairSwap);
212 atmYoYSwapRateCurve_ = interpolator1d_.interpolate(
213 atmYoYSwapTimeRates_.first.begin(), atmYoYSwapTimeRates_.first.end(), atmYoYSwapTimeRates_.second.begin());
215 calculateYoYTermStructure();
218 yoy_ = yoyIndex_->yoyInflationTermStructure().currentLink();
221 cPriceB_ = Matrix(cfStrikes_.size(), cfMaturities_.size(), Null<Real>());
222 fPriceB_ = Matrix(cfStrikes_.size(), cfMaturities_.size(), Null<Real>());
224 for (Size j = 0; j < cfMaturities_.size(); ++j) {
225 Period mat = cfMaturities_[j];
227 Time t = cfMaturityTimes_[j];
228 Size numYears = (Size)(t + 0.5);
229 Real sumDiscount = 0.0;
230 for (Size k = 0; k < numYears; ++k)
231 sumDiscount += nominalTS_->discount(k + 1.0);
233 Real S = yoy_->yoyRate(yoyOptionDateFromTenor(mat));
234 for (Size i = 0; i < cfStrikes_.size(); ++i) {
235 Real K = cfStrikes_[i];
241 bool isFloorStrike = indF < fStrikes_.size();
242 bool isCapStrike = indC < cStrikes_.size();
244 fPriceB_[i][j] = fPrice_[indF][j];
246 cPriceB_[i][j] = fPrice_[indF][j] + (S - K) * 10000 * sumDiscount;
250 cPriceB_[i][j] = cPrice_[indC][j];
251 if (!isFloorStrike) {
252 fPriceB_[i][j] = cPrice_[indC][j] - (S - K) * 10000 * sumDiscount;
259 for (Size i = 0; i < cPriceB_.rows(); ++i) {
260 for (Size j = 0; j < cPriceB_.columns(); ++j) {
261 QL_REQUIRE(cPriceB_[i][j] != Null<Real>(),
"InterpolatedCPICapFloorTermPriceSurface: did not "
262 "fill call price matrix at ("
263 << i <<
"," << j <<
"), this is unexpected");
264 QL_REQUIRE(fPriceB_[i][j] != Null<Real>(),
"InterpolatedCPICapFloorTermPriceSurface: did not "
265 "fill floor price matrix at ("
266 << i <<
"," << j <<
"), this is unexpected");
270 capPrice_ = interpolator2d_.interpolate(cfMaturityTimes_.begin(), cfMaturityTimes_.end(), cfStrikes_.begin(),
271 cfStrikes_.end(), cPriceB_);
272 capPrice_.enableExtrapolation();
274 floorPrice_ = interpolator2d_.interpolate(cfMaturityTimes_.begin(), cfMaturityTimes_.end(), cfStrikes_.begin(),
275 cfStrikes_.end(), fPriceB_);
276 floorPrice_.enableExtrapolation();
279template <
class I2D,
class I1D>
281 Rate atm = atmYoYSwapRate(d);
282 return k > atm ? capPrice(d, k) : floorPrice(d, k);
285template <
class I2D,
class I1D>
287 Time t = timeFromReference(d);
288 return std::max(0.0, capPrice_(t, k));
291template <
class I2D,
class I1D>
293 Time t = timeFromReference(d);
294 return std::max(0.0, floorPrice_(t, k));
297template <
class I2D,
class I1D>
302 Size nYears = (Size)(0.5 + timeFromReference(referenceDate() + cfMaturities_.back()));
304 Handle<YieldTermStructure> nominalH(nominalTS_);
305 std::vector<QuantLib::ext::shared_ptr<BootstrapHelper<YoYInflationTermStructure> > > YYhelpers;
306 for (Size i = 1; i <= nYears; i++) {
307 Date maturity = nominalTS_->referenceDate() + Period(i, Years);
308 Handle<Quote> quote(QuantLib::ext::shared_ptr<Quote>(
new SimpleQuote(atmYoYSwapRate(maturity))));
309 QuantLib::ext::shared_ptr<BootstrapHelper<YoYInflationTermStructure> > anInstrument(
new YearOnYearInflationSwapHelper(
310 quote, observationLag(), maturity, calendar(), bdc_, dayCounter(), yoyIndex(), nominalH));
311 YYhelpers.push_back(anInstrument);
317 Rate baseYoYRate = atmYoYSwapRate(referenceDate());
319 QuantLib::ext::shared_ptr<PiecewiseYoYInflationCurve<I1D>> pYITS(
new PiecewiseYoYInflationCurve<I1D>(
320 nominalTS_->referenceDate(), calendar(), dayCounter(), observationLag(), yoyIndex()->frequency(),
321 yoyIndex()->interpolated(), baseYoYRate, YYhelpers));
322 pYITS->recalculate();
326 const Real eps = 1e-5;
327 for (Size i = 0; i < YYhelpers.size(); i++) {
328 Rate original = atmYoYSwapRate(yoyOptionDateFromTenor(Period(i + 1, Years)));
329 QL_REQUIRE(fabs(YYhelpers[i]->impliedQuote() - original) < eps,
330 "could not reprice helper " << i <<
", data " << original <<
", implied quote "
331 << YYhelpers[i]->impliedQuote());
Interpolated YoY Inflation Cap floor term price surface.
Interpolator2D interpolator2d_
virtual std::pair< std::vector< Time >, std::vector< Rate > > atmYoYSwapTimeRates() const override
virtual Real floorPrice(const Date &d, const Rate k) const override
virtual QuantLib::ext::shared_ptr< YoYInflationTermStructure > YoYTS() const override
virtual Rate atmYoYRate(const Date &d, const Period &obsLag=Period(-1, Days), bool extrapolate=true) const override
virtual Real capPrice(const Date &d, const Rate k) const override
void performCalculations() const
Interpolation2D capPrice_
virtual Natural fixingDays() const override
virtual std::pair< std::vector< Date >, std::vector< Rate > > atmYoYSwapDateRates() const override
Interpolation2D floorPrice_
virtual Rate price(const Date &d, const Rate k) const override
InterpolatedYoYCapFloorTermPriceSurface(Natural fixingDays, const Period &yyLag, const QuantLib::ext::shared_ptr< YoYInflationIndex > &yii, Rate baseRate, const Handle< YieldTermStructure > &nominal, const DayCounter &dc, const Calendar &cal, const BusinessDayConvention &bdc, const std::vector< Rate > &cStrikes, const std::vector< Rate > &fStrikes, const std::vector< Period > &cfMaturities, const Matrix &cPrice, const Matrix &fPrice, const Interpolator2D &interpolator2d=Interpolator2D(), const Interpolator1D &interpolator1d=Interpolator1D())
virtual Date baseDate() const override
void calculateYoYTermStructure() const
virtual Rate atmYoYSwapRate(const Date &d, bool extrapolate=true) const override
Interpolation atmYoYSwapRateCurve_
virtual Date maxDate() const override
inflation term structure interface
void setMaturities(std::vector< Period > &overrideMaturities)
Interpolator1D interpolator1d_
wrapper classes for inflation yoy and interpolation
CloseEnoughComparator(const Real v)
bool operator()(const Real w) const