1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 
3 /*
4  Copyright (C) 2009 Chris Kenyon
5 
6  This file is part of QuantLib, a free-software/open-source library
7  for financial quantitative analysts and developers - http://quantlib.org/
8 
9  QuantLib is free software: you can redistribute it and/or modify it
10  under the terms of the QuantLib license.  You should have received a
11  copy of the license along with this program; if not, please email
12  <quantlib-dev@lists.sf.net>. The license is also available online at
13  <http://quantlib.org/license.shtml>.
14 
15  This program is distributed in the hope that it will be useful, but WITHOUT
16  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17  FOR A PARTICULAR PURPOSE.  See the license for more details.
18  */
19 
20 /*! \file inflationcouponpricer.hpp
21  \brief inflation-coupon pricers
22  */
23 
24 #ifndef quantlib_inflation_coupon_pricer_hpp
25 #define quantlib_inflation_coupon_pricer_hpp
26 
27 #include <ql/cashflow.hpp>
28 #include <ql/option.hpp>
29 #include <ql/cashflows/yoyinflationcoupon.hpp>
30 #include <ql/termstructures/volatility/inflation/yoyinflationoptionletvolatilitystructure.hpp>
31 
32 namespace QuantLib {
33 
34     //! Base inflation-coupon pricer.
35     /*! The main reason we can't use FloatingRateCouponPricer as the
36         base is that it takes a FloatingRateCoupon which takes an
37         InterestRateIndex and we need an inflation index (these are
38         lagged).
39 
40         The basic inflation-specific thing that the pricer has to do
41         is deal with different lags in the index and the option
42         e.g. the option could look 3 months back and the index 2.
43 
44         We add the requirement that pricers do inverseCap/Floor-lets.
45         These are cap/floor-lets as usually defined, i.e. pay out if
46         underlying is above/below a strike.  The non-inverse (usual)
47         versions are from a coupon point of view (a capped coupon has
48         a maximum at the strike).
49 
50         We add the inverse prices so that conventional caps can be
51         priced simply.
52     */
53     class InflationCouponPricer: public virtual Observer,
54                                  public virtual Observable {
55     public:
~InflationCouponPricer()56         virtual ~InflationCouponPricer() {}
57         //! \name Interface
58         //@{
59         virtual Real swapletPrice() const = 0;
60         virtual Rate swapletRate() const = 0;
61         virtual Real capletPrice(Rate effectiveCap) const = 0;
62         virtual Rate capletRate(Rate effectiveCap) const = 0;
63         virtual Real floorletPrice(Rate effectiveFloor) const = 0;
64         virtual Rate floorletRate(Rate effectiveFloor) const = 0;
65         virtual void initialize(const InflationCoupon&) = 0;
66         //@}
67 
68         //! \name Observer interface
69         //@{
update()70         virtual void update(){notifyObservers();}
71         //@}
72     protected:
73         Handle<YieldTermStructure> rateCurve_;
74         Date paymentDate_;
75     };
76 
77 
78     void setCouponPricer(const Leg& leg,
79                          const ext::shared_ptr<InflationCouponPricer>&);
80 
81 
82     //! base pricer for capped/floored YoY inflation coupons
83     /*! \note this pricer can already do swaplets but to get
84               volatility-dependent coupons you need the descendents.
85     */
86     class YoYInflationCouponPricer : public InflationCouponPricer {
87       public:
88         /*! \deprecated Use one of the other constructors.
89                         Deprecated in version 1.19.
90         */
91         QL_DEPRECATED
92         YoYInflationCouponPricer();
93 
94         explicit YoYInflationCouponPricer(
95             const Handle<YieldTermStructure>& nominalTermStructure);
96 
97         YoYInflationCouponPricer(
98             const Handle<YoYOptionletVolatilitySurface>& capletVol,
99             const Handle<YieldTermStructure>& nominalTermStructure);
100 
capletVolatility() const101         virtual Handle<YoYOptionletVolatilitySurface> capletVolatility() const{
102             return capletVol_;
103         }
104 
nominalTermStructure() const105         virtual Handle<YieldTermStructure> nominalTermStructure() const{
106             return nominalTermStructure_;
107         }
108 
109         virtual void setCapletVolatility(
110             const Handle<YoYOptionletVolatilitySurface>& capletVol);
111 
112         //! \name InflationCouponPricer interface
113         //@{
114         virtual Real swapletPrice() const;
115         virtual Rate swapletRate() const;
116         virtual Real capletPrice(Rate effectiveCap) const;
117         virtual Rate capletRate(Rate effectiveCap) const;
118         virtual Real floorletPrice(Rate effectiveFloor) const;
119         virtual Rate floorletRate(Rate effectiveFloor) const;
120         virtual void initialize(const InflationCoupon&);
121         //@}
122 
123       protected:
124         virtual Real optionletPrice(Option::Type optionType,
125                                     Real effStrike) const;
126         virtual Real optionletRate(Option::Type optionType,
127                                    Real effStrike) const;
128 
129         /*! Derived classes usually only need to implement this.
130 
131             The name of the method is misleading.  This actually
132             returns the rate of the optionlet (so not discounted and
133             not accrued).
134         */
135         virtual Real optionletPriceImp(Option::Type, Real strike,
136                                        Real forward, Real stdDev) const;
137         virtual Rate adjustedFixing(Rate fixing = Null<Rate>()) const;
138 
139         //! data
140         Handle<YoYOptionletVolatilitySurface> capletVol_;
141         Handle<YieldTermStructure> nominalTermStructure_;
142         const YoYInflationCoupon* coupon_;
143         Real gearing_;
144         Spread spread_;
145         Real discount_;
146     };
147 
148 
149     //! Black-formula pricer for capped/floored yoy inflation coupons
150     class BlackYoYInflationCouponPricer : public YoYInflationCouponPricer {
151       public:
152         /*! \deprecated Use one of the other constructors.
153                         Deprecated in version 1.19.
154         */
155         QL_DEPRECATED
BlackYoYInflationCouponPricer()156         BlackYoYInflationCouponPricer()
157         : YoYInflationCouponPricer(Handle<YoYOptionletVolatilitySurface>(),
158                                    Handle<YieldTermStructure>()) {}
159 
BlackYoYInflationCouponPricer(const Handle<YieldTermStructure> & nominalTermStructure)160         explicit BlackYoYInflationCouponPricer(
161             const Handle<YieldTermStructure>& nominalTermStructure)
162         : YoYInflationCouponPricer(nominalTermStructure) {}
163 
BlackYoYInflationCouponPricer(const Handle<YoYOptionletVolatilitySurface> & capletVol,const Handle<YieldTermStructure> & nominalTermStructure)164         BlackYoYInflationCouponPricer(
165             const Handle<YoYOptionletVolatilitySurface>& capletVol,
166             const Handle<YieldTermStructure>& nominalTermStructure)
167         : YoYInflationCouponPricer(capletVol, nominalTermStructure) {}
168       protected:
169         Real optionletPriceImp(Option::Type, Real strike,
170                                Real forward, Real stdDev) const;
171     };
172 
173 
174     //! Unit-Displaced-Black-formula pricer for capped/floored yoy inflation coupons
175     class UnitDisplacedBlackYoYInflationCouponPricer : public YoYInflationCouponPricer {
176       public:
177         /*! \deprecated Use one of the other constructors.
178                         Deprecated in version 1.19.
179         */
180         QL_DEPRECATED
UnitDisplacedBlackYoYInflationCouponPricer()181         UnitDisplacedBlackYoYInflationCouponPricer()
182         : YoYInflationCouponPricer(Handle<YoYOptionletVolatilitySurface>(),
183                                    Handle<YieldTermStructure>()) {}
184 
UnitDisplacedBlackYoYInflationCouponPricer(const Handle<YieldTermStructure> & nominalTermStructure)185         explicit UnitDisplacedBlackYoYInflationCouponPricer(
186             const Handle<YieldTermStructure>& nominalTermStructure)
187         : YoYInflationCouponPricer(nominalTermStructure) {}
188 
UnitDisplacedBlackYoYInflationCouponPricer(const Handle<YoYOptionletVolatilitySurface> & capletVol,const Handle<YieldTermStructure> & nominalTermStructure)189         UnitDisplacedBlackYoYInflationCouponPricer(
190             const Handle<YoYOptionletVolatilitySurface>& capletVol,
191             const Handle<YieldTermStructure>& nominalTermStructure)
192         : YoYInflationCouponPricer(capletVol, nominalTermStructure) {}
193       protected:
194         Real optionletPriceImp(Option::Type, Real strike,
195                                Real forward, Real stdDev) const;
196     };
197 
198 
199     //! Bachelier-formula pricer for capped/floored yoy inflation coupons
200     class BachelierYoYInflationCouponPricer : public YoYInflationCouponPricer {
201       public:
202         /*! \deprecated Use one of the other constructors.
203                         Deprecated in version 1.19.
204         */
205         QL_DEPRECATED
BachelierYoYInflationCouponPricer()206         BachelierYoYInflationCouponPricer()
207         : YoYInflationCouponPricer(Handle<YoYOptionletVolatilitySurface>(),
208                                    Handle<YieldTermStructure>()) {}
209 
BachelierYoYInflationCouponPricer(const Handle<YieldTermStructure> & nominalTermStructure)210         explicit BachelierYoYInflationCouponPricer(
211             const Handle<YieldTermStructure>& nominalTermStructure)
212         : YoYInflationCouponPricer(nominalTermStructure) {}
213 
BachelierYoYInflationCouponPricer(const Handle<YoYOptionletVolatilitySurface> & capletVol,const Handle<YieldTermStructure> & nominalTermStructure)214         BachelierYoYInflationCouponPricer(
215             const Handle<YoYOptionletVolatilitySurface>& capletVol,
216             const Handle<YieldTermStructure>& nominalTermStructure)
217         : YoYInflationCouponPricer(capletVol, nominalTermStructure) {}
218       protected:
219         Real optionletPriceImp(Option::Type, Real strike,
220                                Real forward, Real stdDev) const;
221     };
222 
223 }
224 
225 
226 #endif
227 
228 
229