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