QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
digitalcoupon.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2007 Cristina Duminuco
5 Copyright (C) 2007 Giorgio Facchinetti
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/cashflows/capflooredcoupon.hpp>
22#include <ql/cashflows/digitalcoupon.hpp>
23#include <ql/indexes/indexmanager.hpp>
24#include <ql/indexes/interestrateindex.hpp>
25
26namespace QuantLib {
27
28 DigitalCoupon::DigitalCoupon(const ext::shared_ptr<FloatingRateCoupon>& underlying,
29 Rate callStrike,
30 Position::Type callPosition,
31 bool isCallATMIncluded,
32 Rate callDigitalPayoff,
33 Rate putStrike,
34 Position::Type putPosition,
35 bool isPutATMIncluded,
36 Rate putDigitalPayoff,
37 ext::shared_ptr<DigitalReplication> replication,
38 const bool nakedOption)
39 : FloatingRateCoupon(underlying->date(),
40 underlying->nominal(),
41 underlying->accrualStartDate(),
42 underlying->accrualEndDate(),
43 underlying->fixingDays(),
44 underlying->index(),
45 underlying->gearing(),
46 underlying->spread(),
47 underlying->referencePeriodStart(),
48 underlying->referencePeriodEnd(),
49 underlying->dayCounter(),
50 underlying->isInArrears()),
51 underlying_(underlying), isCallATMIncluded_(isCallATMIncluded),
52 isPutATMIncluded_(isPutATMIncluded), nakedOption_(nakedOption) {
53
54 if (replication == nullptr)
55 replication = ext::make_shared<DigitalReplication>();
56
57 QL_REQUIRE(replication->gap()>0.0, "Non positive epsilon not allowed");
58
59 callLeftEps_ = callRightEps_ = putLeftEps_ = putRightEps_ = replication->gap() / 2;
60 replicationType_ = replication->replicationType();
61
62 if (putStrike == Null<Rate>()) {
63 QL_REQUIRE(putDigitalPayoff == Null<Rate>(),
64 "Put Cash rate non allowed if put strike is null");
65 }
66 if (callStrike == Null<Rate>()) {
67 QL_REQUIRE(callDigitalPayoff == Null<Rate>(),
68 "Call Cash rate non allowed if call strike is null");
69 }
70 if (callStrike != Null<Rate>()) {
71 hasCallStrike_ = true;
73 switch (callPosition) {
74 case Position::Long :
75 callCsi_ = 1.0;
76 break;
77 case Position::Short :
78 callCsi_ = -1.0;
79 break;
80 default:
81 QL_FAIL("unsupported position type");
82 }
86 }
87 }
88 if (putStrike != Null<Rate>()){
89 hasPutStrike_ = true;
91 switch (putPosition) {
92 case Position::Long :
93 putCsi_ = 1.0;
94 break;
95 case Position::Short :
96 putCsi_ = -1.0;
97 break;
98 default:
99 QL_FAIL("unsupported position type");
100 }
103 isPutCashOrNothing_ = true;
104 }
105 }
106
107 switch (replicationType_) {
109 // do nothing
110 break;
111 case Replication::Sub :
112 if (hasCallStrike_) {
113 switch (callPosition) {
114 case Position::Long :
115 callLeftEps_ = 0.;
116 callRightEps_ = replication->gap();
117 break;
118 case Position::Short :
119 callLeftEps_ = replication->gap();
120 callRightEps_ = 0.;
121 break;
122 default:
123 QL_FAIL("unsupported position type");
124 }
125 }
126 if (hasPutStrike_) {
127 switch (putPosition) {
128 case Position::Long :
129 putLeftEps_ = replication->gap();
130 putRightEps_ = 0.;
131 break;
132 case Position::Short :
133 putLeftEps_ = 0.;
134 putRightEps_ = replication->gap();
135 break;
136 default:
137 QL_FAIL("unsupported position type");
138 }
139 }
140 break;
141 case Replication::Super :
142 if (hasCallStrike_) {
143 switch (callPosition) {
144 case Position::Long :
145 callLeftEps_ = replication->gap();
146 callRightEps_ = 0.;
147 break;
148 case Position::Short :
149 callLeftEps_ = 0.;
150 callRightEps_ = replication->gap();
151 break;
152 default:
153 QL_FAIL("unsupported position type");
154 }
155 }
156 if (hasPutStrike_) {
157 switch (putPosition) {
158 case Position::Long :
159 putLeftEps_ = 0.;
160 putRightEps_ = replication->gap();
161 break;
162 case Position::Short :
163 putLeftEps_ = replication->gap();
164 putRightEps_ = 0.;
165 break;
166 default:
167 QL_FAIL("unsupported position type");
168 }
169 }
170 break;
171 default:
172 QL_FAIL("unsupported replication type");
173 }
174
176 }
177
178
180
182 if(hasCallStrike_) {
183 // Step function
187 callOptionRate *= (next.rate() - previous.rate())
190 // Call
192 Rate call = underlying_->rate() - atStrike.rate();
193 // Sum up
194 callOptionRate += call;
195 }
196 }
197 return callOptionRate;
198 }
199
201
202 Rate putOptionRate = Rate(0.);
203 if(hasPutStrike_) {
204 // Step function
208 putOptionRate *= (next.rate() - previous.rate())
210 if (!isPutCashOrNothing_) {
211 // Put
213 Rate put = - underlying_->rate() + atStrike.rate();
214 // Sum up
215 putOptionRate -= put;
216 }
217 }
218 return putOptionRate;
219 }
220
222 update();
223 underlying_->deepUpdate();
224 }
225
227
228 QL_REQUIRE(underlying_->pricer(), "pricer not set");
229
230 Date fixingDate = underlying_->fixingDate();
232 bool enforceTodaysHistoricFixings =
234 Rate underlyingRate = nakedOption_ ? 0.0 : underlying_->rate();
235 if (fixingDate < today ||
236 ((fixingDate == today) && enforceTodaysHistoricFixings)) {
237 // must have been fixed
238 rate_ = underlyingRate + callCsi_ * callPayoff() + putCsi_ * putPayoff();
239 } else if (fixingDate == today) {
240 // might have been fixed
241 Rate pastFixing =
243 if (pastFixing != Null<Real>()) {
244 rate_ = underlyingRate + callCsi_ * callPayoff() + putCsi_ * putPayoff();
245 } else {
246 rate_ = underlyingRate + callCsi_ * callOptionRate() + putCsi_ * putOptionRate();
247 }
248 } else {
249 rate_ = underlyingRate + callCsi_ * callOptionRate() + putCsi_ * putOptionRate();
250 }
251 }
252
254 calculate();
255 return rate_;
256 }
257
259 return underlying_->convexityAdjustment();
260 }
261
263 if (hasCall())
264 return callStrike_;
265 else
266 return Null<Rate>();
267 }
268
270 if (hasPut())
271 return putStrike_;
272 else
273 return Null<Rate>();
274 }
275
278 return callDigitalPayoff_;
279 else
280 return Null<Rate>();
281 }
282
285 return putDigitalPayoff_;
286 else
287 return Null<Rate>();
288 }
289
291 typedef FloatingRateCoupon super;
292 auto* v1 = dynamic_cast<Visitor<DigitalCoupon>*>(&v);
293 if (v1 != nullptr)
294 v1->visit(*this);
295 else
296 super::accept(v);
297 }
298
300 // to use only if index has fixed
301 Rate payoff(0.);
302 if(hasCallStrike_) {
303 Rate underlyingRate = underlying_->rate();
304 if ( (underlyingRate - callStrike_) > 1.e-16 ) {
305 payoff = isCallCashOrNothing_ ? callDigitalPayoff_ : underlyingRate;
306 } else {
307 if (isCallATMIncluded_) {
308 if ( std::abs(callStrike_ - underlyingRate) <= 1.e-16 )
309 payoff = isCallCashOrNothing_ ? callDigitalPayoff_ : underlyingRate;
310 }
311 }
312 }
313 return payoff;
314 }
315
317 // to use only if index has fixed
318 Rate payoff(0.);
319 if(hasPutStrike_) {
320 Rate underlyingRate = underlying_->rate();
321 if ( (putStrike_ - underlyingRate) > 1.e-16 ) {
322 payoff = isPutCashOrNothing_ ? putDigitalPayoff_ : underlyingRate;
323 } else {
324 // putStrike_ <= underlyingRate
325 if (isPutATMIncluded_) {
326 if ( std::abs(putStrike_ - underlyingRate) <= 1.e-16 )
327 payoff = isPutCashOrNothing_ ? putDigitalPayoff_ : underlyingRate;
328 }
329 }
330 }
331 return payoff;
332 }
333
334}
335
degenerate base class for the Acyclic Visitor pattern
Definition: visitor.hpp:33
Capped and/or floored floating-rate coupon.
Rate rate() const override
accrued rate
Concrete date class.
Definition: date.hpp:125
Real callLeftEps_
the left and right gaps applied in payoff replication for call
void performCalculations() const override
Rate putDigitalPayoff_
digital put option payoff rate, if any
ext::shared_ptr< FloatingRateCoupon > underlying() const
void deepUpdate() override
bool isPutCashOrNothing_
digital put option type: if true, cash-or-nothing, if false asset-or-nothing
ext::shared_ptr< FloatingRateCoupon > underlying_
Rate rate() const override
accrued rate
bool isCallATMIncluded_
inclusion flag og the call payoff if the call option ends at-the-money
void accept(AcyclicVisitor &) override
bool isPutATMIncluded_
inclusion flag og the put payoff if the put option ends at-the-money
bool nakedOption_
underlying excluded from the payoff
Rate callStrike_
strike rate for the the call option
bool isCallCashOrNothing_
digital call option type: if true, cash-or-nothing, if false asset-or-nothing
Real callCsi_
multiplicative factor of call payoff
Replication::Type replicationType_
Type of replication.
Rate callDigitalPayoff() const
Rate putStrike_
strike rate for the the put option
Rate callDigitalPayoff_
digital call option payoff rate, if any
Real putLeftEps_
the left and right gaps applied in payoff replication for put
Rate convexityAdjustment() const override
convexity adjustment
DigitalCoupon(const ext::shared_ptr< FloatingRateCoupon > &underlying, Rate callStrike=Null< Rate >(), Position::Type callPosition=Position::Long, bool isCallITMIncluded=false, Rate callDigitalPayoff=Null< Rate >(), Rate putStrike=Null< Rate >(), Position::Type putPosition=Position::Long, bool isPutITMIncluded=false, Rate putDigitalPayoff=Null< Rate >(), ext::shared_ptr< DigitalReplication > replication={}, bool nakedOption=false)
general constructor
Real putCsi_
multiplicative factor of put payoff
base floating-rate coupon class
virtual Date fixingDate() const
fixing date
const TimeSeries< Real > & getHistory(const std::string &name) const
returns the (possibly empty) history of the index fixings
virtual void calculate() const
Definition: lazyobject.hpp:253
void update() override
Definition: lazyobject.hpp:188
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
DateProxy & evaluationDate()
the date at which pricing is to be performed.
Definition: settings.hpp:147
bool & enforcesTodaysHistoricFixings()
Definition: settings.hpp:171
static Settings & instance()
access to the unique instance
Definition: singleton.hpp:104
Visitor for a specific class
Definition: visitor.hpp:40
virtual void visit(T &)=0
Real Rate
interest rates
Definition: types.hpp:70
Definition: any.hpp:35