QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
optionletstripper1.cpp
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) 2007, 2008 Ferdinando Ametrano
5 Copyright (C) 2007 François du Vignaud
6 Copyright (C) 2007 Katiuscia Manzoni
7 Copyright (C) 2007 Giorgio Facchinetti
8 Copyright (C) 2015 Michael von den Driesch
9 Copyright (C) 2015 Peter Caspers
10
11 This file is part of QuantLib, a free-software/open-source library
12 for financial quantitative analysts and developers - http://quantlib.org/
13
14 QuantLib is free software: you can redistribute it and/or modify it
15 under the terms of the QuantLib license. You should have received a
16 copy of the license along with this program; if not, please email
17 <quantlib-dev@lists.sf.net>. The license is also available online at
18 <http://quantlib.org/license.shtml>.
19
20 This program is distributed in the hope that it will be useful, but WITHOUT
21 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
22 FOR A PARTICULAR PURPOSE. See the license for more details.
23*/
24
28#include <ql/pricingengine.hpp>
34
35namespace QuantLib {
36
38 const ext::shared_ptr<CapFloorTermVolSurface>& termVolSurface,
39 const ext::shared_ptr<IborIndex>& index,
40 Rate switchStrike,
41 Real accuracy,
42 Natural maxIter,
43 const Handle<YieldTermStructure>& discount,
44 const VolatilityType type,
45 const Real displacement,
46 bool dontThrow)
47 : OptionletStripper(termVolSurface, index, discount, type, displacement),
48 floatingSwitchStrike_(switchStrike == Null<Rate>()), switchStrike_(switchStrike),
49 accuracy_(accuracy), maxIter_(maxIter), dontThrow_(dontThrow) {
50
55
56 Real firstGuess = 0.14; // guess is only used for shifted lognormal vols
58 }
59
61
62 // update dates
63 const Date& referenceDate = termVolSurface_->referenceDate();
64 const DayCounter& dc = termVolSurface_->dayCounter();
65 ext::shared_ptr<BlackCapFloorEngine> dummy(new
66 BlackCapFloorEngine(// discounting does not matter here
67 iborIndex_->forwardingTermStructure(),
68 0.20, dc));
69 for (Size i=0; i<nOptionletTenors_; ++i) {
73 0.04, // dummy strike
74 0*Days)
75 .withPricingEngine(dummy);
76 ext::shared_ptr<FloatingRateCoupon> lFRC =
78 optionletDates_[i] = lFRC->fixingDate();
79 optionletPaymentDates_[i] = lFRC->date();
80 optionletAccrualPeriods_[i] = lFRC->accrualPeriod();
81 optionletTimes_[i] = dc.yearFraction(referenceDate,
83 atmOptionletRate_[i] = lFRC->indexFixing();
84 }
85
87 Rate averageAtmOptionletRate = 0.0;
88 for (Size i=0; i<nOptionletTenors_; ++i) {
89 averageAtmOptionletRate += atmOptionletRate_[i];
90 }
91 switchStrike_ = averageAtmOptionletRate / nOptionletTenors_;
92 }
93
94 const Handle<YieldTermStructure>& discountCurve =
95 discount_.empty() ?
96 iborIndex_->forwardingTermStructure() :
98
99 const std::vector<Rate>& strikes = termVolSurface_->strikes();
100
101 ext::shared_ptr<PricingEngine> capFloorEngine;
102 ext::shared_ptr<SimpleQuote> volQuote(new SimpleQuote);
103
105 capFloorEngine = ext::make_shared<BlackCapFloorEngine>(
106
107 discountCurve, Handle<Quote>(volQuote),
108 dc, displacement_);
109 } else if (volatilityType_ == Normal) {
110 capFloorEngine = ext::make_shared<BachelierCapFloorEngine>(
111
112 discountCurve, Handle<Quote>(volQuote),
113 dc);
114 } else {
115 QL_FAIL("unknown volatility type: " << volatilityType_);
116 }
117
118 for (Size j=0; j<nStrikes_; ++j) {
119 // using out-of-the-money options
120 CapFloor::Type capFloorType =
122 Option::Type optionletType =
123 strikes[j] < switchStrike_ ? Option::Put : Option::Call;
124
125 Real previousCapFloorPrice = 0.0;
126 for (Size i=0; i<nOptionletTenors_; ++i) {
127
128 capFloorVols_[i][j] = termVolSurface_->volatility(
129 capFloorLengths_[i], strikes[j], true);
130 volQuote->setValue(capFloorVols_[i][j]);
131 ext::shared_ptr<CapFloor> capFloor =
132 MakeCapFloor(capFloorType, capFloorLengths_[i],
133 iborIndex_, strikes[j], -0 * Days)
134 .withPricingEngine(capFloorEngine);
135 capFloorPrices_[i][j] = capFloor->NPV();
136 optionletPrices_[i][j] = capFloorPrices_[i][j] -
137 previousCapFloorPrice;
138 previousCapFloorPrice = capFloorPrices_[i][j];
140 discountCurve->discount(optionletPaymentDates_[i]);
141 DiscountFactor optionletAnnuity=optionletAccrualPeriods_[i]*d;
142 try {
145 optionletType, strikes[j], atmOptionletRate_[i],
146 optionletPrices_[i][j], optionletAnnuity, displacement_,
148 } else if (volatilityType_ == Normal) {
149 optionletStDevs_[i][j] =
150 std::sqrt(optionletTimes_[i]) *
152 optionletType, strikes[j], atmOptionletRate_[i],
154 optionletAnnuity);
155 } else {
156 QL_FAIL("Unknown volatility type: " << volatilityType_);
157 }
158 }
159 catch (std::exception &e) {
160 if(dontThrow_)
161 optionletStDevs_[i][j]=0.0;
162 else
163 QL_FAIL("could not bootstrap optionlet:"
164 "\n type: " << optionletType <<
165 "\n strike: " << io::rate(strikes[j]) <<
166 "\n atm: " << io::rate(atmOptionletRate_[i]) <<
167 "\n price: " << optionletPrices_[i][j] <<
168 "\n annuity: " << optionletAnnuity <<
169 "\n expiry: " << optionletDates_[i] <<
170 "\n error: " << e.what());
171 }
173 std::sqrt(optionletTimes_[i]);
174 }
175 }
176
177 }
178
180 calculate();
181 return capletVols_;
182 }
183
185 calculate();
186 return capFloorPrices_;
187 }
188
190 calculate();
191 return capFloorVols_;
192 }
193
195 calculate();
196 return optionletPrices_;
197 }
198
201 calculate();
202 return switchStrike_;
203 }
204
205}
Bachelier-Black-formula cap/floor engine.
Black-formula cap/floor engine.
Black formula.
Black-formula cap/floor engine.
Base class for cap-like instruments.
Definition: capfloor.hpp:55
ext::shared_ptr< FloatingRateCoupon > lastFloatingRateCoupon() const
Definition: capfloor.cpp:188
Concrete date class.
Definition: date.hpp:125
day counter class
Definition: daycounter.hpp:44
Time yearFraction(const Date &, const Date &, const Date &refPeriodStart=Date(), const Date &refPeriodEnd=Date()) const
Returns the period between two dates as a fraction of year.
Definition: daycounter.hpp:128
Shared handle to an observable.
Definition: handle.hpp:41
virtual void calculate() const
Definition: lazyobject.hpp:253
MakeCapFloor & withPricingEngine(const ext::shared_ptr< PricingEngine > &engine)
Matrix used in linear algebra.
Definition: matrix.hpp:41
template class providing a null value for a given type.
Definition: null.hpp:76
const Matrix & capletVols() const
void performCalculations() const override
const Matrix & optionletPrices() const
OptionletStripper1(const ext::shared_ptr< CapFloorTermVolSurface > &, const ext::shared_ptr< IborIndex > &index, Rate switchStrikes=Null< Rate >(), Real accuracy=1.0e-6, Natural maxIter=100, const Handle< YieldTermStructure > &discount={}, VolatilityType type=ShiftedLognormal, Real displacement=0.0, bool dontThrow=false)
const Matrix & capFloorPrices() const
const Matrix & capFloorVolatilities() const
std::vector< Rate > atmOptionletRate_
std::vector< std::vector< Volatility > > optionletVolatilities_
std::vector< Period > capFloorLengths_
Handle< YieldTermStructure > discount_
ext::shared_ptr< IborIndex > iborIndex_
std::vector< Date > optionletPaymentDates_
std::vector< Time > optionletAccrualPeriods_
std::vector< Time > optionletTimes_
std::vector< Date > optionletDates_
const VolatilityType volatilityType_
ext::shared_ptr< CapFloorTermVolSurface > termVolSurface_
market element returning a stored value
Definition: simplequote.hpp:33
output manipulators
#define QL_FAIL(message)
throw an error (possibly with file and line information)
Definition: errors.hpp:92
Date d
detail::percent_holder rate(Rate)
output rates and spreads as percentages
QL_REAL Real
real number
Definition: types.hpp:50
Real DiscountFactor
discount factor between dates
Definition: types.hpp:66
unsigned QL_INTEGER Natural
positive integer
Definition: types.hpp:43
Real Rate
interest rates
Definition: types.hpp:70
std::size_t Size
size of a container
Definition: types.hpp:58
base class for Inter-Bank-Offered-Rate indexes
Helper class to instantiate standard market cap/floor.
Definition: any.hpp:35
Real blackFormulaImpliedStdDev(Option::Type optionType, Real strike, Real forward, Real blackPrice, Real discount, Real displacement, Real guess, Real accuracy, Natural maxIterations)
Real bachelierBlackFormulaImpliedVol(Option::Type optionType, Real strike, Real forward, Real tte, Real bachelierPrice, Real discount)
optionlet (caplet/floorlet) volatility stripper
Base class for pricing engines.
simple quote class