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