QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
interpolatedyoyoptionletstripper.hpp
Go to the documentation of this file.
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2009 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
20/*! \file interpolatedyoyoptionletstripper.hpp
21 \brief interpolated yoy inflation-cap stripping
22*/
23
24#ifndef quantlib_interpolated_yoy_optionlet_stripper_hpp
25#define quantlib_interpolated_yoy_optionlet_stripper_hpp
26
33#include <utility>
34
35
36namespace QuantLib {
37
38 /*! The interpolated version interpolates along each K (as opposed
39 to fitting a model, say).
40
41 \bug Tests currently fail.
42 */
43 template <class Interpolator1D>
45 public:
46
47 //! YoYOptionletStripper interface
48 //@{
49 void initialize(const ext::shared_ptr<YoYCapFloorTermPriceSurface>&,
50 const ext::shared_ptr<YoYInflationCapFloorEngine>&,
51 Real slope) const override;
52 Rate minStrike() const override { return YoYCapFloorTermPriceSurface_->strikes().front(); }
53 Rate maxStrike() const override { return YoYCapFloorTermPriceSurface_->strikes().back(); }
54 std::vector<Rate> strikes() const override {
55 return YoYCapFloorTermPriceSurface_->strikes();
56 }
57 std::pair<std::vector<Rate>, std::vector<Volatility> > slice(const Date& d) const override;
58 //@}
59
60 protected:
61 mutable std::vector<ext::shared_ptr<YoYOptionletVolatilitySurface> >
63
64 // used to set up the first point on each vol curve
65 // using assumptions on unobserved vols at start
67 public:
69 Real slope,
70 Rate K,
71 Period& lag,
72 Natural fixingDays,
73 const ext::shared_ptr<YoYInflationIndex>& anIndex,
74 const ext::shared_ptr<YoYCapFloorTermPriceSurface>&,
75 ext::shared_ptr<YoYInflationCapFloorEngine> p,
76 Real priceToMatch);
77 Real operator()(Volatility guess) const;
78 protected:
83 std::vector<Time> tvec_;
84 std::vector<Date> dvec_;
85 mutable std::vector<Volatility> vvec_;
86 ext::shared_ptr<YoYInflationCapFloor> capfloor_;
88 ext::shared_ptr<YoYCapFloorTermPriceSurface> surf_;
90 ext::shared_ptr<YoYInflationCapFloorEngine> p_;
91 };
92 };
93
94
95 // template definitions
96
97 template <class Interpolator1D>
100 Real slope,
101 Rate K,
102 Period& lag,
103 Natural fixingDays,
104 const ext::shared_ptr<YoYInflationIndex>& anIndex,
105 const ext::shared_ptr<YoYCapFloorTermPriceSurface>& surf,
106 ext::shared_ptr<YoYInflationCapFloorEngine> p,
107 Real priceToMatch)
108 : slope_(slope), K_(K), frequency_(anIndex->frequency()),
109 indexIsInterpolated_(anIndex->interpolated()), tvec_(std::vector<Time>(2)),
110 dvec_(std::vector<Date>(2)), vvec_(std::vector<Volatility>(2)), priceToMatch_(priceToMatch),
111 surf_(surf), p_(std::move(p)) {
112
113 lag_ = surf_->observationLag();
114 capfloor_ =
115 MakeYoYInflationCapFloor(type, anIndex,
116 (Size)std::floor(0.5+surf->timeFromReference(surf->minMaturity())),
117 surf->calendar(), lag)
118 .withNominal(10000.0)
119 .withStrike(K);
120
121 // shortest time available from price surface
122 dvec_[0] = surf_->baseDate();
123 dvec_[1] = surf_->minMaturity() +
124 Period(7, Days);
125 tvec_[0] = surf_->dayCounter().yearFraction(surf_->referenceDate(),
126 dvec_[0] );
127 tvec_[1] = surf_->dayCounter().yearFraction(surf_->referenceDate(),
128 dvec_[1]);
129
130 Size n = (Size)std::floor(0.5 + surf->timeFromReference(surf_->minMaturity()));
131 QL_REQUIRE( n > 0,
132 "first maturity in price surface not > 0: "
133 << n);
134
135 capfloor_->setPricingEngine(p_);
136 // pricer already setup just need to do the volatility surface each time
137 }
138
139
140 template <class Interpolator1D>
143
144 vvec_[1] = guess;
145 vvec_[0] = guess - slope_ * (tvec_[1] - tvec_[0]) * guess;
146 // could have Interpolator1D instead of Linear
147 ext::shared_ptr<InterpolatedYoYOptionletVolatilityCurve<Linear> >
148 vCurve(
153 dvec_, vvec_,
154 -1.0, 3.0) ); // strike limits
156 p_->setVolatility(hCurve);
157 // hopefully this gets to the pricer ... then
158 return priceToMatch_ - capfloor_->NPV();
159 }
160
161
162 template <class Interpolator1D>
164 initialize(const ext::shared_ptr<YoYCapFloorTermPriceSurface> &s,
165 const ext::shared_ptr<YoYInflationCapFloorEngine> &p,
166 const Real slope) const {
168 p_ = p;
169 lag_ = YoYCapFloorTermPriceSurface_->observationLag();
171 indexIsInterpolated_ = YoYCapFloorTermPriceSurface_->indexIsInterpolated();
172 Natural fixingDays_ = YoYCapFloorTermPriceSurface_->fixingDays();
173 Natural settlementDays = 0; // always
174 Calendar cal = YoYCapFloorTermPriceSurface_->calendar();
176 YoYCapFloorTermPriceSurface_->businessDayConvention();
177 DayCounter dc = YoYCapFloorTermPriceSurface_->dayCounter();
178
179 // switch from caps to floors when out of floors
180 Rate maxFloor = YoYCapFloorTermPriceSurface_->floorStrikes().back();
182 Period TPmin = YoYCapFloorTermPriceSurface_->maturities().front();
183 // create a "fake index" based on Generic, this should work
184 // provided that the lag and frequency are correct
187 ext::shared_ptr<YoYInflationIndex> anIndex(
188 new YYGenericCPI(frequency_, false,
189 false, lag_,
190 Currency(), hYoY));
191
192 // strip each K separatly
193 for (Size i=0; i<YoYCapFloorTermPriceSurface_->strikes().size(); i++) {
194 Rate K = YoYCapFloorTermPriceSurface_->strikes()[i];
195 if (K > maxFloor) useType = YoYInflationCapFloor::Cap;
196
197 // solve for the initial point on the vol curve
198 Brent solver;
199 Real solverTolerance_ = 1e-7;
200 // these are VOLATILITY guesses (always +)
201 Real lo = 0.00001, hi = 0.08;
202 Real guess = (hi+lo)/2.0;
203 Real found;
204 Real priceToMatch =
205 (useType == YoYInflationCapFloor::Cap ?
206 YoYCapFloorTermPriceSurface_->capPrice(TPmin, K) :
207 YoYCapFloorTermPriceSurface_->floorPrice(TPmin, K));
208
209 try{
210 found = solver.solve(
211 ObjectiveFunction(useType, slope, K, lag_, fixingDays_,
213 p_, priceToMatch),
214 solverTolerance_, guess, lo, hi );
215 } catch( std::exception &e) {
216 QL_FAIL("failed to find solution here because: " << e.what());
217 }
218
219 // ***create helpers***
220 Real notional = 10000; // work in bps
221 std::vector<ext::shared_ptr<BootstrapHelper<YoYOptionletVolatilitySurface> > > helperInstruments;
222 std::vector<ext::shared_ptr<YoYOptionletHelper> > helpers;
223 for (Size j = 0; j < YoYCapFloorTermPriceSurface_->maturities().size(); j++){
224 Period Tp = YoYCapFloorTermPriceSurface_->maturities()[j];
225
226 Real nextPrice =
227 (useType == YoYInflationCapFloor::Cap ?
228 YoYCapFloorTermPriceSurface_->capPrice(Tp, K) :
229 YoYCapFloorTermPriceSurface_->floorPrice(Tp, K));
230
231 Handle<Quote> quote1(ext::shared_ptr<Quote>(
232 new SimpleQuote( nextPrice )));
233 // helper should be an integer number of periods away,
234 // this is enforced by rounding
235 Size nT = (Size)floor(s->timeFromReference(s->yoyOptionDateFromTenor(Tp))+0.5);
236 helpers.push_back(ext::shared_ptr<YoYOptionletHelper>(
237 new YoYOptionletHelper(quote1, notional, useType,
238 lag_,
239 dc, cal,
240 fixingDays_,
241 anIndex, K, nT, p_)));
242
243 ext::shared_ptr<ConstantYoYOptionletVolatility> yoyVolBLACK(
244 new ConstantYoYOptionletVolatility(found, settlementDays,
245 cal, bdc, dc,
247 false,
248 // -100% to +300%
249 -1.0,3.0));
250
251 helpers[j]->setTermStructure(
252 // gets underlying pointer & removes const
254 yoyVolBLACK.get()));
255 helperInstruments.push_back(helpers[j]);
256 }
257 // ***bootstrap***
258 // this is the artificial vol at zero so that first section works
259 Real Tmin = s->timeFromReference(s->yoyOptionDateFromTenor(TPmin));
260 Volatility baseYoYVolatility = found - slope * Tmin * found;
261 Rate eps = std::max(K, 0.02) / 1000.0;
262 Rate minStrike = K-eps;
263 Rate maxStrike = K+eps;
264 ext::shared_ptr<
267 settlementDays, cal, bdc, dc, lag_,
270 baseYoYVolatility,
271 helperInstruments) );
272 testPW->recalculate();
273 volCurves_.push_back(testPW);
274 }
275 }
276
277
278 template <class Interpolator1D>
279 std::pair<std::vector<Rate>, std::vector<Volatility> >
281 const Date &d) const {
282
283 const std::vector<Real>& Ks = strikes();
284
285 const Size nK = Ks.size();
286
287 std::pair<std::vector<Rate>, std::vector<Volatility> > result =
288 std::make_pair(std::vector<Rate>(nK), std::vector<Volatility>(nK));
289
290 for (Size i = 0; i < nK; i++) {
291 Rate K = Ks[i];
292 Volatility v = volCurves_[i]->volatility(d, K);
293 result.first[i] = K;
294 result.second[i] = v;
295 }
296
297 return result;
298 }
299
300}
301
302#endif
303
Brent 1-D solver.
Actual/365 (Fixed) day count convention.
Brent 1-D solver
Definition: brent.hpp:37
calendar class
Definition: calendar.hpp:61
Currency specification
Definition: currency.hpp:36
Concrete date class.
Definition: date.hpp:125
day counter class
Definition: daycounter.hpp:44
Shared handle to an observable.
Definition: handle.hpp:41
ObjectiveFunction(YoYInflationCapFloor::Type type, Real slope, Rate K, Period &lag, Natural fixingDays, const ext::shared_ptr< YoYInflationIndex > &anIndex, const ext::shared_ptr< YoYCapFloorTermPriceSurface > &, ext::shared_ptr< YoYInflationCapFloorEngine > p, Real priceToMatch)
void initialize(const ext::shared_ptr< YoYCapFloorTermPriceSurface > &, const ext::shared_ptr< YoYInflationCapFloorEngine > &, Real slope) const override
YoYOptionletStripper interface.
std::vector< ext::shared_ptr< YoYOptionletVolatilitySurface > > volCurves_
std::pair< std::vector< Rate >, std::vector< Volatility > > slice(const Date &d) const override
MakeYoYInflationCapFloor & withStrike(Rate strike)
MakeYoYInflationCapFloor & withNominal(Real n)
Piecewise year-on-year inflation volatility term structure.
Relinkable handle to an observable.
Definition: handle.hpp:117
market element returning a stored value
Definition: simplequote.hpp:33
Real solve(const F &f, Real accuracy, Real guess, Real step) const
Definition: solver1d.hpp:84
TARGET calendar
Definition: target.hpp:50
Quoted year-on-year Generic CPI (i.e. not a ratio)
Year-on-year inflation-volatility bootstrap helper.
Interface for inflation cap stripping, i.e. from price surfaces.
ext::shared_ptr< YoYCapFloorTermPriceSurface > YoYCapFloorTermPriceSurface_
ext::shared_ptr< YoYInflationCapFloorEngine > p_
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
#define QL_FAIL(message)
throw an error (possibly with file and line information)
Definition: errors.hpp:92
Date d
Generic inflation indexes.
Frequency
Frequency of events.
Definition: frequency.hpp:37
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
unsigned QL_INTEGER Natural
positive integer
Definition: types.hpp:43
Real Volatility
volatility
Definition: types.hpp:78
Real Rate
interest rates
Definition: types.hpp:70
std::size_t Size
size of a container
Definition: types.hpp:58
const HestonParams p_
Helper class to instantiate standard yoy inflation cap/floor.
Definition: any.hpp:35
STL namespace.
ext::shared_ptr< BlackVolTermStructure > v
piecewise yoy inflation volatility term structure
helpers for YoY inflation-volatility bootstrap
yoy inflation-cap stripping