Coverage Report

Created: 2025-11-04 06:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/experimental/coupons/strippedcapflooredcoupon.cpp
Line
Count
Source
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
 <https://www.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
24
namespace QuantLib {
25
26
    StrippedCappedFlooredCoupon::StrippedCappedFlooredCoupon(
27
        const ext::shared_ptr<CappedFlooredCoupon> &underlying)
28
0
        : FloatingRateCoupon(
29
0
              underlying->date(), underlying->nominal(),
30
0
              underlying->accrualStartDate(), underlying->accrualEndDate(),
31
0
              underlying->fixingDays(), underlying->index(),
32
0
              underlying->gearing(), underlying->spread(),
33
0
              underlying->referencePeriodStart(),
34
0
              underlying->referencePeriodEnd(), underlying->dayCounter(),
35
0
              underlying->isInArrears()),
36
0
          underlying_(underlying) {
37
0
        registerWith(underlying_);
38
0
    }
Unexecuted instantiation: QuantLib::StrippedCappedFlooredCoupon::StrippedCappedFlooredCoupon(boost::shared_ptr<QuantLib::CappedFlooredCoupon> const&)
Unexecuted instantiation: QuantLib::StrippedCappedFlooredCoupon::StrippedCappedFlooredCoupon(boost::shared_ptr<QuantLib::CappedFlooredCoupon> const&)
39
40
0
    void StrippedCappedFlooredCoupon::deepUpdate() {
41
0
        update();
42
0
        underlying_->deepUpdate();
43
0
    }
44
45
0
    void StrippedCappedFlooredCoupon::performCalculations() const {
46
0
        QL_REQUIRE(underlying_->underlying()->pricer() != nullptr, "pricer not set");
47
0
        underlying_->underlying()->pricer()->initialize(*underlying_->underlying());
48
0
        Rate floorletRate = 0.0;
49
0
        if (underlying_->isFloored())
50
0
            floorletRate = underlying_->underlying()->pricer()->floorletRate(
51
0
                underlying_->effectiveFloor());
52
0
        Rate capletRate = 0.0;
53
0
        if (underlying_->isCapped())
54
0
            capletRate =
55
0
                underlying_->underlying()->pricer()->capletRate(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
0
        rate_ = (underlying_->isFloored() && underlying_->isCapped()) ?
61
0
                    Real(floorletRate - capletRate) :
62
0
                    Real(floorletRate + capletRate);
63
0
    }
64
65
0
    Rate StrippedCappedFlooredCoupon::rate() const {
66
0
        calculate();
67
0
        return rate_;
68
0
    }
69
70
0
    Rate StrippedCappedFlooredCoupon::convexityAdjustment() const {
71
0
        return underlying_->convexityAdjustment();
72
0
    }
73
74
0
    Rate StrippedCappedFlooredCoupon::cap() const { return underlying_->cap(); }
75
76
0
    Rate StrippedCappedFlooredCoupon::floor() const {
77
0
        return underlying_->floor();
78
0
    }
79
80
0
    Rate StrippedCappedFlooredCoupon::effectiveCap() const {
81
0
        return underlying_->effectiveCap();
82
0
    }
83
84
0
    Rate StrippedCappedFlooredCoupon::effectiveFloor() const {
85
0
        return underlying_->effectiveFloor();
86
0
    }
87
88
0
    void StrippedCappedFlooredCoupon::accept(AcyclicVisitor &v) {
89
0
        underlying_->accept(v);
90
0
        auto* v1 = dynamic_cast<Visitor<StrippedCappedFlooredCoupon>*>(&v);
91
0
        if (v1 != nullptr)
92
0
            v1->visit(*this);
93
0
        else
94
0
            FloatingRateCoupon::accept(v);
95
0
    }
96
97
0
    bool StrippedCappedFlooredCoupon::isCap() const {
98
0
        return underlying_->isCapped();
99
0
    }
100
101
0
    bool StrippedCappedFlooredCoupon::isFloor() const {
102
0
        return underlying_->isFloored();
103
0
    }
104
105
0
    bool StrippedCappedFlooredCoupon::isCollar() const {
106
0
        return isCap() && isFloor();
107
0
    }
108
109
    void StrippedCappedFlooredCoupon::setPricer(
110
0
        const ext::shared_ptr<FloatingRateCouponPricer> &pricer) {
111
0
        FloatingRateCoupon::setPricer(pricer);
112
0
        underlying_->setPricer(pricer);
113
0
    }
114
115
    StrippedCappedFlooredCouponLeg::StrippedCappedFlooredCouponLeg(Leg underlyingLeg)
116
0
    : underlyingLeg_(std::move(underlyingLeg)) {}
117
118
0
    StrippedCappedFlooredCouponLeg::operator Leg() const {
119
0
        Leg resultLeg;
120
0
        resultLeg.reserve(underlyingLeg_.size());
121
0
        ext::shared_ptr<CappedFlooredCoupon> c;
122
0
        for (const auto& i : underlyingLeg_) {
123
0
            if ((c = ext::dynamic_pointer_cast<CappedFlooredCoupon>(i)) != nullptr) {
124
0
                resultLeg.push_back(
125
0
                    ext::make_shared<StrippedCappedFlooredCoupon>(c));
126
0
            } else {
127
0
                resultLeg.push_back(i);
128
0
            }
129
0
        }
130
0
        return resultLeg;
131
0
    }
132
}