1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 
3 /*
4  Copyright (C) 2008 Piero Del Boca
5  Copyright (C) 2009 Chris Kenyon
6  Copyright (C) 2015 Bernd Lewerenz
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 #ifndef quantlib_seasonality_hpp
23 #define quantlib_seasonality_hpp
24 
25 #include <ql/time/daycounter.hpp>
26 #include <ql/time/frequency.hpp>
27 #include <ql/shared_ptr.hpp>
28 #include <vector>
29 
30 namespace QuantLib {
31 
32     class InflationTermStructure;
33 
34     //! A transformation of an existing inflation swap rate.
35     /*! This is an abstract class and contains the functions
36         correctXXXRate which returns rates with the seasonality
37         correction.  Currently only the price multiplicative version
38         is implemented, but this covers stationary (1-year) and
39         non-stationary (multi-year) seasonality depending on how many
40         years of factors are given.  Seasonality is piecewise
41         constant, hence it will work with un-interpolated inflation
42         indices.
43 
44         A seasonality assumption can be used to fill in inflation swap
45         curves between maturities that are usually given in integer
46         numbers of years, e.g. 8,9,10,15,20, etc.  Historical
47         seasonality may be observed in reported CPI values,
48         alternatively it may be affected by known future events, e.g.
49         announced changes in VAT rates.  Thus seasonality may be
50         stationary or non-stationary.
51 
52         If seasonality is additive then both swap rates will show
53         affects.  Additive seasonality is not implemented.
54     */
55     class Seasonality {
56 
57         public:
58 
59         //! \name Seasonality interface
60         //@{
61           virtual Rate
62           correctZeroRate(const Date& d, Rate r, const InflationTermStructure& iTS) const = 0;
63           virtual Rate
64           correctYoYRate(const Date& d, Rate r, const InflationTermStructure& iTS) const = 0;
65           /*! It is possible for multi-year seasonalities to be
66               inconsistent with the inflation term structure they are
67               given to.  This method enables testing - but programmers
68               are not required to implement it.  E.g. for price
69               seasonality the corrections at whole years after the
70               inflation curve base date should be the same or else there
71               can be an inconsistency with quoted instruments.
72               Alternatively, the seasonality can be set _before_ the
73               inflation curve is bootstrapped.
74           */
75           virtual bool isConsistent(const InflationTermStructure& iTS) const;
76           //@}
77 
~Seasonality()78           virtual ~Seasonality() {}
79     };
80 
81     //! Multiplicative seasonality in the price index (CPI/RPI/HICP/etc).
82 
83     /*! Stationary multiplicative seasonality in CPI/RPI/HICP (i.e. in
84         price) implies that zero inflation swap rates are affected,
85         but that year-on-year inflation swap rates show no effect.  Of
86         course, if the seasonality in CPI/RPI/HICP is non-stationary
87         then both swap rates will be affected.
88 
89         Factors must be in multiples of the minimum required for one
90         year, e.g. 12 for monthly, and these factors are reused for as
91         long as is required, i.e. they wrap around.  So, for example,
92         if 24 factors are given this repeats every two years.  True
93         stationary seasonality can be obtained by giving the same
94         number of factors as the frequency dictates e.g. 12 for
95         monthly seasonality.
96 
97         \warning Multi-year seasonality (i.e. non-stationary) is
98                  fragile: the user <b>must</b> ensure that corrections
99                  at whole years before and after the inflation term
100                  structure base date are the same.  Otherwise there
101                  can be an inconsistency with quoted rates.  This is
102                  enforced if the frequency is lower than daily.  This
103                  is not enforced for daily seasonality because this
104                  will always be inconsistent due to weekends,
105                  holidays, leap years, etc.  If you use multi-year
106                  daily seasonality it is up to you to check.
107 
108         \note Factors are normalized relative to their appropriate
109               reference dates.  For zero inflation this is the
110               inflation curve true base date: since you have a fixing
111               for that date the seasonality factor must be one.  For
112               YoY inflation the reference is always one year earlier.
113 
114         Seasonality is treated as piecewise constant, hence it works
115         correctly with uninterpolated indices if the seasonality
116         correction factor frequency is the same as the index frequency
117         (or less).
118     */
119     class MultiplicativePriceSeasonality : public Seasonality {
120 
121         private:
122             Date seasonalityBaseDate_;
123             Frequency frequency_;
124             std::vector<Rate> seasonalityFactors_;
125 
126         public:
127 
128             //Constructors
129             //
130             MultiplicativePriceSeasonality();
131 
132             MultiplicativePriceSeasonality(const Date& seasonalityBaseDate,
133                                            Frequency frequency,
134                                            const std::vector<Rate>& seasonalityFactors);
135 
136             virtual void set(const Date& seasonalityBaseDate,
137                              Frequency frequency,
138                              const std::vector<Rate>& seasonalityFactors);
139 
140             //! inspectors
141             //@{
142             virtual Date seasonalityBaseDate() const;
143             virtual Frequency frequency() const;
144             virtual std::vector<Rate> seasonalityFactors() const;
145             //! The factor returned is NOT normalized relative to ANYTHING.
146             virtual Rate seasonalityFactor(const Date &d) const;
147             //@}
148 
149             //! \name Seasonality interface
150             //@{
151             virtual Rate
152             correctZeroRate(const Date& d, Rate r, const InflationTermStructure& iTS) const;
153             virtual Rate
154             correctYoYRate(const Date& d, Rate r, const InflationTermStructure& iTS) const;
155             virtual bool isConsistent(const InflationTermStructure& iTS) const;
156             //@}
157 
158             //Destructor
~MultiplicativePriceSeasonality()159             virtual ~MultiplicativePriceSeasonality() {};
160 
161         protected:
162             virtual void validate() const;
163             virtual Rate seasonalityCorrection(Rate r, const Date &d, const DayCounter &dc,
164                                                const Date &curveBaseDate, bool isZeroRate) const;
165     };
166 
167 
168     class KerkhofSeasonality : public MultiplicativePriceSeasonality {
169       public:
KerkhofSeasonality(const Date & seasonalityBaseDate,const std::vector<Rate> & seasonalityFactors)170         KerkhofSeasonality(const Date& seasonalityBaseDate,
171                            const std::vector<Rate>& seasonalityFactors)
172         : MultiplicativePriceSeasonality(seasonalityBaseDate,Monthly,
173                                          seasonalityFactors) {}
174 
175         /*Rate correctZeroRate(const Date &d, const Rate r,
176                                const InflationTermStructure& iTS) const;*/
177         Real seasonalityFactor(const Date &to) const;
178       protected:
179         virtual Rate seasonalityCorrection(Rate rate,
180                                            const Date& atDate,
181                                            const DayCounter& dc,
182                                            const Date& curveBaseDate,
183                                            bool isZeroRate) const;
184     };
185 
186 }  // end of namespace QuantLib
187 
188 #endif
189 
190