1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 3 /* 4 Copyright (C) 2007, 2009, 2011 Chris Kenyon 5 Copyright (C) 2009 StatPro Italia srl 6 7 This file is part of QuantLib, a free-software/open-source library 8 for financial quantitative analysts and developers - http://quantlib.org/ 9 10 QuantLib is free software: you can redistribute it and/or modify it 11 under the terms of the QuantLib license. You should have received a 12 copy of the license along with this program; if not, please email 13 <quantlib-dev@lists.sf.net>. The license is also available online at 14 <http://quantlib.org/license.shtml>. 15 16 This program is distributed in the hope that it will be useful, but WITHOUT 17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 18 FOR A PARTICULAR PURPOSE. See the license for more details. 19 */ 20 21 /*! \file cpiswap.hpp 22 \brief zero-inflation-indexed-ratio-with-base swap 23 */ 24 25 #ifndef quantlib_zeroinflationswap_hpp 26 #define quantlib_zeroinflationswap_hpp 27 28 #include <ql/instruments/swap.hpp> 29 #include <ql/time/calendar.hpp> 30 #include <ql/time/daycounter.hpp> 31 #include <ql/time/schedule.hpp> 32 #include <ql/indexes/iborindex.hpp> 33 #include <ql/cashflows/cpicoupon.hpp> 34 35 namespace QuantLib { 36 37 class ZeroInflationIndex; 38 39 //! zero-inflation-indexed swap, 40 /*! fixed x zero-inflation, i.e. fixed x CPI(i'th fixing)/CPI(base) 41 versus floating + spread 42 43 Note that this does ony the inflation-vs-floating-leg. 44 Extension to inflation-vs-fixed-leg. is simple - just replace 45 the floating leg with a fixed leg. 46 47 Typically there are notional exchanges at the end: either 48 inflated-notional vs notional; or just (inflated-notional - 49 notional) vs zero. The latter is perhaphs more typical. 50 \warning Setting subtractInflationNominal to true means that 51 the original inflation nominal is subtracted from both 52 nominals before they are exchanged, even if they are 53 different. 54 55 This swap can mimic a ZCIIS where [(1+q)^n - 1] is exchanged 56 against (cpi ratio - 1), by using differnt nominals on each 57 leg and setting subtractInflationNominal to true. ALSO - 58 there must be just one date in each schedule. 59 60 The two legs can have different schedules, fixing (days vs 61 lag), settlement, and roll conventions. N.B. accrual 62 adjustment periods are already in the schedules. Trade date 63 and swap settlement date are outside the scope of the 64 instrument. 65 */ 66 class CPISwap : public Swap { 67 public: 68 enum Type { Receiver = -1, Payer = 1 }; 69 class arguments; 70 class results; 71 class engine; 72 73 CPISwap(Type type, 74 Real nominal, 75 bool subtractInflationNominal, 76 // float+spread leg 77 Spread spread, 78 const DayCounter& floatDayCount, 79 const Schedule& floatSchedule, 80 const BusinessDayConvention& floatRoll, 81 Natural fixingDays, 82 const ext::shared_ptr<IborIndex>& floatIndex, 83 // fixed x inflation leg 84 Rate fixedRate, 85 Real baseCPI, 86 const DayCounter& fixedDayCount, 87 const Schedule& fixedSchedule, 88 const BusinessDayConvention& fixedRoll, 89 const Period& observationLag, 90 const ext::shared_ptr<ZeroInflationIndex>& fixedIndex, 91 CPI::InterpolationType observationInterpolation = CPI::AsIndex, 92 Real inflationNominal = Null<Real>() 93 ); 94 95 // results 96 // float+spread 97 virtual Real floatLegNPV() const; 98 virtual Spread fairSpread() const; 99 // fixed rate x inflation 100 virtual Real fixedLegNPV() const; 101 virtual Rate fairRate() const; 102 103 // inspectors 104 virtual Type type() const; 105 virtual Real nominal() const; 106 virtual bool subtractInflationNominal() const; 107 108 // float+spread 109 virtual Spread spread() const; 110 virtual const DayCounter& floatDayCount() const; 111 virtual const Schedule& floatSchedule() const; 112 virtual const BusinessDayConvention& floatPaymentRoll() const; 113 virtual Natural fixingDays() const; 114 virtual const ext::shared_ptr<IborIndex>& floatIndex() const; 115 116 // fixed rate x inflation 117 virtual Rate fixedRate() const; 118 virtual Real baseCPI() const; 119 virtual const DayCounter& fixedDayCount() const; 120 virtual const Schedule& fixedSchedule() const; 121 virtual const BusinessDayConvention& fixedPaymentRoll() const; 122 virtual Period observationLag() const; 123 virtual const ext::shared_ptr<ZeroInflationIndex>& fixedIndex() const; 124 virtual CPI::InterpolationType observationInterpolation() const; 125 virtual Real inflationNominal() const; 126 127 // legs 128 virtual const Leg& cpiLeg() const; 129 virtual const Leg& floatLeg() const; 130 131 // other 132 void setupArguments(PricingEngine::arguments* args) const; 133 void fetchResults(const PricingEngine::results*) const; 134 135 private: 136 void setupExpired() const; 137 138 Type type_; 139 Real nominal_; 140 bool subtractInflationNominal_; 141 142 // float+spread leg 143 Spread spread_; 144 DayCounter floatDayCount_; 145 Schedule floatSchedule_; 146 BusinessDayConvention floatPaymentRoll_; 147 Natural fixingDays_; 148 ext::shared_ptr<IborIndex> floatIndex_; 149 150 // fixed x inflation leg 151 Rate fixedRate_; 152 Real baseCPI_; 153 DayCounter fixedDayCount_; 154 Schedule fixedSchedule_; 155 BusinessDayConvention fixedPaymentRoll_; 156 ext::shared_ptr<ZeroInflationIndex> fixedIndex_; 157 Period observationLag_; 158 CPI::InterpolationType observationInterpolation_; 159 Real inflationNominal_; 160 // results 161 mutable Spread fairSpread_; 162 mutable Rate fairRate_; 163 164 }; 165 166 167 //! %Arguments for swap calculation 168 class CPISwap::arguments : public Swap::arguments { 169 public: arguments()170 arguments() : type(Receiver), 171 nominal(Null<Real>()) {} 172 Type type; 173 Real nominal; 174 175 void validate() const; 176 }; 177 178 //! %Results from swap calculation 179 class CPISwap::results : public Swap::results { 180 public: 181 Rate fairRate; 182 Spread fairSpread; 183 void reset(); 184 }; 185 186 class CPISwap::engine : public GenericEngine<CPISwap::arguments, 187 CPISwap::results> {}; 188 189 190 // inline definitions 191 192 // inspectors type() const193 inline CPISwap::Type CPISwap::type() const { return type_; } nominal() const194 inline Real CPISwap::nominal() const { return nominal_; } subtractInflationNominal() const195 inline bool CPISwap::subtractInflationNominal() const { return subtractInflationNominal_; } 196 197 // float+spread spread() const198 inline Spread CPISwap::spread() const { return spread_; } floatDayCount() const199 inline const DayCounter& CPISwap::floatDayCount() const { return floatDayCount_; } floatSchedule() const200 inline const Schedule& CPISwap::floatSchedule() const { return floatSchedule_; } floatPaymentRoll() const201 inline const BusinessDayConvention& CPISwap::floatPaymentRoll() const { return floatPaymentRoll_; } fixingDays() const202 inline Natural CPISwap::fixingDays() const { return fixingDays_; } floatIndex() const203 inline const ext::shared_ptr<IborIndex>& CPISwap::floatIndex() const { return floatIndex_; } 204 205 // fixed rate x inflation fixedRate() const206 inline Rate CPISwap::fixedRate() const { return fixedRate_; } baseCPI() const207 inline Real CPISwap::baseCPI() const { return baseCPI_; } fixedDayCount() const208 inline const DayCounter& CPISwap::fixedDayCount() const { return fixedDayCount_; } fixedSchedule() const209 inline const Schedule& CPISwap::fixedSchedule() const { return fixedSchedule_; } fixedPaymentRoll() const210 inline const BusinessDayConvention& CPISwap::fixedPaymentRoll() const { return fixedPaymentRoll_; } observationLag() const211 inline Period CPISwap::observationLag() const { return observationLag_; } fixedIndex() const212 inline const ext::shared_ptr<ZeroInflationIndex>& CPISwap::fixedIndex() const { return fixedIndex_; } observationInterpolation() const213 inline CPI::InterpolationType CPISwap::observationInterpolation() const { return observationInterpolation_; } inflationNominal() const214 inline Real CPISwap::inflationNominal() const { return inflationNominal_; } 215 cpiLeg() const216 inline const Leg& CPISwap::cpiLeg() const {//inflation indexed 217 return legs_[0]; 218 } 219 floatLeg() const220 inline const Leg& CPISwap::floatLeg() const { 221 return legs_[1]; 222 } 223 224 std::ostream& operator<<(std::ostream& out, CPISwap::Type t); 225 226 } 227 228 #endif 229 230