1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2014 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/couponpricer.hpp>
21#include <ql/experimental/coupons/strippedcapflooredcoupon.hpp>
22#include <utility>
23
24namespace QuantLib {
25
26 StrippedCappedFlooredCoupon::StrippedCappedFlooredCoupon(
27 const ext::shared_ptr<CappedFlooredCoupon> &underlying)
28 : FloatingRateCoupon(
29 underlying->date(), underlying->nominal(),
30 underlying->accrualStartDate(), underlying->accrualEndDate(),
31 underlying->fixingDays(), underlying->index(),
32 underlying->gearing(), underlying->spread(),
33 underlying->referencePeriodStart(),
34 underlying->referencePeriodEnd(), underlying->dayCounter(),
35 underlying->isInArrears()),
36 underlying_(underlying) {
37 registerWith(h: underlying_);
38 }
39
40 void StrippedCappedFlooredCoupon::deepUpdate() {
41 update();
42 underlying_->deepUpdate();
43 }
44
45 void StrippedCappedFlooredCoupon::performCalculations() const {
46 QL_REQUIRE(underlying_->underlying()->pricer() != nullptr, "pricer not set");
47 underlying_->underlying()->pricer()->initialize(coupon: *underlying_->underlying());
48 Rate floorletRate = 0.0;
49 if (underlying_->isFloored())
50 floorletRate = underlying_->underlying()->pricer()->floorletRate(
51 effectiveFloor: underlying_->effectiveFloor());
52 Rate capletRate = 0.0;
53 if (underlying_->isCapped())
54 capletRate =
55 underlying_->underlying()->pricer()->capletRate(effectiveCap: underlying_->effectiveCap());
56
57 // if the underlying is collared we return the value of the embedded
58 // collar, otherwise the value of a long floor or a long cap respectively
59
60 rate_ = (underlying_->isFloored() && underlying_->isCapped()) ?
61 Real(floorletRate - capletRate) :
62 Real(floorletRate + capletRate);
63 }
64
65 Rate StrippedCappedFlooredCoupon::rate() const {
66 calculate();
67 return rate_;
68 }
69
70 Rate StrippedCappedFlooredCoupon::convexityAdjustment() const {
71 return underlying_->convexityAdjustment();
72 }
73
74 Rate StrippedCappedFlooredCoupon::cap() const { return underlying_->cap(); }
75
76 Rate StrippedCappedFlooredCoupon::floor() const {
77 return underlying_->floor();
78 }
79
80 Rate StrippedCappedFlooredCoupon::effectiveCap() const {
81 return underlying_->effectiveCap();
82 }
83
84 Rate StrippedCappedFlooredCoupon::effectiveFloor() const {
85 return underlying_->effectiveFloor();
86 }
87
88 void StrippedCappedFlooredCoupon::accept(AcyclicVisitor &v) {
89 underlying_->accept(v);
90 auto* v1 = dynamic_cast<Visitor<StrippedCappedFlooredCoupon>*>(&v);
91 if (v1 != nullptr)
92 v1->visit(*this);
93 else
94 FloatingRateCoupon::accept(v);
95 }
96
97 bool StrippedCappedFlooredCoupon::isCap() const {
98 return underlying_->isCapped();
99 }
100
101 bool StrippedCappedFlooredCoupon::isFloor() const {
102 return underlying_->isFloored();
103 }
104
105 bool StrippedCappedFlooredCoupon::isCollar() const {
106 return isCap() && isFloor();
107 }
108
109 void StrippedCappedFlooredCoupon::setPricer(
110 const ext::shared_ptr<FloatingRateCouponPricer> &pricer) {
111 FloatingRateCoupon::setPricer(pricer);
112 underlying_->setPricer(pricer);
113 }
114
115 StrippedCappedFlooredCouponLeg::StrippedCappedFlooredCouponLeg(Leg underlyingLeg)
116 : underlyingLeg_(std::move(underlyingLeg)) {}
117
118 StrippedCappedFlooredCouponLeg::operator Leg() const {
119 Leg resultLeg;
120 resultLeg.reserve(n: underlyingLeg_.size());
121 ext::shared_ptr<CappedFlooredCoupon> c;
122 for (const auto& i : underlyingLeg_) {
123 if ((c = ext::dynamic_pointer_cast<CappedFlooredCoupon>(r: i)) != nullptr) {
124 resultLeg.push_back(
125 x: ext::make_shared<StrippedCappedFlooredCoupon>(args&: c));
126 } else {
127 resultLeg.push_back(x: i);
128 }
129 }
130 return resultLeg;
131 }
132}
133

source code of quantlib/ql/experimental/coupons/strippedcapflooredcoupon.cpp