QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
cpicapfloortermpricesurface.hpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2010, 2011 Chris Kenyon
5
6 This file is part of QuantLib, a free-software/open-source library
7 for financial quantitative analysts and developers - http://quantlib.org/
8
9 QuantLib is free software: you can redistribute it and/or modify it
10 under the terms of the QuantLib license. You should have received a
11 copy of the license along with this program; if not, please email
12 <quantlib-dev@lists.sf.net>. The license is also available online at
13 <http://quantlib.org/license.shtml>.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the license for more details.
18*/
19
24#ifndef quantlib_cpi_capfloor_term_price_surface_hpp
25#define quantlib_cpi_capfloor_term_price_surface_hpp
26
27#include <ql/termstructures/inflationtermstructure.hpp>
28#include <ql/math/interpolation.hpp>
29#include <ql/math/interpolations/interpolation2d.hpp>
30#include <ql/experimental/inflation/polynomial2Dspline.hpp>
31#include <ql/indexes/inflationindex.hpp>
32
33
34namespace QuantLib {
35
37
55 public:
58 Real baseRate, // avoids an uncontrolled crash if index has no TS
60 const Calendar& cal, // calendar in index may not be useful
61 const BusinessDayConvention& bdc,
62 const DayCounter& dc,
63 const ext::shared_ptr<ZeroInflationIndex>& zii,
64 CPI::InterpolationType interpolationType,
66 const std::vector<Rate>& cStrikes,
67 const std::vector<Rate>& fStrikes,
68 const std::vector<Period>& cfMaturities,
69 const Matrix& cPrice,
70 const Matrix& fPrice);
71
73
74 Period observationLag() const override;
75 Date baseDate() const override;
77
79
83 virtual Real nominal() const;
85 ext::shared_ptr<ZeroInflationIndex> zeroInflationIndex() const { return zii_; }
87
88 Rate atmRate(Date maturity) const;
89
93
94 virtual Real price(const Period &d, Rate k) const;
95 virtual Real capPrice(const Period &d, Rate k) const;
96 virtual Real floorPrice(const Period &d, Rate k) const;
97 virtual Real price(const Date &d, Rate k) const = 0;
98 virtual Real capPrice(const Date &d, Rate k) const = 0;
99 virtual Real floorPrice(const Date &d, Rate k) const = 0;
101
102 virtual std::vector<Rate> strikes() const {return cfStrikes_;}
103 virtual std::vector<Rate> capStrikes() const {return cStrikes_;}
104 virtual std::vector<Rate> floorStrikes() const {return fStrikes_;}
105 virtual std::vector<Period> maturities() const {return cfMaturities_;}
106
107 virtual const Matrix &capPrices() const { return cPrice_; }
108 virtual const Matrix &floorPrices() const { return fPrice_; }
109
110 virtual Rate minStrike() const {return cfStrikes_.front();};
111 virtual Rate maxStrike() const {return cfStrikes_.back();};
112 virtual Date minDate() const {return referenceDate()+cfMaturities_.front();}// \TODO deal with index interpolation
113 Date maxDate() const override { return referenceDate() + cfMaturities_.back(); }
115
116 virtual Date cpiOptionDateFromTenor(const Period& p) const;
117
118 protected:
119 virtual bool checkStrike(Rate K) {
120 return ( minStrike() <= K && K <= maxStrike() );
121 }
122 virtual bool checkMaturity(const Date& d) {
123 return ( minDate() <= d && d <= maxDate() );
124 }
125
126 ext::shared_ptr<ZeroInflationIndex> zii_;
129 // data
130 std::vector<Rate> cStrikes_;
131 std::vector<Rate> fStrikes_;
132 std::vector<Period> cfMaturities_;
133 mutable std::vector<Real> cfMaturityTimes_;
136 // constructed
137 mutable std::vector<Rate> cfStrikes_;
138 private:
141 };
142
143
144
145 template<class Interpolator2D>
148 public:
150 Rate startRate,
151 const Period &observationLag,
152 const Calendar &cal,
153 const BusinessDayConvention &bdc,
154 const DayCounter &dc,
155 const ext::shared_ptr<ZeroInflationIndex>& zii,
156 CPI::InterpolationType interpolationType,
158 const std::vector<Rate> &cStrikes,
159 const std::vector<Rate> &fStrikes,
160 const std::vector<Period> &cfMaturities,
161 const Matrix &cPrice,
162 const Matrix &fPrice,
163 const Interpolator2D &interpolator2d = Interpolator2D());
164
166
167 void performCalculations() const;
169
171
176
178
179 Real price(const Date& d, Rate k) const override;
180 Real capPrice(const Date& d, Rate k) const override;
181 Real floorPrice(const Date& d, Rate k) const override;
183
184 protected:
185
186 // data for surfaces and curve
190 mutable Interpolator2D interpolator2d_;
191 };
192
193
194 // template definitions, for some reason DOXYGEN doesn't like the first one
195
196 #ifndef __DOXYGEN__
197
198 template<class Interpolator2D>
201 Rate startRate,
202 const Period &observationLag,
203 const Calendar &cal,
204 const BusinessDayConvention &bdc,
205 const DayCounter &dc,
206 const ext::shared_ptr<ZeroInflationIndex>& zii,
207 CPI::InterpolationType interpolationType,
209 const std::vector<Rate> &cStrikes,
210 const std::vector<Rate> &fStrikes,
211 const std::vector<Period> &cfMaturities,
212 const Matrix &cPrice,
213 const Matrix &fPrice,
214 const Interpolator2D &interpolator2d)
215 : CPICapFloorTermPriceSurface(nominal, startRate, observationLag, cal, bdc, dc,
216 zii, interpolationType, yts, cStrikes, fStrikes,
217 cfMaturities, cPrice, fPrice),
218 interpolator2d_(interpolator2d) {
220 }
221
222 #endif
223
228 template<class I2D>
230 performCalculations() const {
231
232 cPriceB_ =
233 Matrix(cfStrikes_.size(), cfMaturities_.size(), Null<Real>());
234 fPriceB_ =
235 Matrix(cfStrikes_.size(), cfMaturities_.size(), Null<Real>());
236
237 Handle<YieldTermStructure> yts = nominalTS_;
238 QL_REQUIRE(!yts.empty(), "Yts is empty!!!");
239
240 for (Size j = 0; j < cfMaturities_.size(); ++j) {
241 Period mat = cfMaturities_[j];
242 Real df = yts->discount(cpiOptionDateFromTenor(mat));
243 Real atm_quote = atmRate(cpiOptionDateFromTenor(mat));
244 Real atm = std::pow(1.0 + atm_quote, mat.length());
245 Real S = atm * df;
246 for (Size i = 0; i < cfStrikes_.size(); ++i) {
247 Real K_quote = cfStrikes_[i];
248 Real K = std::pow(1.0 + K_quote, mat.length());
249 auto close = [k = cfStrikes_[i]](Real x){ return close_enough(x, k); };
250 Size indF = std::find_if(fStrikes_.begin(), fStrikes_.end(), close) - fStrikes_.begin();
251 Size indC = std::find_if(cStrikes_.begin(), cStrikes_.end(), close) - cStrikes_.begin();
252 bool isFloorStrike = indF < fStrikes_.size();
253 bool isCapStrike = indC < cStrikes_.size();
254 if (isFloorStrike) {
255 fPriceB_[i][j] = fPrice_[indF][j];
256 if (!isCapStrike) {
257 cPriceB_[i][j] = fPrice_[indF][j] + S - K * df;
258 }
259 }
260 if (isCapStrike) {
261 cPriceB_[i][j] = cPrice_[indC][j];
262 if (!isFloorStrike) {
263 fPriceB_[i][j] = cPrice_[indC][j] + K * df - S;
264 }
265 }
266 }
267 }
268
269 // check that all cells are filled
270 for (Size i = 0; i < cPriceB_.rows(); ++i) {
271 for (Size j = 0; j < cPriceB_.columns(); ++j) {
272 QL_REQUIRE(cPriceB_[i][j] != Null<Real>(),
273 "InterpolatedCPICapFloorTermPriceSurface: did not "
274 "fill call price matrix at ("
275 << i << "," << j << "), this is unexpected");
276 QL_REQUIRE(fPriceB_[i][j] != Null<Real>(),
277 "InterpolatedCPICapFloorTermPriceSurface: did not "
278 "fill floor price matrix at ("
279 << i << "," << j << "), this is unexpected");
280 }
281 }
282
283 cfMaturityTimes_.clear();
284 for (Size i=0; i<cfMaturities_.size();i++) {
285 cfMaturityTimes_.push_back(timeFromReference(cpiOptionDateFromTenor(cfMaturities_[i])));
286 }
287
288 capPrice_ = interpolator2d_.interpolate(cfMaturityTimes_.begin(),cfMaturityTimes_.end(),
289 cfStrikes_.begin(), cfStrikes_.end(),
290 cPriceB_
291 );
292 capPrice_.enableExtrapolation();
293
294 floorPrice_ = interpolator2d_.interpolate(cfMaturityTimes_.begin(),cfMaturityTimes_.end(),
295 cfStrikes_.begin(), cfStrikes_.end(),
296 fPriceB_
297 );
298 floorPrice_.enableExtrapolation();
299 }
300
302 template<class I2D>
304 price(const Date &d, Rate k) const {
305
306 Rate atm = atmRate(d);
307 return k > atm ? capPrice(d,k): floorPrice(d,k);
308 }
309
311 template<class I2D>
313 capPrice(const Date &d, Rate k) const {
314 Time t = timeFromReference(d);
315 return capPrice_(t,k);
316 }
317
319 template<class I2D>
321 floorPrice(const Date &d, Rate k) const {
322 Time t = timeFromReference(d);
323 return floorPrice_(t,k);
324 }
325
326 // inline definitions
327
329 return zeroInflationIndex()->zeroInflationTermStructure()->observationLag();
330 }
331
333 return zeroInflationIndex()->zeroInflationTermStructure()->baseDate();
334 }
335
337 return nominal_;
338 }
339
342 return bdc_;
343 }
344
345}
346
347#endif
Provides cpi cap/floor prices by interpolation and put/call parity (not cap/floor/swap* parity).
virtual Real price(const Date &d, Rate k) const =0
virtual std::vector< Rate > strikes() const
virtual Date cpiOptionDateFromTenor(const Period &p) const
virtual std::vector< Rate > floorStrikes() const
Date baseDate() const override
minimum (base) date
virtual Real capPrice(const Date &d, Rate k) const =0
virtual std::vector< Period > maturities() const
Date maxDate() const override
the latest date for which the curve can return values
virtual Real capPrice(const Period &d, Rate k) const
ext::shared_ptr< ZeroInflationIndex > zeroInflationIndex() const
ext::shared_ptr< ZeroInflationIndex > zii_
virtual Real floorPrice(const Date &d, Rate k) const =0
virtual Real price(const Period &d, Rate k) const
virtual BusinessDayConvention businessDayConvention() const
virtual Real floorPrice(const Period &d, Rate k) const
virtual std::vector< Rate > capStrikes() const
calendar class
Definition: calendar.hpp:61
Concrete date class.
Definition: date.hpp:125
day counter class
Definition: daycounter.hpp:44
Shared handle to an observable.
Definition: handle.hpp:41
bool empty() const
checks if the contained shared pointer points to anything
Definition: handle.hpp:166
Interface for inflation term structures.
InterpolatedCPICapFloorTermPriceSurface(Real nominal, Rate startRate, const Period &observationLag, const Calendar &cal, const BusinessDayConvention &bdc, const DayCounter &dc, const ext::shared_ptr< ZeroInflationIndex > &zii, CPI::InterpolationType interpolationType, const Handle< YieldTermStructure > &yts, 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())
Real capPrice(const Date &d, Rate k) const override
remember that the strike uses the quoting convention
Real floorPrice(const Date &d, Rate k) const override
remember that the strike uses the quoting convention
Real price(const Date &d, Rate k) const override
remember that the strikes use the quoting convention
base class for 2-D interpolations.
Matrix used in linear algebra.
Definition: matrix.hpp:41
template class providing a null value for a given type.
Definition: null.hpp:76
Integer length() const
Definition: period.hpp:50
virtual const Date & referenceDate() const
the date at which discount = 1.0 and/or variance = 0.0
BusinessDayConvention
Business Day conventions.
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
Real Rate
interest rates
Definition: types.hpp:70
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
bool close(const Quantity &m1, const Quantity &m2, Size n)
Definition: quantity.cpp:163
bool close_enough(const Quantity &m1, const Quantity &m2, Size n)
Definition: quantity.cpp:182
InterpolationType
when you observe an index, how do you interpolate between fixings?