1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 3 /* 4 5 Copyright (C) 2006, 2007 Giorgio Facchinetti 6 Copyright (C) 2006, 2007 Mario Pucci 7 8 This file is part of QuantLib, a free-software/open-source library 9 for financial quantitative analysts and developers - http://quantlib.org/ 10 11 QuantLib is free software: you can redistribute it and/or modify it 12 under the terms of the QuantLib license. You should have received a 13 copy of the license along with this program; if not, please email 14 <quantlib-dev@lists.sf.net>. The license is also available online at 15 <http://quantlib.org/license.shtml>. 16 17 This program is distributed in the hope that it will be useful, but WITHOUT 18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 19 FOR A PARTICULAR PURPOSE. See the license for more details. 20 */ 21 22 /*! \file rangeaccrual.hpp 23 \brief range-accrual coupon 24 */ 25 26 #ifndef quantlib_range_accrual_h 27 #define quantlib_range_accrual_h 28 29 #include <ql/termstructures/volatility/smilesection.hpp> 30 #include <ql/cashflows/couponpricer.hpp> 31 #include <ql/cashflows/floatingratecoupon.hpp> 32 #include <ql/time/schedule.hpp> 33 #include <vector> 34 35 namespace QuantLib { 36 37 class IborIndex; 38 class RangeAccrualPricer; 39 40 class RangeAccrualFloatersCoupon: public FloatingRateCoupon { 41 42 public: 43 44 RangeAccrualFloatersCoupon( 45 const Date& paymentDate, 46 Real nominal, 47 const ext::shared_ptr<IborIndex>& index, 48 const Date& startDate, 49 const Date& endDate, 50 Natural fixingDays, 51 const DayCounter& dayCounter, 52 Real gearing, 53 Rate spread, 54 const Date& refPeriodStart, 55 const Date& refPeriodEnd, 56 const ext::shared_ptr<Schedule>& observationsSchedule, 57 Real lowerTrigger, 58 Real upperTrigger); 59 startTime() const60 Real startTime() const {return startTime_; } endTime() const61 Real endTime() const {return endTime_; } lowerTrigger() const62 Real lowerTrigger() const {return lowerTrigger_; } upperTrigger() const63 Real upperTrigger() const {return upperTrigger_; } observationsNo() const64 Size observationsNo() const {return observationsNo_; } observationDates() const65 const std::vector<Date>& observationDates() const { 66 return observationDates_; 67 } observationTimes() const68 const std::vector<Real>& observationTimes() const { 69 return observationTimes_; 70 } observationsSchedule() const71 ext::shared_ptr<Schedule> observationsSchedule() const { return observationsSchedule_; } 72 73 Real priceWithoutOptionality( 74 const Handle<YieldTermStructure>& discountCurve) const; 75 //! \name Visitability 76 //@{ 77 virtual void accept(AcyclicVisitor&); 78 //@} 79 private: 80 81 Real startTime_; // S 82 Real endTime_; // T 83 84 const ext::shared_ptr<Schedule> observationsSchedule_; 85 std::vector<Date> observationDates_; 86 std::vector<Real> observationTimes_; 87 Size observationsNo_; 88 89 Real lowerTrigger_; 90 Real upperTrigger_; 91 }; 92 93 class RangeAccrualPricer: public FloatingRateCouponPricer { 94 public: 95 //! \name Observer interface 96 //@{ 97 virtual Rate swapletRate() const; 98 virtual Real capletPrice(Rate effectiveCap) const; 99 virtual Rate capletRate(Rate effectiveCap) const; 100 virtual Real floorletPrice(Rate effectiveFloor) const; 101 virtual Rate floorletRate(Rate effectiveFloor) const; 102 void initialize(const FloatingRateCoupon& coupon); 103 //@} 104 105 protected: 106 const RangeAccrualFloatersCoupon* coupon_; 107 Real startTime_; // S 108 Real endTime_; // T 109 Real accrualFactor_; // T-S 110 std::vector<Real> observationTimeLags_; // d 111 std::vector<Real> observationTimes_; // U 112 std::vector<Real> initialValues_; 113 Size observationsNo_; 114 Real lowerTrigger_; 115 Real upperTrigger_; 116 Real discount_; 117 Real gearing_; 118 Spread spread_; 119 Real spreadLegValue_; 120 121 }; 122 123 class RangeAccrualPricerByBgm : public RangeAccrualPricer { 124 125 public: 126 RangeAccrualPricerByBgm( 127 Real correlation, 128 const ext::shared_ptr<SmileSection>& smilesOnExpiry, 129 const ext::shared_ptr<SmileSection>& smilesOnPayment, 130 bool withSmile, 131 bool byCallSpread); 132 //! \name Observer interface 133 //@{ 134 virtual Real swapletPrice() const; 135 //@} 136 137 protected: 138 139 Real drift(Real U, Real lambdaS, Real lambdaT, Real correlation) const; 140 Real derDriftDerLambdaS(Real U, Real lambdaS, Real lambdaT, 141 Real correlation) const; 142 Real derDriftDerLambdaT(Real U, Real lambdaS, Real lambdaT, 143 Real correlation) const; 144 145 Real lambda(Real U, Real lambdaS, Real lambdaT) const; 146 Real derLambdaDerLambdaS(Real U) const; 147 Real derLambdaDerLambdaT(Real U) const; 148 149 std::vector<Real> driftsOverPeriod(Real U, Real lambdaS, Real lambdaT, 150 Real correlation) const; 151 std::vector<Real> lambdasOverPeriod(Real U, Real lambdaS, 152 Real lambdaT) const; 153 154 Real digitalRangePrice(Real lowerTrigger, 155 Real upperTrigger, 156 Real initialValue, 157 Real expiry, 158 Real deflator) const; 159 160 Real digitalPrice(Real strike, 161 Real initialValue, 162 Real expiry, 163 Real deflator) const; 164 165 Real digitalPriceWithoutSmile(Real strike, 166 Real initialValue, 167 Real expiry, 168 Real deflator) const; 169 170 Real digitalPriceWithSmile(Real strike, 171 Real initialValue, 172 Real expiry, 173 Real deflator) const; 174 175 Real callSpreadPrice(Real previousInitialValue, 176 Real nextInitialValue, 177 Real previousStrike, 178 Real nextStrike, 179 Real deflator, 180 Real previousVariance, 181 Real nextVariance) const; 182 183 Real smileCorrection(Real strike, 184 Real initialValue, 185 Real expiry, 186 Real deflator) const; 187 188 private: 189 Real correlation_; // correlation between L(S) and L(T) 190 bool withSmile_; 191 bool byCallSpread_; 192 193 ext::shared_ptr<SmileSection> smilesOnExpiry_; 194 ext::shared_ptr<SmileSection> smilesOnPayment_; 195 Real eps_; 196 }; 197 198 199 //! helper class building a sequence of range-accrual floating-rate coupons 200 class RangeAccrualLeg { 201 public: 202 RangeAccrualLeg(const Schedule& schedule, 203 const ext::shared_ptr<IborIndex>& index); 204 RangeAccrualLeg& withNotionals(Real notional); 205 RangeAccrualLeg& withNotionals(const std::vector<Real>& notionals); 206 RangeAccrualLeg& withPaymentDayCounter(const DayCounter&); 207 RangeAccrualLeg& withPaymentAdjustment(BusinessDayConvention); 208 RangeAccrualLeg& withFixingDays(Natural fixingDays); 209 RangeAccrualLeg& withFixingDays(const std::vector<Natural>& fixingDays); 210 RangeAccrualLeg& withGearings(Real gearing); 211 RangeAccrualLeg& withGearings(const std::vector<Real>& gearings); 212 RangeAccrualLeg& withSpreads(Spread spread); 213 RangeAccrualLeg& withSpreads(const std::vector<Spread>& spreads); 214 RangeAccrualLeg& withLowerTriggers(Rate trigger); 215 RangeAccrualLeg& withLowerTriggers(const std::vector<Rate>& triggers); 216 RangeAccrualLeg& withUpperTriggers(Rate trigger); 217 RangeAccrualLeg& withUpperTriggers(const std::vector<Rate>& triggers); 218 RangeAccrualLeg& withObservationTenor(const Period&); 219 RangeAccrualLeg& withObservationConvention(BusinessDayConvention); 220 operator Leg() const; 221 private: 222 Schedule schedule_; 223 ext::shared_ptr<IborIndex> index_; 224 std::vector<Real> notionals_; 225 DayCounter paymentDayCounter_; 226 BusinessDayConvention paymentAdjustment_; 227 std::vector<Natural> fixingDays_; 228 std::vector<Real> gearings_; 229 std::vector<Spread> spreads_; 230 std::vector<Rate> lowerTriggers_, upperTriggers_; 231 Period observationTenor_; 232 BusinessDayConvention observationConvention_; 233 }; 234 235 } 236 237 238 #endif 239