QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
floatfloatswap.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2013 Peter Caspers
5
6 This file is part of QuantLib, a free-software/open-source library
7 for financial quantitative analysts and developers - http://quantlib.org/
8
9 QuantLib is free software: you can redistribute it and/or modify it
10 under the terms of the QuantLib license. You should have received a
11 copy of the license along with this program; if not, please email
12 <quantlib-dev@lists.sf.net>. The license is also available online at
13 <http://quantlib.org/license.shtml>.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the license for more details.
18*/
19
20#include <ql/cashflows/capflooredcoupon.hpp>
21#include <ql/cashflows/cashflows.hpp>
22#include <ql/cashflows/cashflowvectors.hpp>
23#include <ql/cashflows/cmscoupon.hpp>
24#include <ql/cashflows/couponpricer.hpp>
25#include <ql/cashflows/iborcoupon.hpp>
26#include <ql/cashflows/simplecashflow.hpp>
27#include <ql/experimental/coupons/cmsspreadcoupon.hpp> // internal
28#include <ql/indexes/iborindex.hpp>
29#include <ql/indexes/swapindex.hpp>
30#include <ql/instruments/floatfloatswap.hpp>
31#include <ql/termstructures/yieldtermstructure.hpp>
32#include <ql/optional.hpp>
33#include <utility>
34
35namespace QuantLib {
36
38 const Real nominal1,
39 const Real nominal2,
40 const Schedule& schedule1,
41 ext::shared_ptr<InterestRateIndex> index1,
42 DayCounter dayCount1,
43 const Schedule& schedule2,
44 ext::shared_ptr<InterestRateIndex> index2,
45 DayCounter dayCount2,
46 const bool intermediateCapitalExchange,
47 const bool finalCapitalExchange,
48 const Real gearing1,
49 const Real spread1,
50 const Real cappedRate1,
51 const Real flooredRate1,
52 const Real gearing2,
53 const Real spread2,
54 const Real cappedRate2,
55 const Real flooredRate2,
56 const ext::optional<BusinessDayConvention>& paymentConvention1,
57 const ext::optional<BusinessDayConvention>& paymentConvention2)
58 : Swap(2), type_(type), nominal1_(std::vector<Real>(schedule1.size() - 1, nominal1)),
59 nominal2_(std::vector<Real>(schedule2.size() - 1, nominal2)), schedule1_(schedule1),
60 schedule2_(schedule2), index1_(std::move(index1)), index2_(std::move(index2)),
61 gearing1_(std::vector<Real>(schedule1.size() - 1, gearing1)),
62 gearing2_(std::vector<Real>(schedule2.size() - 1, gearing2)),
63 spread1_(std::vector<Real>(schedule1.size() - 1, spread1)),
64 spread2_(std::vector<Real>(schedule2.size() - 1, spread2)),
65 cappedRate1_(std::vector<Real>(schedule1.size() - 1, cappedRate1)),
66 flooredRate1_(std::vector<Real>(schedule1.size() - 1, flooredRate1)),
67 cappedRate2_(std::vector<Real>(schedule2.size() - 1, cappedRate2)),
68 flooredRate2_(std::vector<Real>(schedule2.size() - 1, flooredRate2)),
69 dayCount1_(std::move(dayCount1)), dayCount2_(std::move(dayCount2)),
70 intermediateCapitalExchange_(intermediateCapitalExchange),
71 finalCapitalExchange_(finalCapitalExchange) {
72
74 }
75
77 std::vector<Real> nominal1,
78 std::vector<Real> nominal2,
79 Schedule schedule1,
80 ext::shared_ptr<InterestRateIndex> index1,
81 DayCounter dayCount1,
82 Schedule schedule2,
83 ext::shared_ptr<InterestRateIndex> index2,
84 DayCounter dayCount2,
85 const bool intermediateCapitalExchange,
86 const bool finalCapitalExchange,
87 std::vector<Real> gearing1,
88 std::vector<Real> spread1,
89 std::vector<Real> cappedRate1,
90 std::vector<Real> flooredRate1,
91 std::vector<Real> gearing2,
92 std::vector<Real> spread2,
93 std::vector<Real> cappedRate2,
94 std::vector<Real> flooredRate2,
95 const ext::optional<BusinessDayConvention>& paymentConvention1,
96 const ext::optional<BusinessDayConvention>& paymentConvention2)
97 : Swap(2), type_(type), nominal1_(std::move(nominal1)), nominal2_(std::move(nominal2)),
98 schedule1_(std::move(schedule1)), schedule2_(std::move(schedule2)),
99 index1_(std::move(index1)), index2_(std::move(index2)), gearing1_(std::move(gearing1)),
100 gearing2_(std::move(gearing2)), spread1_(std::move(spread1)), spread2_(std::move(spread2)),
101 cappedRate1_(std::move(cappedRate1)), flooredRate1_(std::move(flooredRate1)),
102 cappedRate2_(std::move(cappedRate2)), flooredRate2_(std::move(flooredRate2)),
103 dayCount1_(std::move(dayCount1)), dayCount2_(std::move(dayCount2)),
104 intermediateCapitalExchange_(intermediateCapitalExchange),
105 finalCapitalExchange_(finalCapitalExchange) {
106
108 }
109
111 ext::optional<BusinessDayConvention> paymentConvention1,
112 ext::optional<BusinessDayConvention> paymentConvention2) {
113
114 QL_REQUIRE(nominal1_.size() == schedule1_.size() - 1,
115 "nominal1 size (" << nominal1_.size()
116 << ") does not match schedule1 size ("
117 << schedule1_.size() << ")");
118 QL_REQUIRE(nominal2_.size() == schedule2_.size() - 1,
119 "nominal2 size (" << nominal2_.size()
120 << ") does not match schedule2 size ("
121 << nominal2_.size() << ")");
122 QL_REQUIRE(gearing1_.empty() || gearing1_.size() == nominal1_.size(),
123 "nominal1 size (" << nominal1_.size() << ") does not match gearing1 size ("
124 << gearing1_.size() << ")");
125 QL_REQUIRE(gearing2_.empty() || gearing2_.size() == nominal2_.size(),
126 "nominal2 size (" << nominal2_.size() << ") does not match gearing2 size ("
127 << gearing2_.size() << ")");
128 QL_REQUIRE(cappedRate1_.empty() || cappedRate1_.size() == nominal1_.size(),
129 "nominal1 size (" << nominal1_.size() << ") does not match cappedRate1 size ("
130 << cappedRate1_.size() << ")");
131 QL_REQUIRE(cappedRate2_.empty() || cappedRate2_.size() == nominal2_.size(),
132 "nominal2 size (" << nominal2_.size() << ") does not match cappedRate2 size ("
133 << cappedRate2_.size() << ")");
134 QL_REQUIRE(flooredRate1_.empty() || flooredRate1_.size() == nominal1_.size(),
135 "nominal1 size (" << nominal1_.size() << ") does not match flooredRate1 size ("
136 << flooredRate1_.size() << ")");
137 QL_REQUIRE(flooredRate2_.empty() || flooredRate2_.size() == nominal2_.size(),
138 "nominal2 size (" << nominal2_.size() << ") does not match flooredRate2 size ("
139 << flooredRate2_.size() << ")");
140
141 if (paymentConvention1) // NOLINT(readability-implicit-bool-conversion)
143 else
145
146 if (paymentConvention2) // NOLINT(readability-implicit-bool-conversion)
148 else
150
151 if (gearing1_.empty())
152 gearing1_ = std::vector<Real>(nominal1_.size(), 1.0);
153 if (gearing2_.empty())
154 gearing2_ = std::vector<Real>(nominal2_.size(), 1.0);
155 if (spread1_.empty())
156 spread1_ = std::vector<Real>(nominal1_.size(), 0.0);
157 if (spread2_.empty())
158 spread2_ = std::vector<Real>(nominal2_.size(), 0.0);
159 if (cappedRate1_.empty())
160 cappedRate1_ = std::vector<Real>(nominal1_.size(), Null<Real>());
161 if (cappedRate2_.empty())
162 cappedRate2_ = std::vector<Real>(nominal2_.size(), Null<Real>());
163 if (flooredRate1_.empty())
164 flooredRate1_ = std::vector<Real>(nominal1_.size(), Null<Real>());
165 if (flooredRate2_.empty())
166 flooredRate2_ = std::vector<Real>(nominal2_.size(), Null<Real>());
167
168 bool isNull;
169 isNull = cappedRate1_[0] == Null<Real>();
170 for (Size i = 0; i < cappedRate1_.size(); i++) {
171 if (isNull)
172 QL_REQUIRE(cappedRate1_[i] == Null<Real>(),
173 "cappedRate1 must be null for all or none entry ("
174 << (i + 1) << "th is " << cappedRate1_[i]
175 << ")");
176 else
177 QL_REQUIRE(cappedRate1_[i] != Null<Real>(),
178 "cappedRate 1 must be null for all or none entry ("
179 << "1st is " << cappedRate1_[0] << ")");
180 }
181 isNull = cappedRate2_[0] == Null<Real>();
182 for (Size i = 0; i < cappedRate2_.size(); i++) {
183 if (isNull)
184 QL_REQUIRE(cappedRate2_[i] == Null<Real>(),
185 "cappedRate2 must be null for all or none entry ("
186 << (i + 1) << "th is " << cappedRate2_[i]
187 << ")");
188 else
189 QL_REQUIRE(cappedRate2_[i] != Null<Real>(),
190 "cappedRate2 must be null for all or none entry ("
191 << "1st is " << cappedRate2_[0] << ")");
192 }
193 isNull = flooredRate1_[0] == Null<Real>();
194 for (Size i = 0; i < flooredRate1_.size(); i++) {
195 if (isNull)
196 QL_REQUIRE(flooredRate1_[i] == Null<Real>(),
197 "flooredRate1 must be null for all or none entry ("
198 << (i + 1) << "th is " << flooredRate1_[i]
199 << ")");
200 else
201 QL_REQUIRE(flooredRate1_[i] != Null<Real>(),
202 "flooredRate 1 must be null for all or none entry ("
203 << "1st is " << flooredRate1_[0] << ")");
204 }
205 isNull = flooredRate2_[0] == Null<Real>();
206 for (Size i = 0; i < flooredRate2_.size(); i++) {
207 if (isNull)
208 QL_REQUIRE(flooredRate2_[i] == Null<Real>(),
209 "flooredRate2 must be null for all or none entry ("
210 << (i + 1) << "th is " << flooredRate2_[i]
211 << ")");
212 else
213 QL_REQUIRE(flooredRate2_[i] != Null<Real>(),
214 "flooredRate2 must be null for all or none entry ("
215 << "1st is " << flooredRate2_[0] << ")");
216 }
217
218 // if the gearing is zero then the ibor / cms leg will be set up with
219 // fixed coupons which makes trouble here in this context. We therefore
220 // use a dirty trick and enforce the gearing to be non zero.
221 for (Real& i : gearing1_)
222 if (close(i, 0.0))
223 i = QL_EPSILON;
224 for (Real& i : gearing2_)
225 if (close(i, 0.0))
226 i = QL_EPSILON;
227
228 ext::shared_ptr<IborIndex> ibor1 =
229 ext::dynamic_pointer_cast<IborIndex>(index1_);
230 ext::shared_ptr<IborIndex> ibor2 =
231 ext::dynamic_pointer_cast<IborIndex>(index2_);
232 ext::shared_ptr<SwapIndex> cms1 =
233 ext::dynamic_pointer_cast<SwapIndex>(index1_);
234 ext::shared_ptr<SwapIndex> cms2 =
235 ext::dynamic_pointer_cast<SwapIndex>(index2_);
236 ext::shared_ptr<SwapSpreadIndex> cmsspread1 =
237 ext::dynamic_pointer_cast<SwapSpreadIndex>(index1_);
238 ext::shared_ptr<SwapSpreadIndex> cmsspread2 =
239 ext::dynamic_pointer_cast<SwapSpreadIndex>(index2_);
240
241 QL_REQUIRE(ibor1 != nullptr || cms1 != nullptr || cmsspread1 != nullptr,
242 "index1 must be ibor or cms or cms spread");
243 QL_REQUIRE(ibor2 != nullptr || cms2 != nullptr || cmsspread2 != nullptr,
244 "index2 must be ibor or cms");
245
246 if (ibor1 != nullptr) {
247 IborLeg leg(schedule1_, ibor1);
248 leg = leg.withNotionals(nominal1_)
249 .withPaymentDayCounter(dayCount1_)
250 .withPaymentAdjustment(paymentConvention1_)
251 .withSpreads(spread1_)
252 .withGearings(gearing1_);
253 if (cappedRate1_[0] != Null<Real>())
254 leg = leg.withCaps(cappedRate1_);
255 if (flooredRate1_[0] != Null<Real>())
256 leg = leg.withFloors(flooredRate1_);
257 legs_[0] = leg;
258 }
259
260 if (ibor2 != nullptr) {
261 IborLeg leg(schedule2_, ibor2);
262 leg = leg.withNotionals(nominal2_)
263 .withPaymentDayCounter(dayCount2_)
264 .withPaymentAdjustment(paymentConvention2_)
265 .withSpreads(spread2_)
266 .withGearings(gearing2_);
267 if (cappedRate2_[0] != Null<Real>())
268 leg = leg.withCaps(cappedRate2_);
269 if (flooredRate2_[0] != Null<Real>())
270 leg = leg.withFloors(flooredRate2_);
271 legs_[1] = leg;
272 }
273
274 if (cms1 != nullptr) {
275 CmsLeg leg(schedule1_, cms1);
276 leg = leg.withNotionals(nominal1_)
277 .withPaymentDayCounter(dayCount1_)
278 .withPaymentAdjustment(paymentConvention1_)
279 .withSpreads(spread1_)
280 .withGearings(gearing1_);
281 if (cappedRate1_[0] != Null<Real>())
282 leg = leg.withCaps(cappedRate1_);
283 if (flooredRate1_[0] != Null<Real>())
284 leg = leg.withFloors(flooredRate1_);
285 legs_[0] = leg;
286 }
287
288 if (cms2 != nullptr) {
289 CmsLeg leg(schedule2_, cms2);
290 leg = leg.withNotionals(nominal2_)
291 .withPaymentDayCounter(dayCount2_)
292 .withPaymentAdjustment(paymentConvention2_)
293 .withSpreads(spread2_)
294 .withGearings(gearing2_);
295 if (cappedRate2_[0] != Null<Real>())
296 leg = leg.withCaps(cappedRate2_);
297 if (flooredRate2_[0] != Null<Real>())
298 leg = leg.withFloors(flooredRate2_);
299 legs_[1] = leg;
300 }
301
302 if (cmsspread1 != nullptr) {
303 CmsSpreadLeg leg(schedule1_, cmsspread1);
304 leg = leg.withNotionals(nominal1_)
305 .withPaymentDayCounter(dayCount1_)
306 .withPaymentAdjustment(paymentConvention1_)
307 .withSpreads(spread1_)
308 .withGearings(gearing1_);
309 if (cappedRate1_[0] != Null<Real>())
310 leg = leg.withCaps(cappedRate1_);
311 if (flooredRate1_[0] != Null<Real>())
312 leg = leg.withFloors(flooredRate1_);
313 legs_[0] = leg;
314 }
315
316 if (cmsspread2 != nullptr) {
317 CmsSpreadLeg leg(schedule2_, cmsspread2);
318 leg = leg.withNotionals(nominal2_)
319 .withPaymentDayCounter(dayCount2_)
320 .withPaymentAdjustment(paymentConvention2_)
321 .withSpreads(spread2_)
322 .withGearings(gearing2_);
323 if (cappedRate2_[0] != Null<Real>())
324 leg = leg.withCaps(cappedRate2_);
325 if (flooredRate2_[0] != Null<Real>())
326 leg = leg.withFloors(flooredRate2_);
327 legs_[1] = leg;
328 }
329
331 for (Size i = 0; i < legs_[0].size() - 1; i++) {
332 Real cap = nominal1_[i] - nominal1_[i + 1];
333 if (!close(cap, 0.0)) {
334 auto it1 = legs_[0].begin();
335 std::advance(it1, i + 1);
336 legs_[0].insert(
337 it1, ext::shared_ptr<CashFlow>(
338 new Redemption(cap, legs_[0][i]->date())));
339 auto it2 = nominal1_.begin();
340 std::advance(it2, i + 1);
341 nominal1_.insert(it2, nominal1_[i]);
342 i++;
343 }
344 }
345 for (Size i = 0; i < legs_[1].size() - 1; i++) {
346 Real cap = nominal2_[i] - nominal2_[i + 1];
347 if (!close(cap, 0.0)) {
348 auto it1 = legs_[1].begin();
349 std::advance(it1, i + 1);
350 legs_[1].insert(
351 it1, ext::shared_ptr<CashFlow>(
352 new Redemption(cap, legs_[1][i]->date())));
353 auto it2 = nominal2_.begin();
354 std::advance(it2, i + 1);
355 nominal2_.insert(it2, nominal2_[i]);
356 i++;
357 }
358 }
359 }
360
362 legs_[0].push_back(ext::shared_ptr<CashFlow>(
363 new Redemption(nominal1_.back(), legs_[0].back()->date())));
364 nominal1_.push_back(nominal1_.back());
365 legs_[1].push_back(ext::shared_ptr<CashFlow>(
366 new Redemption(nominal2_.back(), legs_[1].back()->date())));
367 nominal2_.push_back(nominal2_.back());
368 }
369
370 for (Leg::const_iterator i = legs_[0].begin(); i < legs_[0].end(); ++i)
371 registerWith(*i);
372
373 for (Leg::const_iterator i = legs_[1].begin(); i < legs_[1].end(); ++i)
374 registerWith(*i);
375
376 switch (type_) {
377 case Swap::Payer:
378 payer_[0] = -1.0;
379 payer_[1] = +1.0;
380 break;
381 case Swap::Receiver:
382 payer_[0] = +1.0;
383 payer_[1] = -1.0;
384 break;
385 default:
386 QL_FAIL("Unknown float float - swap type");
387 }
388 }
389
391
393
394 auto* arguments = dynamic_cast<FloatFloatSwap::arguments*>(args);
395
396 if (arguments == nullptr)
397 return; // swap engine ... // QL_REQUIRE(arguments != 0, "argument type does not match");
398
404
405 const Leg &leg1Coupons = leg1();
406 const Leg &leg2Coupons = leg2();
407
409 arguments->leg1FixingDates = std::vector<Date>(leg1Coupons.size());
411 arguments->leg2FixingDates = std::vector<Date>(leg2Coupons.size());
412
414 arguments->leg1Gearings = std::vector<Real>(leg1Coupons.size());
416 arguments->leg2Gearings = std::vector<Real>(leg2Coupons.size());
417
419 std::vector<Real>(leg1Coupons.size(), Null<Real>());
421 std::vector<Real>(leg2Coupons.size(), Null<Real>());
422
424 std::vector<bool>(leg1Coupons.size(), false);
426 std::vector<bool>(leg2Coupons.size(), false);
427
429 std::vector<Real>(leg1Coupons.size(), Null<Real>());
431 std::vector<Real>(leg2Coupons.size(), Null<Real>());
432
433 for (Size i = 0; i < leg1Coupons.size(); ++i) {
434 ext::shared_ptr<FloatingRateCoupon> coupon =
435 ext::dynamic_pointer_cast<FloatingRateCoupon>(leg1Coupons[i]);
436 if (coupon != nullptr) {
437 arguments->leg1AccrualTimes[i] = coupon->accrualPeriod();
438 arguments->leg1PayDates[i] = coupon->date();
439 arguments->leg1ResetDates[i] = coupon->accrualStartDate();
440 arguments->leg1FixingDates[i] = coupon->fixingDate();
441 arguments->leg1Spreads[i] = coupon->spread();
442 arguments->leg1Gearings[i] = coupon->gearing();
443 try {
444 arguments->leg1Coupons[i] = coupon->amount();
445 }
446 catch (Error &) {
448 }
449 ext::shared_ptr<CappedFlooredCoupon> cfcoupon =
450 ext::dynamic_pointer_cast<CappedFlooredCoupon>(
451 leg1Coupons[i]);
452 if (cfcoupon != nullptr) {
453 arguments->leg1CappedRates[i] = cfcoupon->cap();
454 arguments->leg1FlooredRates[i] = cfcoupon->floor();
455 }
456 } else {
457 ext::shared_ptr<CashFlow> cashflow =
458 ext::dynamic_pointer_cast<CashFlow>(leg1Coupons[i]);
459 std::vector<Date>::const_iterator j =
460 std::find(arguments->leg1PayDates.begin(),
461 arguments->leg1PayDates.end(), cashflow->date());
462 QL_REQUIRE(j != arguments->leg1PayDates.end(),
463 "nominal redemption on "
464 << cashflow->date()
465 << "has no corresponding coupon");
466 Size jIdx = j - arguments->leg1PayDates.begin();
468 arguments->leg1Coupons[i] = cashflow->amount();
472 arguments->leg1AccrualTimes[i] = 0.0;
473 arguments->leg1Spreads[i] = 0.0;
474 arguments->leg1Gearings[i] = 1.0;
475 arguments->leg1PayDates[i] = cashflow->date();
476 }
477 }
478
479 for (Size i = 0; i < leg2Coupons.size(); ++i) {
480 ext::shared_ptr<FloatingRateCoupon> coupon =
481 ext::dynamic_pointer_cast<FloatingRateCoupon>(leg2Coupons[i]);
482 if (coupon != nullptr) {
483 arguments->leg2AccrualTimes[i] = coupon->accrualPeriod();
484 arguments->leg2PayDates[i] = coupon->date();
485 arguments->leg2ResetDates[i] = coupon->accrualStartDate();
486 arguments->leg2FixingDates[i] = coupon->fixingDate();
487 arguments->leg2Spreads[i] = coupon->spread();
488 arguments->leg2Gearings[i] = coupon->gearing();
489 try {
490 arguments->leg2Coupons[i] = coupon->amount();
491 }
492 catch (Error &) {
494 }
495 ext::shared_ptr<CappedFlooredCoupon> cfcoupon =
496 ext::dynamic_pointer_cast<CappedFlooredCoupon>(
497 leg2Coupons[i]);
498 if (cfcoupon != nullptr) {
499 arguments->leg2CappedRates[i] = cfcoupon->cap();
500 arguments->leg2FlooredRates[i] = cfcoupon->floor();
501 }
502 } else {
503 ext::shared_ptr<CashFlow> cashflow =
504 ext::dynamic_pointer_cast<CashFlow>(leg2Coupons[i]);
505 std::vector<Date>::const_iterator j =
506 std::find(arguments->leg2PayDates.begin(),
507 arguments->leg2PayDates.end(), cashflow->date());
508 QL_REQUIRE(j != arguments->leg2PayDates.end(),
509 "nominal redemption on "
510 << cashflow->date()
511 << "has no corresponding coupon");
512 Size jIdx = j - arguments->leg2PayDates.begin();
514 arguments->leg2Coupons[i] = cashflow->amount();
518 arguments->leg2AccrualTimes[i] = 0.0;
519 arguments->leg2Spreads[i] = 0.0;
520 arguments->leg2Gearings[i] = 1.0;
521 arguments->leg2PayDates[i] = cashflow->date();
522 }
523 }
524 }
525
527
530 }
531
533
535
536 QL_REQUIRE(nominal1.size() == leg1ResetDates.size(),
537 "nominal1 size is different from resetDates1 size");
538 QL_REQUIRE(nominal1.size() == leg1FixingDates.size(),
539 "nominal1 size is different from fixingDates1 size");
540 QL_REQUIRE(nominal1.size() == leg1PayDates.size(),
541 "nominal1 size is different from payDates1 size");
542 QL_REQUIRE(nominal1.size() == leg1Spreads.size(),
543 "nominal1 size is different from spreads1 size");
544 QL_REQUIRE(nominal1.size() == leg1Gearings.size(),
545 "nominal1 size is different from gearings1 size");
546 QL_REQUIRE(nominal1.size() == leg1CappedRates.size(),
547 "nominal1 size is different from cappedRates1 size");
548 QL_REQUIRE(nominal1.size() == leg1FlooredRates.size(),
549 "nominal1 size is different from flooredRates1 size");
550 QL_REQUIRE(nominal1.size() == leg1Coupons.size(),
551 "nominal1 size is different from coupons1 size");
552 QL_REQUIRE(nominal1.size() == leg1AccrualTimes.size(),
553 "nominal1 size is different from accrualTimes1 size");
554 QL_REQUIRE(nominal1.size() == leg1IsRedemptionFlow.size(),
555 "nominal1 size is different from redemption1 size");
556
557 QL_REQUIRE(nominal2.size() == leg2ResetDates.size(),
558 "nominal2 size is different from resetDates2 size");
559 QL_REQUIRE(nominal2.size() == leg2FixingDates.size(),
560 "nominal2 size is different from fixingDates2 size");
561 QL_REQUIRE(nominal2.size() == leg2PayDates.size(),
562 "nominal2 size is different from payDates2 size");
563 QL_REQUIRE(nominal2.size() == leg2Spreads.size(),
564 "nominal2 size is different from spreads2 size");
565 QL_REQUIRE(nominal2.size() == leg2Gearings.size(),
566 "nominal2 size is different from gearings2 size");
567 QL_REQUIRE(nominal2.size() == leg2CappedRates.size(),
568 "nominal2 size is different from cappedRates2 size");
569 QL_REQUIRE(nominal2.size() == leg2FlooredRates.size(),
570 "nominal2 size is different from flooredRates2 size");
571 QL_REQUIRE(nominal2.size() == leg2Coupons.size(),
572 "nominal2 size is different from coupons2 size");
573 QL_REQUIRE(nominal2.size() == leg2AccrualTimes.size(),
574 "nominal2 size is different from accrualTimes2 size");
575 QL_REQUIRE(nominal2.size() == leg2IsRedemptionFlow.size(),
576 "nominal2 size is different from redemption2 size");
577
578 QL_REQUIRE(index1 != nullptr, "index1 is null");
579 QL_REQUIRE(index2 != nullptr, "index2 is null");
580 }
581
583}
helper class building a sequence of capped/floored cms-rate coupons
Definition: cmscoupon.hpp:70
helper class building a sequence of capped/floored cms-spread-rate coupons
day counter class
Definition: daycounter.hpp:44
Base error class.
Definition: errors.hpp:39
Arguments for float float swap calculation
ext::shared_ptr< InterestRateIndex > index1
ext::shared_ptr< InterestRateIndex > index2
std::vector< Real > cappedRate2_
std::vector< Real > flooredRate2_
std::vector< Real > gearing2_
const Leg & leg2() const
const Leg & leg1() const
std::vector< Real > nominal1_
std::vector< Real > spread1_
std::vector< Real > cappedRate1_
BusinessDayConvention paymentConvention2() const
std::vector< Real > spread2_
const bool intermediateCapitalExchange_
std::vector< Real > nominal2_
std::vector< Real > gearing1_
BusinessDayConvention paymentConvention2_
void setupArguments(PricingEngine::arguments *args) const override
BusinessDayConvention paymentConvention1_
std::vector< Real > flooredRate1_
ext::shared_ptr< InterestRateIndex > index1_
void init(ext::optional< BusinessDayConvention > paymentConvention1, ext::optional< BusinessDayConvention > paymentConvention2)
void setupExpired() const override
ext::shared_ptr< InterestRateIndex > index2_
void fetchResults(const PricingEngine::results *) const override
FloatFloatSwap(Swap::Type type, Real nominal1, Real nominal2, const Schedule &schedule1, ext::shared_ptr< InterestRateIndex > index1, DayCounter dayCount1, const Schedule &schedule2, ext::shared_ptr< InterestRateIndex > index2, DayCounter dayCount2, bool intermediateCapitalExchange=false, bool finalCapitalExchange=false, Real gearing1=1.0, Real spread1=0.0, Real cappedRate1=Null< Real >(), Real flooredRate1=Null< Real >(), Real gearing2=1.0, Real spread2=0.0, Real cappedRate2=Null< Real >(), Real flooredRate2=Null< Real >(), const ext::optional< BusinessDayConvention > &paymentConvention1=ext::nullopt, const ext::optional< BusinessDayConvention > &paymentConvention2=ext::nullopt)
BusinessDayConvention paymentConvention1() const
helper class building a sequence of capped/floored ibor-rate coupons
Definition: iborcoupon.hpp:133
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
Bond redemption.
Payment schedule.
Definition: schedule.hpp:40
Size size() const
Definition: schedule.hpp:69
BusinessDayConvention businessDayConvention() const
Definition: schedule.hpp:196
void validate() const override
Definition: swap.cpp:171
void reset() override
Definition: swap.cpp:176
Interest rate swap.
Definition: swap.hpp:41
void setupArguments(PricingEngine::arguments *) const override
Definition: swap.cpp:87
std::vector< Leg > legs_
Definition: swap.hpp:133
const Leg & leg(Size j) const
Definition: swap.hpp:111
void setupExpired() const override
Definition: swap.cpp:78
void fetchResults(const PricingEngine::results *) const override
Definition: swap.cpp:95
std::vector< Real > payer_
Definition: swap.hpp:134
#define QL_EPSILON
Definition: qldefines.hpp:178
QL_REAL Real
real number
Definition: types.hpp:50
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
bool close(const Quantity &m1, const Quantity &m2, Size n)
Definition: quantity.cpp:163
std::vector< ext::shared_ptr< CashFlow > > Leg
Sequence of cash-flows.
Definition: cashflow.hpp:78
STL namespace.