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 <http://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
32namespace 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 const ext::shared_ptr<SwapSpreadIndex>& swapSpreadIndex() const {
59 return index_;
60 }
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 : CappedFlooredCoupon(ext::shared_ptr<FloatingRateCoupon>(new
89 CmsSpreadCoupon(paymentDate, nominal, startDate, endDate, fixingDays,
90 index, gearing, spread, refPeriodStart, refPeriodEnd,
91 dayCounter, isInArrears, exCouponDate)), cap, floor) {}
92
93 void accept(AcyclicVisitor& v) override {
94 auto* v1 = dynamic_cast<Visitor<CappedFlooredCmsSpreadCoupon>*>(&v);
95 if (v1 != nullptr)
96 v1->visit(*this);
97 else
98 CappedFlooredCoupon::accept(v);
99 }
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 : correlation_(std::move(correlation)) {
142 registerWith(h: correlation_);
143 }
144
145 Handle<Quote> correlation() const{
146 return correlation_;
147 }
148
149 void setCorrelation(
150 const Handle<Quote> &correlation = Handle<Quote>()) {
151 unregisterWith(h: correlation_);
152 correlation_ = correlation;
153 registerWith(h: correlation_);
154 update();
155 }
156 private:
157 Handle<Quote> correlation_;
158 };
159
160}
161
162#endif
163

source code of quantlib/ql/experimental/coupons/cmsspreadcoupon.hpp