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) 2007 Cristina Duminuco
6 Copyright (C) 2011 Ferdinando Ametrano
7 Copyright (C) 2015 Peter Caspers
8
9 This file is part of QuantLib, a free-software/open-source library
10 for financial quantitative analysts and developers - http://quantlib.org/
11
12 QuantLib is free software: you can redistribute it and/or modify it
13 under the terms of the QuantLib license. You should have received a
14 copy of the license along with this program; if not, please email
15 <quantlib-dev@lists.sf.net>. The license is also available online at
16 <http://quantlib.org/license.shtml>.
17
18 This program is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20 FOR A PARTICULAR PURPOSE. See the license for more details.
21*/
22
23/*! \file couponpricer.hpp
24 \brief Coupon pricers
25*/
26
27#ifndef quantlib_coupon_pricer_hpp
28#define quantlib_coupon_pricer_hpp
29
30#include <ql/cashflow.hpp>
31#include <ql/indexes/iborindex.hpp>
32#include <ql/option.hpp>
33#include <ql/optional.hpp>
34#include <ql/quotes/simplequote.hpp>
35#include <ql/termstructures/volatility/optionlet/optionletvolatilitystructure.hpp>
36#include <ql/termstructures/volatility/swaption/swaptionvolstructure.hpp>
37#include <utility>
38
39namespace QuantLib {
40
41 class FloatingRateCoupon;
42 class IborCoupon;
43
44 //! generic pricer for floating-rate coupons
45 class FloatingRateCouponPricer: public virtual Observer,
46 public virtual Observable {
47 public:
48 ~FloatingRateCouponPricer() override = default;
49 //! \name required interface
50 //@{
51 virtual Real swapletPrice() const = 0;
52 virtual Rate swapletRate() const = 0;
53 virtual Real capletPrice(Rate effectiveCap) const = 0;
54 virtual Rate capletRate(Rate effectiveCap) const = 0;
55 virtual Real floorletPrice(Rate effectiveFloor) const = 0;
56 virtual Rate floorletRate(Rate effectiveFloor) const = 0;
57 virtual void initialize(const FloatingRateCoupon& coupon) = 0;
58 //@}
59 //! \name Observer interface
60 //@{
61 void update() override { notifyObservers(); }
62 //@}
63 };
64
65 //! base pricer for capped/floored Ibor coupons
66 class IborCouponPricer : public FloatingRateCouponPricer {
67 public:
68 explicit IborCouponPricer(
69 Handle<OptionletVolatilityStructure> v = Handle<OptionletVolatilityStructure>(),
70 ext::optional<bool> useIndexedCoupon = ext::nullopt);
71
72 bool useIndexedCoupon() const { return useIndexedCoupon_; }
73
74 Handle<OptionletVolatilityStructure> capletVolatility() const {
75 return capletVol_;
76 }
77 void setCapletVolatility(
78 const Handle<OptionletVolatilityStructure>& v =
79 Handle<OptionletVolatilityStructure>()) {
80 unregisterWith(h: capletVol_);
81 capletVol_ = v;
82 registerWith(h: capletVol_);
83 update();
84 }
85 void initialize(const FloatingRateCoupon& coupon) override;
86
87 void initializeCachedData(const IborCoupon& coupon) const;
88
89 protected:
90
91 const IborCoupon* coupon_;
92
93 ext::shared_ptr<IborIndex> index_;
94 Date fixingDate_;
95 Real gearing_;
96 Spread spread_;
97 Time accrualPeriod_;
98
99 Date fixingValueDate_, fixingEndDate_, fixingMaturityDate_;
100 Time spanningTime_, spanningTimeIndexMaturity_;
101
102 Handle<OptionletVolatilityStructure> capletVol_;
103 bool useIndexedCoupon_;
104 };
105
106 /*! Black-formula pricer for capped/floored Ibor coupons
107 References for timing adjustments
108 Black76 Hull, Options, Futures and other
109 derivatives, 4th ed., page 550
110 BivariateLognormal http://ssrn.com/abstract=2170721 */
111 class BlackIborCouponPricer : public IborCouponPricer {
112 public:
113 enum TimingAdjustment { Black76, BivariateLognormal };
114 BlackIborCouponPricer(
115 const Handle<OptionletVolatilityStructure>& v = Handle<OptionletVolatilityStructure>(),
116 const TimingAdjustment timingAdjustment = Black76,
117 Handle<Quote> correlation = Handle<Quote>(ext::shared_ptr<Quote>(new SimpleQuote(1.0))),
118 const ext::optional<bool> useIndexedCoupon = ext::nullopt)
119 : IborCouponPricer(v, useIndexedCoupon), timingAdjustment_(timingAdjustment),
120 correlation_(std::move(correlation)) {
121 { // this additional scope seems required to avoid a misleading-indentation warning
122 QL_REQUIRE(timingAdjustment_ == Black76 || timingAdjustment_ == BivariateLognormal,
123 "unknown timing adjustment (code " << timingAdjustment_ << ")");
124 }
125 registerWith(h: correlation_);
126 };
127 void initialize(const FloatingRateCoupon& coupon) override;
128 Real swapletPrice() const override;
129 Rate swapletRate() const override;
130 Real capletPrice(Rate effectiveCap) const override;
131 Rate capletRate(Rate effectiveCap) const override;
132 Real floorletPrice(Rate effectiveFloor) const override;
133 Rate floorletRate(Rate effectiveFloor) const override;
134
135 protected:
136 Real optionletPrice(Option::Type optionType, Real effStrike) const;
137 Real optionletRate(Option::Type optionType, Real effStrike) const;
138
139 virtual Rate adjustedFixing(Rate fixing = Null<Rate>()) const;
140
141 Real discount_;
142
143 private:
144 const TimingAdjustment timingAdjustment_;
145 const Handle<Quote> correlation_;
146 };
147
148 //! base pricer for vanilla CMS coupons
149 class CmsCouponPricer : public FloatingRateCouponPricer {
150 public:
151 explicit CmsCouponPricer(
152 Handle<SwaptionVolatilityStructure> v = Handle<SwaptionVolatilityStructure>())
153 : swaptionVol_(std::move(v)) {
154 registerWith(h: swaptionVol_);
155 }
156
157 Handle<SwaptionVolatilityStructure> swaptionVolatility() const{
158 return swaptionVol_;
159 }
160 void setSwaptionVolatility(
161 const Handle<SwaptionVolatilityStructure>& v=
162 Handle<SwaptionVolatilityStructure>()) {
163 unregisterWith(h: swaptionVol_);
164 swaptionVol_ = v;
165 registerWith(h: swaptionVol_);
166 update();
167 }
168 private:
169 Handle<SwaptionVolatilityStructure> swaptionVol_;
170 };
171
172 /*! (CMS) coupon pricer that has a mean reversion parameter which can be
173 used to calibrate to cms market quotes */
174 class MeanRevertingPricer {
175 public:
176 virtual Real meanReversion() const = 0;
177 virtual void setMeanReversion(const Handle<Quote>&) = 0;
178 virtual ~MeanRevertingPricer() = default;
179 };
180
181 void setCouponPricer(const Leg& leg,
182 const ext::shared_ptr<FloatingRateCouponPricer>&);
183
184 void setCouponPricers(
185 const Leg& leg,
186 const std::vector<ext::shared_ptr<FloatingRateCouponPricer> >&);
187
188 /*! set the first matching pricer (if any) to each coupon of the leg */
189 void setCouponPricers(
190 const Leg& leg,
191 const ext::shared_ptr<FloatingRateCouponPricer>&,
192 const ext::shared_ptr<FloatingRateCouponPricer>&);
193
194 void setCouponPricers(
195 const Leg& leg,
196 const ext::shared_ptr<FloatingRateCouponPricer>&,
197 const ext::shared_ptr<FloatingRateCouponPricer>&,
198 const ext::shared_ptr<FloatingRateCouponPricer>&);
199
200 void setCouponPricers(
201 const Leg& leg,
202 const ext::shared_ptr<FloatingRateCouponPricer>&,
203 const ext::shared_ptr<FloatingRateCouponPricer>&,
204 const ext::shared_ptr<FloatingRateCouponPricer>&,
205 const ext::shared_ptr<FloatingRateCouponPricer>&);
206
207 // inline
208
209 inline Real BlackIborCouponPricer::swapletPrice() const {
210 // past or future fixing is managed in InterestRateIndex::fixing()
211 QL_REQUIRE(discount_ != Null<Rate>(), "no forecast curve provided");
212 return swapletRate() * accrualPeriod_ * discount_;
213 }
214
215 inline Rate BlackIborCouponPricer::swapletRate() const {
216 return gearing_ * adjustedFixing() + spread_;
217 }
218
219 inline Real BlackIborCouponPricer::capletPrice(Rate effectiveCap) const {
220 QL_REQUIRE(discount_ != Null<Rate>(), "no forecast curve provided");
221 return capletRate(effectiveCap) * accrualPeriod_ * discount_;
222 }
223
224 inline Rate BlackIborCouponPricer::capletRate(Rate effectiveCap) const {
225 return gearing_ * optionletRate(optionType: Option::Call, effStrike: effectiveCap);
226 }
227
228 inline
229 Real BlackIborCouponPricer::floorletPrice(Rate effectiveFloor) const {
230 QL_REQUIRE(discount_ != Null<Rate>(), "no forecast curve provided");
231 return floorletRate(effectiveFloor) * accrualPeriod_ * discount_;
232 }
233
234 inline
235 Rate BlackIborCouponPricer::floorletRate(Rate effectiveFloor) const {
236 return gearing_ * optionletRate(optionType: Option::Put, effStrike: effectiveFloor);
237 }
238
239}
240
241#endif
242

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of quantlib/ql/cashflows/couponpricer.hpp