Coverage Report

Created: 2025-12-08 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/cashflows/capflooredcoupon.cpp
Line
Count
Source
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2006, 2007 Cristina Duminuco
5
 Copyright (C) 2006, 2009 StatPro Italia srl
6
 Copyright (C) 2007 Giorgio Facchinetti
7
8
 This file is part of QuantLib, a free-software/open-source library
9
 for financial quantitative analysts and developers - http://quantlib.org/
10
11
 QuantLib is free software: you can redistribute it and/or modify it
12
 under the terms of the QuantLib license.  You should have received a
13
 copy of the license along with this program; if not, please email
14
 <quantlib-dev@lists.sf.net>. The license is also available online at
15
 <https://www.quantlib.org/license.shtml>.
16
17
 This program is distributed in the hope that it will be useful, but WITHOUT
18
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19
 FOR A PARTICULAR PURPOSE.  See the license for more details.
20
*/
21
22
#include <ql/cashflows/capflooredcoupon.hpp>
23
#include <ql/cashflows/couponpricer.hpp>
24
25
namespace QuantLib {
26
27
    CappedFlooredCoupon::CappedFlooredCoupon(const ext::shared_ptr<FloatingRateCoupon>& underlying,
28
                                             Rate cap,
29
                                             Rate floor)
30
0
    : FloatingRateCoupon(underlying->date(),
31
0
                         underlying->nominal(),
32
0
                         underlying->accrualStartDate(),
33
0
                         underlying->accrualEndDate(),
34
0
                         underlying->fixingDays(),
35
0
                         underlying->index(),
36
0
                         underlying->gearing(),
37
0
                         underlying->spread(),
38
0
                         underlying->referencePeriodStart(),
39
0
                         underlying->referencePeriodEnd(),
40
0
                         underlying->dayCounter(),
41
0
                         underlying->isInArrears(),
42
0
                         underlying->exCouponDate()),
43
0
      underlying_(underlying) {
44
45
0
        if (gearing_ > 0) {
46
0
            if (cap != Null<Rate>()) {
47
0
                isCapped_ = true;
48
0
                cap_ = cap;
49
0
            }
50
0
            if (floor != Null<Rate>()) {
51
0
                floor_ = floor;
52
0
                isFloored_ = true;
53
0
            }
54
0
        } else {
55
0
              if (cap != Null<Rate>()){
56
0
                floor_ = cap;
57
0
                isFloored_ = true;
58
0
              }
59
0
              if (floor != Null<Rate>()){
60
0
                isCapped_ = true;
61
0
                cap_ = floor;
62
0
              }
63
0
        }
64
65
0
        if (isCapped_ && isFloored_) {
66
0
            QL_REQUIRE(cap >= floor,
67
0
                       "cap level (" << cap <<
68
0
                       ") less than floor level (" << floor << ")");
69
0
        }
70
71
0
        registerWith(underlying_);
72
0
    }
Unexecuted instantiation: QuantLib::CappedFlooredCoupon::CappedFlooredCoupon(boost::shared_ptr<QuantLib::FloatingRateCoupon> const&, double, double)
Unexecuted instantiation: QuantLib::CappedFlooredCoupon::CappedFlooredCoupon(boost::shared_ptr<QuantLib::FloatingRateCoupon> const&, double, double)
73
74
    void CappedFlooredCoupon::setPricer(
75
0
                 const ext::shared_ptr<FloatingRateCouponPricer>& pricer) {
76
0
        FloatingRateCoupon::setPricer(pricer);
77
0
        underlying_->setPricer(pricer);
78
0
    }
79
80
0
    void CappedFlooredCoupon::deepUpdate() {
81
0
        update();
82
0
        underlying_->deepUpdate();
83
0
    }
84
85
0
    void CappedFlooredCoupon::performCalculations() const {
86
0
        QL_REQUIRE(underlying_->pricer(), "pricer not set");
87
0
        Rate swapletRate = underlying_->rate();
88
0
        Rate floorletRate = 0.;
89
0
        if(isFloored_)
90
0
            floorletRate = underlying_->pricer()->floorletRate(effectiveFloor());
91
0
        Rate capletRate = 0.;
92
0
        if(isCapped_)
93
0
            capletRate = underlying_->pricer()->capletRate(effectiveCap());
94
0
        rate_ =  swapletRate + floorletRate - capletRate;
95
0
    }
96
97
0
    Rate CappedFlooredCoupon::rate() const {
98
0
        calculate();
99
0
        return rate_;
100
0
    }
101
102
0
    Rate CappedFlooredCoupon::convexityAdjustment() const {
103
0
        return underlying_->convexityAdjustment();
104
0
    }
105
106
0
    Rate CappedFlooredCoupon::cap() const {
107
0
        if ( (gearing_ > 0) && isCapped_)
108
0
                return cap_;
109
0
        if ( (gearing_ < 0) && isFloored_)
110
0
            return floor_;
111
0
        return Null<Rate>();
112
0
    }
113
114
0
    Rate CappedFlooredCoupon::floor() const {
115
0
        if ( (gearing_ > 0) && isFloored_)
116
0
            return floor_;
117
0
        if ( (gearing_ < 0) && isCapped_)
118
0
            return cap_;
119
0
        return Null<Rate>();
120
0
    }
121
122
0
    Rate CappedFlooredCoupon::effectiveCap() const {
123
0
        if (isCapped_)
124
0
            return (cap_ - spread())/gearing();
125
0
        else
126
0
            return Null<Rate>();
127
0
    }
128
129
0
    Rate CappedFlooredCoupon::effectiveFloor() const {
130
0
        if (isFloored_)
131
0
            return (floor_ - spread())/gearing();
132
0
        else
133
0
            return Null<Rate>();
134
0
    }
135
136
0
    void CappedFlooredCoupon::accept(AcyclicVisitor& v) {
137
0
        typedef FloatingRateCoupon super;
138
0
        auto* v1 = dynamic_cast<Visitor<CappedFlooredCoupon>*>(&v);
139
0
        if (v1 != nullptr)
140
0
            v1->visit(*this);
141
0
        else
142
0
            super::accept(v);
143
0
    }
144
145
}