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/floatingratecoupon.hpp>
26 #include <ql/cashflows/capflooredcoupon.hpp>
27 #include <ql/cashflows/couponpricer.hpp>
28 #include <ql/experimental/coupons/swapspreadindex.hpp>
29 #include <ql/time/schedule.hpp>
30 
31 namespace QuantLib {
32 
33     class SwapIndex;
34 
35     //! CMS spread coupon class
36     /*! \warning This class does not perform any date adjustment,
37                  i.e., the start and end date passed upon construction
38                  should be already rolled to a business day.
39     */
40     class CmsSpreadCoupon : public FloatingRateCoupon {
41       public:
42         CmsSpreadCoupon(const Date& paymentDate,
43                   Real nominal,
44                   const Date& startDate,
45                   const Date& endDate,
46                   Natural fixingDays,
47                   const ext::shared_ptr<SwapSpreadIndex>& index,
48                   Real gearing = 1.0,
49                   Spread spread = 0.0,
50                   const Date& refPeriodStart = Date(),
51                   const Date& refPeriodEnd = Date(),
52                   const DayCounter& dayCounter = DayCounter(),
53                   bool isInArrears = false,
54                   const Date& exCouponDate = Date());
55         //! \name Inspectors
56         //@{
swapSpreadIndex() const57         const ext::shared_ptr<SwapSpreadIndex>& swapSpreadIndex() const {
58             return index_;
59         }
60         //@}
61         //! \name Visitability
62         //@{
63         virtual void accept(AcyclicVisitor&);
64         //@}
65       private:
66         ext::shared_ptr<SwapSpreadIndex> index_;
67     };
68 
69     class CappedFlooredCmsSpreadCoupon : public CappedFlooredCoupon {
70       public:
CappedFlooredCmsSpreadCoupon(const Date & paymentDate,Real nominal,const Date & startDate,const Date & endDate,Natural fixingDays,const ext::shared_ptr<SwapSpreadIndex> & index,Real gearing=1.0,Spread spread=0.0,const Rate cap=Null<Rate> (),const Rate floor=Null<Rate> (),const Date & refPeriodStart=Date (),const Date & refPeriodEnd=Date (),const DayCounter & dayCounter=DayCounter (),bool isInArrears=false,const Date & exCouponDate=Date ())71         CappedFlooredCmsSpreadCoupon(
72                   const Date& paymentDate,
73                   Real nominal,
74                   const Date& startDate,
75                   const Date& endDate,
76                   Natural fixingDays,
77                   const ext::shared_ptr<SwapSpreadIndex>& index,
78                   Real gearing = 1.0,
79                   Spread spread= 0.0,
80                   const Rate cap = Null<Rate>(),
81                   const Rate floor = Null<Rate>(),
82                   const Date& refPeriodStart = Date(),
83                   const Date& refPeriodEnd = Date(),
84                   const DayCounter& dayCounter = DayCounter(),
85                   bool isInArrears = false,
86                   const Date& exCouponDate = Date())
87         : CappedFlooredCoupon(ext::shared_ptr<FloatingRateCoupon>(new
88             CmsSpreadCoupon(paymentDate, nominal, startDate, endDate, fixingDays,
89                       index, gearing, spread, refPeriodStart, refPeriodEnd,
90                       dayCounter, isInArrears, exCouponDate)), cap, floor) {}
91 
accept(AcyclicVisitor & v)92         virtual void accept(AcyclicVisitor& v) {
93             Visitor<CappedFlooredCmsSpreadCoupon>* v1 =
94                 dynamic_cast<Visitor<CappedFlooredCmsSpreadCoupon>*>(&v);
95             if (v1 != 0)
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(const Schedule& schedule,
106                const ext::shared_ptr<SwapSpreadIndex>& swapSpreadIndex);
107         CmsSpreadLeg& withNotionals(Real notional);
108         CmsSpreadLeg& withNotionals(const std::vector<Real>& notionals);
109         CmsSpreadLeg& withPaymentDayCounter(const DayCounter&);
110         CmsSpreadLeg& withPaymentAdjustment(BusinessDayConvention);
111         CmsSpreadLeg& withFixingDays(Natural fixingDays);
112         CmsSpreadLeg& withFixingDays(const std::vector<Natural>& fixingDays);
113         CmsSpreadLeg& withGearings(Real gearing);
114         CmsSpreadLeg& withGearings(const std::vector<Real>& gearings);
115         CmsSpreadLeg& withSpreads(Spread spread);
116         CmsSpreadLeg& withSpreads(const std::vector<Spread>& spreads);
117         CmsSpreadLeg& withCaps(Rate cap);
118         CmsSpreadLeg& withCaps(const std::vector<Rate>& caps);
119         CmsSpreadLeg& withFloors(Rate floor);
120         CmsSpreadLeg& withFloors(const std::vector<Rate>& floors);
121         CmsSpreadLeg& inArrears(bool flag = true);
122         CmsSpreadLeg& withZeroPayments(bool flag = true);
123         operator Leg() const;
124       private:
125         Schedule schedule_;
126         ext::shared_ptr<SwapSpreadIndex> swapSpreadIndex_;
127         std::vector<Real> notionals_;
128         DayCounter paymentDayCounter_;
129         BusinessDayConvention paymentAdjustment_;
130         std::vector<Natural> fixingDays_;
131         std::vector<Real> gearings_;
132         std::vector<Spread> spreads_;
133         std::vector<Rate> caps_, floors_;
134         bool inArrears_, zeroPayments_;
135     };
136 
137 
138     //! base pricer for vanilla CMS spread coupons
139     class CmsSpreadCouponPricer : public FloatingRateCouponPricer {
140       public:
CmsSpreadCouponPricer(const Handle<Quote> & correlation=Handle<Quote> ())141         explicit CmsSpreadCouponPricer(
142                            const Handle<Quote> &correlation = Handle<Quote>())
143         : correlation_(correlation) {
144             registerWith(correlation_);
145         }
146 
correlation() const147         Handle<Quote> correlation() const{
148             return correlation_;
149         }
150 
setCorrelation(const Handle<Quote> & correlation=Handle<Quote> ())151         void setCorrelation(
152                          const Handle<Quote> &correlation = Handle<Quote>()) {
153             unregisterWith(correlation_);
154             correlation_ = correlation;
155             registerWith(correlation_);
156             update();
157         }
158       private:
159         Handle<Quote> correlation_;
160     };
161 
162 }
163 
164 #endif
165