QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
optionletstripper2.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2007 Giorgio Facchinetti
5 Copyright (C) 2010 Ferdinando Ametrano
6
7 This file is part of QuantLib, a free-software/open-source library
8 for financial quantitative analysts and developers - http://quantlib.org/
9
10 QuantLib is free software: you can redistribute it and/or modify it
11 under the terms of the QuantLib license. You should have received a
12 copy of the license along with this program; if not, please email
13 <quantlib-dev@lists.sf.net>. The license is also available online at
14 <http://quantlib.org/license.shtml>.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the license for more details.
19*/
20
21#include <ql/indexes/iborindex.hpp>
22#include <ql/instruments/makecapfloor.hpp>
23#include <ql/math/solvers1d/brent.hpp>
24#include <ql/pricingengines/capfloor/blackcapfloorengine.hpp>
25#include <ql/quotes/simplequote.hpp>
26#include <ql/termstructures/volatility/capfloor/capfloortermvolcurve.hpp>
27#include <ql/termstructures/volatility/optionlet/optionletstripper1.hpp>
28#include <ql/termstructures/volatility/optionlet/optionletstripper2.hpp>
29#include <ql/termstructures/volatility/optionlet/spreadedoptionletvol.hpp>
30#include <ql/termstructures/volatility/optionlet/strippedoptionletadapter.hpp>
31#include <utility>
32
33
34namespace QuantLib {
35
37 const ext::shared_ptr<OptionletStripper1>& optionletStripper1,
38 const Handle<CapFloorTermVolCurve>& atmCapFloorTermVolCurve)
39 : OptionletStripper(optionletStripper1->termVolSurface(),
40 optionletStripper1->iborIndex(),
42 optionletStripper1->volatilityType(),
43 optionletStripper1->displacement()),
44 stripper1_(optionletStripper1), atmCapFloorTermVolCurve_(atmCapFloorTermVolCurve),
45 dc_(stripper1_->termVolSurface()->dayCounter()),
46 nOptionExpiries_(atmCapFloorTermVolCurve->optionTenors().size()),
47 atmCapFloorStrikes_(nOptionExpiries_), atmCapFloorPrices_(nOptionExpiries_),
48 spreadsVolImplied_(nOptionExpiries_), caps_(nOptionExpiries_) {
51
52 QL_REQUIRE(dc_ == atmCapFloorTermVolCurve->dayCounter(),
53 "different day counters provided");
54 }
55
57
59 optionletDates_ = stripper1_->optionletFixingDates();
60 optionletPaymentDates_ = stripper1_->optionletPaymentDates();
61 optionletAccrualPeriods_ = stripper1_->optionletAccrualPeriods();
62 optionletTimes_ = stripper1_->optionletFixingTimes();
63 atmOptionletRate_ = stripper1_->atmOptionletRates();
64 for (Size i=0; i<optionletTimes_.size(); ++i) {
65 optionletStrikes_[i] = stripper1_->optionletStrikes(i);
66 optionletVolatilities_[i] = stripper1_->optionletVolatilities(i);
67 }
68
69 // atmCapFloorTermVolCurve data
70 const std::vector<Period>& optionExpiriesTenors =
71 atmCapFloorTermVolCurve_->optionTenors();
72 const std::vector<Time>& optionExpiriesTimes =
73 atmCapFloorTermVolCurve_->optionTimes();
74
75 for (Size j=0; j<nOptionExpiries_; ++j) {
76 Volatility atmOptionVol = atmCapFloorTermVolCurve_->volatility(
77 optionExpiriesTimes[j], 33.3333); // dummy strike
78 ext::shared_ptr<BlackCapFloorEngine> engine(new
79 BlackCapFloorEngine(iborIndex_->forwardingTermStructure(),
80 atmOptionVol, dc_));
82 optionExpiriesTenors[j],
84 Null<Rate>(),
85 0*Days).withPricingEngine(engine);
87 caps_[j]->atmRate(**iborIndex_->forwardingTermStructure());
88 atmCapFloorPrices_[j] = caps_[j]->NPV();
89 }
90
92
94 adapter.enableExtrapolation();
95
96 Volatility unadjustedVol, adjustedVol;
97 for (Size j=0; j<nOptionExpiries_; ++j) {
98 for (Size i=0; i<optionletVolatilities_.size(); ++i) {
99 if (i<=caps_[j]->floatingLeg().size()) {
100 unadjustedVol = adapter.volatility(optionletTimes_[i],
102 adjustedVol = unadjustedVol + spreadsVolImplied_[j];
103
104 // insert adjusted volatility
105 std::vector<Rate>::const_iterator previous =
106 std::lower_bound(optionletStrikes_[i].begin(),
107 optionletStrikes_[i].end(),
109 Size insertIndex = previous - optionletStrikes_[i].begin();
110
111 optionletStrikes_[i].insert(
112 optionletStrikes_[i].begin() + insertIndex,
114 optionletVolatilities_[i].insert(
115 optionletVolatilities_[i].begin() + insertIndex,
116 adjustedVol);
117 }
118 }
119 }
120 }
121
122 std::vector<Volatility> OptionletStripper2::spreadsVolImplied() const {
123
124 Brent solver;
125 std::vector<Volatility> result(nOptionExpiries_);
126 Volatility guess = 0.0001, minSpread = -0.1, maxSpread = 0.1;
127 for (Size j=0; j<nOptionExpiries_; ++j) {
130 Volatility root = solver.solve(f, accuracy_, guess,
131 minSpread, maxSpread);
132 result[j] = root;
133 }
134 return result;
135 }
136
137 std::vector<Volatility> OptionletStripper2::spreadsVol() const {
138 calculate();
139 return spreadsVolImplied_;
140 }
141
142 std::vector<Rate> OptionletStripper2::atmCapFloorStrikes() const{
143 calculate();
144 return atmCapFloorStrikes_;
145 }
146
147 std::vector<Real> OptionletStripper2::atmCapFloorPrices() const {
148 calculate();
149 return atmCapFloorPrices_;
150 }
151
152//==========================================================================//
153// OptionletStripper2::ObjectiveFunction //
154//==========================================================================//
155
157 const ext::shared_ptr<OptionletStripper1>& optionletStripper1,
158 ext::shared_ptr<CapFloor> cap,
159 Real targetValue)
160 : cap_(std::move(cap)), targetValue_(targetValue) {
161 ext::shared_ptr<OptionletVolatilityStructure> adapter(new
162 StrippedOptionletAdapter(optionletStripper1));
163 adapter->enableExtrapolation();
164
165 // set an implausible value, so that calculation is forced
166 // at first operator()(Volatility x) call
167 spreadQuote_ = ext::make_shared<SimpleQuote>(-1.0);
168
169 ext::shared_ptr<OptionletVolatilityStructure> spreadedAdapter(new
171 adapter), Handle<Quote>(spreadQuote_)));
172
173 ext::shared_ptr<BlackCapFloorEngine> engine(new
175 optionletStripper1->iborIndex()->forwardingTermStructure(),
176 Handle<OptionletVolatilityStructure>(spreadedAdapter)));
177
178 cap_->setPricingEngine(engine);
179 }
180
182 {
183 if (s!=spreadQuote_->value())
184 spreadQuote_->setValue(s);
185 return cap_->NPV()-targetValue_;
186 }
187}
Black-formula cap/floor engine.
Brent 1-D solver
Definition: brent.hpp:37
void enableExtrapolation(bool b=true)
enable extrapolation in subsequent calls
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)
template class providing a null value for a given type.
Definition: null.hpp:76
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Definition: observable.hpp:228
ObjectiveFunction(const ext::shared_ptr< OptionletStripper1 > &, ext::shared_ptr< CapFloor >, Real targetValue)
void performCalculations() const override
std::vector< Volatility > spreadsVolImplied_
const ext::shared_ptr< OptionletStripper1 > stripper1_
std::vector< Rate > atmCapFloorStrikes_
std::vector< Real > atmCapFloorPrices_
std::vector< ext::shared_ptr< CapFloor > > caps_
std::vector< Volatility > spreadsVolImplied() const
std::vector< Rate > atmCapFloorStrikes() const
std::vector< Volatility > spreadsVol() const
OptionletStripper2(const ext::shared_ptr< OptionletStripper1 > &optionletStripper1, const Handle< CapFloorTermVolCurve > &atmCapFloorTermVolCurve)
const Handle< CapFloorTermVolCurve > atmCapFloorTermVolCurve_
std::vector< Real > atmCapFloorPrices() const
std::vector< Rate > atmOptionletRate_
std::vector< std::vector< Volatility > > optionletVolatilities_
ext::shared_ptr< IborIndex > iborIndex_
std::vector< Date > optionletPaymentDates_
std::vector< Time > optionletAccrualPeriods_
std::vector< Time > optionletTimes_
std::vector< Date > optionletDates_
std::vector< std::vector< Rate > > optionletStrikes_
Volatility volatility(const Period &optionTenor, Rate strike, bool extrapolate=false) const
returns the volatility for a given option tenor and strike rate
void setMaxEvaluations(Size evaluations)
Definition: solver1d.hpp:238
Real solve(const F &f, Real accuracy, Real guess, Real step) const
Definition: solver1d.hpp:84
Interest-rate term structure.
QL_REAL Real
real number
Definition: types.hpp:50
Real Volatility
volatility
Definition: types.hpp:78
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
STL namespace.