QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
swaption.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2001, 2002, 2003 Sadruddin Rejeb
5 Copyright (C) 2006 Cristina Duminuco
6 Copyright (C) 2006 Marco Bianchetti
7 Copyright (C) 2007 StatPro Italia srl
8 Copyright (C) 2014 Ferdinando Ametrano
9 Copyright (C) 2016, 2018 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
25#include <ql/any.hpp>
26#include <ql/exercise.hpp>
27#include <ql/instruments/swaption.hpp>
28#include <ql/math/solvers1d/newtonsafe.hpp>
29#include <ql/pricingengines/swaption/blackswaptionengine.hpp>
30#include <ql/quotes/simplequote.hpp>
31#include <ql/shared_ptr.hpp>
32#include <utility>
33
34namespace QuantLib {
35
36 namespace {
37
38 class ImpliedSwaptionVolHelper {
39 public:
40 ImpliedSwaptionVolHelper(const Swaption&,
41 Handle<YieldTermStructure> discountCurve,
42 Real targetValue,
43 Real displacement,
44 VolatilityType type);
45 Real operator()(Volatility x) const;
46 Real derivative(Volatility x) const;
47 private:
48 ext::shared_ptr<PricingEngine> engine_;
49 Handle<YieldTermStructure> discountCurve_;
50 Real targetValue_;
51 ext::shared_ptr<SimpleQuote> vol_;
52 const Instrument::results* results_;
53 };
54
55 ImpliedSwaptionVolHelper::ImpliedSwaptionVolHelper(const Swaption& swaption,
56 Handle<YieldTermStructure> discountCurve,
57 Real targetValue,
58 Real displacement,
59 VolatilityType type)
60 : discountCurve_(std::move(discountCurve)), targetValue_(targetValue),
61 vol_(ext::make_shared<SimpleQuote>(-1.0)) {
62
63 // vol_ is set an implausible value, so that calculation is forced
64 // at first ImpliedSwaptionVolHelper::operator()(Volatility x) call
65
66 Handle<Quote> h(vol_);
67
68 switch (type) {
70 engine_ = ext::make_shared<BlackSwaptionEngine>(
71 discountCurve_, h, Actual365Fixed(), displacement);
72 break;
73 case Normal:
74 engine_ = ext::make_shared<BachelierSwaptionEngine>(
75 discountCurve_, h, Actual365Fixed());
76 break;
77 default:
78 QL_FAIL("unknown VolatilityType (" << type << ")");
79 break;
80 }
81 swaption.setupArguments(engine_->getArguments());
82 results_ = dynamic_cast<const Instrument::results *>(
83 engine_->getResults());
84 }
85
86 Real ImpliedSwaptionVolHelper::operator()(Volatility x) const {
87 if (x!=vol_->value()) {
88 vol_->setValue(x);
89 engine_->calculate();
90 }
91 return results_->value-targetValue_;
92 }
93
94 Real ImpliedSwaptionVolHelper::derivative(Volatility x) const {
95 if (x!=vol_->value()) {
96 vol_->setValue(x);
97 engine_->calculate();
98 }
99 auto vega_ = results_->additionalResults.find("vega");
100 QL_REQUIRE(vega_ != results_->additionalResults.end(),
101 "vega not provided");
102 return ext::any_cast<Real>(vega_->second);
103 }
104 }
105
106 std::ostream& operator<<(std::ostream& out,
108 switch (t) {
109 case Settlement::Physical:
110 return out << "Delivery";
111 case Settlement::Cash:
112 return out << "Cash";
113 default:
114 QL_FAIL("unknown Settlement::Type(" << Integer(t) << ")");
115 }
116 }
117
118 std::ostream& operator<<(std::ostream& out, Settlement::Method m) {
119 switch (m) {
120 case Settlement::PhysicalOTC:
121 return out << "PhysicalOTC";
122 case Settlement::PhysicalCleared:
123 return out << "PhysicalCleared";
124 case Settlement::CollateralizedCashPrice:
125 return out << "CollateralizedCashPrice";
126 case Settlement::ParYieldCurve:
127 return out << "ParYieldCurve";
128 default:
129 QL_FAIL("unknown Settlement::Method(" << Integer(m) << ")");
130 }
131 }
132
133 Swaption::Swaption(ext::shared_ptr<VanillaSwap> swap,
134 const ext::shared_ptr<Exercise>& exercise,
135 Settlement::Type delivery,
136 Settlement::Method settlementMethod)
137 : Option(ext::shared_ptr<Payoff>(), exercise), swap_(std::move(swap)),
138 settlementType_(delivery), settlementMethod_(settlementMethod) {
140 // When we ask for the NPV of an expired swaption, the
141 // swap is not recalculated and thus wouldn't forward
142 // later notifications according to the default behavior of
143 // LazyObject instances. This means that even if the
144 // evaluation date changes so that the swaption is no longer
145 // expired, the instrument wouldn't be notified and thus it
146 // wouldn't recalculate. To avoid this, we override the
147 // default behavior of the underlying swap.
148 swap_->alwaysForwardNotifications();
149 }
150
152 swap_->deepUpdate();
153 update();
154 }
155
156 bool Swaption::isExpired() const {
157 return detail::simple_event(exercise_->dates().back()).hasOccurred();
158 }
159
161
162 swap_->setupArguments(args);
163
164 auto* arguments = dynamic_cast<Swaption::arguments*>(args);
165
166 QL_REQUIRE(arguments != nullptr, "wrong argument type");
167
172 }
173
175 VanillaSwap::arguments::validate();
176 QL_REQUIRE(swap, "vanilla swap not set");
177 QL_REQUIRE(exercise, "exercise not set");
180 }
181
184 Volatility guess,
185 Real accuracy,
186 Natural maxEvaluations,
187 Volatility minVol,
188 Volatility maxVol,
190 Real displacement) const {
191 //calculate();
192 QL_REQUIRE(!isExpired(), "instrument expired");
193
194 ImpliedSwaptionVolHelper f(*this, d, targetValue, displacement, type);
195 //Brent solver;
196 NewtonSafe solver;
197 solver.setMaxEvaluations(maxEvaluations);
198 return solver.solve(f, accuracy, guess, minVol, maxVol);
199 }
200
204 if (settlementType == Physical) {
205 QL_REQUIRE(settlementMethod == PhysicalOTC ||
206 settlementMethod == PhysicalCleared,
207 "invalid settlement method for physical settlement");
208 }
209 if (settlementType == Cash) {
210 QL_REQUIRE(settlementMethod == CollateralizedCashPrice ||
211 settlementMethod == ParYieldCurve,
212 "invalid settlement method for cash settlement");
213 }
214 }
215
216}
virtual bool hasOccurred(const Date &refDate=Date(), ext::optional< bool > includeRefDate=ext::nullopt) const
returns true if an event has already occurred before a date
Definition: event.cpp:28
Shared handle to an observable.
Definition: handle.hpp:41
void update() override
Definition: lazyobject.hpp:188
safe Newton 1-D solver
Definition: newtonsafe.hpp:40
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Definition: observable.hpp:228
ext::shared_ptr< Exercise > exercise
Definition: option.hpp:65
base option class
Definition: option.hpp:36
ext::shared_ptr< Exercise > exercise_
Definition: option.hpp:50
Abstract base class for option payoffs.
Definition: payoff.hpp:36
void setMaxEvaluations(Size evaluations)
Definition: solver1d.hpp:238
Real solve(const F &f, Real accuracy, Real guess, Real step) const
Definition: solver1d.hpp:84
Arguments for swaption calculation
Definition: swaption.hpp:130
Settlement::Method settlementMethod
Definition: swaption.hpp:135
ext::shared_ptr< VanillaSwap > swap
Definition: swaption.hpp:133
Settlement::Type settlementType
Definition: swaption.hpp:134
void validate() const override
Definition: swaption.cpp:174
void setupArguments(PricingEngine::arguments *) const override
Definition: swaption.cpp:160
Settlement::Type settlementType() const
Definition: swaption.hpp:100
bool isExpired() const override
returns whether the instrument might have value greater than zero.
Definition: swaption.cpp:156
ext::shared_ptr< VanillaSwap > swap_
Definition: swaption.hpp:122
void deepUpdate() override
Definition: swaption.cpp:151
Swap::Type type() const
Definition: swaption.hpp:104
Settlement::Method settlementMethod_
Definition: swaption.hpp:125
Volatility impliedVolatility(Real price, const Handle< YieldTermStructure > &discountCurve, Volatility guess, Real accuracy=1.0e-4, Natural maxEvaluations=100, Volatility minVol=1.0e-7, Volatility maxVol=4.0, VolatilityType type=ShiftedLognormal, Real displacement=0.0) const
implied volatility
Definition: swaption.cpp:182
Settlement::Method settlementMethod() const
Definition: swaption.hpp:101
Settlement::Type settlementType_
Definition: swaption.hpp:124
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
QL_INTEGER Integer
integer number
Definition: types.hpp:35
Definition: any.hpp:35
std::ostream & operator<<(std::ostream &out, GFunctionFactory::YieldCurveModel type)
void swap(Array &v, Array &w) noexcept
Definition: array.hpp:903
STL namespace.
static void checkTypeAndMethodConsistency(Settlement::Type, Settlement::Method)
check consistency of settlement type and method
Definition: swaption.cpp:201