Coverage Report

Created: 2025-09-04 07:11

/src/quantlib/ql/experimental/coupons/cmsspreadcoupon.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 Copyright (C) 2014 Peter Caspers
3
4
 This file is part of QuantLib, a free-software/open-source library
5
 for financial quantitative analysts and developers - http://quantlib.org/
6
7
 QuantLib is free software: you can redistribute it and/or modify it
8
 under the terms of the QuantLib license.  You should have received a
9
 copy of the license along with this program; if not, please email
10
 <quantlib-dev@lists.sf.net>. The license is also available online at
11
 <https://www.quantlib.org/license.shtml>.
12
13
14
 This program is distributed in the hope that it will be useful, but
15
 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16
 or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */
17
18
/*! \file cmsspreadcoupon.hpp
19
    \brief CMS spread coupon
20
*/
21
22
#ifndef quantlib_cmsspread_coupon_hpp
23
#define quantlib_cmsspread_coupon_hpp
24
25
#include <ql/cashflows/capflooredcoupon.hpp>
26
#include <ql/cashflows/couponpricer.hpp>
27
#include <ql/cashflows/floatingratecoupon.hpp>
28
#include <ql/experimental/coupons/swapspreadindex.hpp>
29
#include <ql/time/schedule.hpp>
30
#include <utility>
31
32
namespace QuantLib {
33
34
    class SwapIndex;
35
36
    //! CMS spread coupon class
37
    /*! \warning This class does not perform any date adjustment,
38
                 i.e., the start and end date passed upon construction
39
                 should be already rolled to a business day.
40
    */
41
    class CmsSpreadCoupon : public FloatingRateCoupon {
42
      public:
43
        CmsSpreadCoupon(const Date& paymentDate,
44
                  Real nominal,
45
                  const Date& startDate,
46
                  const Date& endDate,
47
                  Natural fixingDays,
48
                  const ext::shared_ptr<SwapSpreadIndex>& index,
49
                  Real gearing = 1.0,
50
                  Spread spread = 0.0,
51
                  const Date& refPeriodStart = Date(),
52
                  const Date& refPeriodEnd = Date(),
53
                  const DayCounter& dayCounter = DayCounter(),
54
                  bool isInArrears = false,
55
                  const Date& exCouponDate = Date());
56
        //! \name Inspectors
57
        //@{
58
0
        const ext::shared_ptr<SwapSpreadIndex>& swapSpreadIndex() const {
59
0
            return index_;
60
0
        }
61
        //@}
62
        //! \name Visitability
63
        //@{
64
        void accept(AcyclicVisitor&) override;
65
        //@}
66
      private:
67
        ext::shared_ptr<SwapSpreadIndex> index_;
68
    };
69
70
    class CappedFlooredCmsSpreadCoupon : public CappedFlooredCoupon {
71
      public:
72
        CappedFlooredCmsSpreadCoupon(
73
                  const Date& paymentDate,
74
                  Real nominal,
75
                  const Date& startDate,
76
                  const Date& endDate,
77
                  Natural fixingDays,
78
                  const ext::shared_ptr<SwapSpreadIndex>& index,
79
                  Real gearing = 1.0,
80
                  Spread spread= 0.0,
81
                  const Rate cap = Null<Rate>(),
82
                  const Rate floor = Null<Rate>(),
83
                  const Date& refPeriodStart = Date(),
84
                  const Date& refPeriodEnd = Date(),
85
                  const DayCounter& dayCounter = DayCounter(),
86
                  bool isInArrears = false,
87
                  const Date& exCouponDate = Date())
88
0
        : CappedFlooredCoupon(ext::shared_ptr<FloatingRateCoupon>(new
89
0
            CmsSpreadCoupon(paymentDate, nominal, startDate, endDate, fixingDays,
90
0
                      index, gearing, spread, refPeriodStart, refPeriodEnd,
91
0
                      dayCounter, isInArrears, exCouponDate)), cap, floor) {}
92
93
0
        void accept(AcyclicVisitor& v) override {
94
0
            auto* v1 = dynamic_cast<Visitor<CappedFlooredCmsSpreadCoupon>*>(&v);
95
0
            if (v1 != nullptr)
96
0
                v1->visit(*this);
97
0
            else
98
0
                CappedFlooredCoupon::accept(v);
99
0
        }
100
    };
101
102
    //! helper class building a sequence of capped/floored cms-spread-rate coupons
103
    class CmsSpreadLeg {
104
      public:
105
        CmsSpreadLeg(Schedule schedule, ext::shared_ptr<SwapSpreadIndex> swapSpreadIndex);
106
        CmsSpreadLeg& withNotionals(Real notional);
107
        CmsSpreadLeg& withNotionals(const std::vector<Real>& notionals);
108
        CmsSpreadLeg& withPaymentDayCounter(const DayCounter&);
109
        CmsSpreadLeg& withPaymentAdjustment(BusinessDayConvention);
110
        CmsSpreadLeg& withFixingDays(Natural fixingDays);
111
        CmsSpreadLeg& withFixingDays(const std::vector<Natural>& fixingDays);
112
        CmsSpreadLeg& withGearings(Real gearing);
113
        CmsSpreadLeg& withGearings(const std::vector<Real>& gearings);
114
        CmsSpreadLeg& withSpreads(Spread spread);
115
        CmsSpreadLeg& withSpreads(const std::vector<Spread>& spreads);
116
        CmsSpreadLeg& withCaps(Rate cap);
117
        CmsSpreadLeg& withCaps(const std::vector<Rate>& caps);
118
        CmsSpreadLeg& withFloors(Rate floor);
119
        CmsSpreadLeg& withFloors(const std::vector<Rate>& floors);
120
        CmsSpreadLeg& inArrears(bool flag = true);
121
        CmsSpreadLeg& withZeroPayments(bool flag = true);
122
        operator Leg() const;
123
      private:
124
        Schedule schedule_;
125
        ext::shared_ptr<SwapSpreadIndex> swapSpreadIndex_;
126
        std::vector<Real> notionals_;
127
        DayCounter paymentDayCounter_;
128
        BusinessDayConvention paymentAdjustment_ = Following;
129
        std::vector<Natural> fixingDays_;
130
        std::vector<Real> gearings_;
131
        std::vector<Spread> spreads_;
132
        std::vector<Rate> caps_, floors_;
133
        bool inArrears_ = false, zeroPayments_ = false;
134
    };
135
136
137
    //! base pricer for vanilla CMS spread coupons
138
    class CmsSpreadCouponPricer : public FloatingRateCouponPricer {
139
      public:
140
        explicit CmsSpreadCouponPricer(Handle<Quote> correlation = Handle<Quote>())
141
0
        : correlation_(std::move(correlation)) {
142
0
            registerWith(correlation_);
143
0
        }
144
145
0
        Handle<Quote> correlation() const{
146
0
            return correlation_;
147
0
        }
148
149
        void setCorrelation(
150
0
                         const Handle<Quote> &correlation = Handle<Quote>()) {
151
0
            unregisterWith(correlation_);
152
0
            correlation_ = correlation;
153
0
            registerWith(correlation_);
154
0
            update();
155
0
        }
156
      private:
157
        Handle<Quote> correlation_;
158
    };
159
160
}
161
162
#endif