1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 
3 /*
4  Copyright (C) 2005, 2006, 2007, 2008 StatPro Italia srl
5  Copyright (C) 2007, 2009, 2015 Ferdinando Ametrano
6  Copyright (C) 2015 Paolo Mazzocchi
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 bootstraphelper.hpp
23     \brief base helper class used for bootstrapping
24 */
25 
26 #ifndef quantlib_bootstrap_helper_hpp
27 #define quantlib_bootstrap_helper_hpp
28 
29 #include <ql/quote.hpp>
30 #include <ql/time/date.hpp>
31 #include <ql/handle.hpp>
32 #include <ql/patterns/observable.hpp>
33 #include <ql/patterns/visitor.hpp>
34 #include <ql/quotes/simplequote.hpp>
35 #include <ql/settings.hpp>
36 
37 namespace QuantLib {
38 
39     struct Pillar {
40         //! Enumeration for pillar determination alternatives
41         /*! These alternatives specify the determination of the pillar date. */
42         enum Choice {
43             MaturityDate,     //! instruments maturity date
44             LastRelevantDate, //! last date relevant for instrument pricing
45             CustomDate        //! custom choice
46         };
47     };
48 
49     std::ostream& operator<<(std::ostream& out, Pillar::Choice type);
50 
51     //! Base helper class for bootstrapping
52     /*! This class provides an abstraction for the instruments used to
53         bootstrap a term structure.
54 
55         It is advised that a bootstrap helper for an instrument
56         contains an instance of the actual instrument class to ensure
57         consistancy between the algorithms used during bootstrapping
58         and later instrument pricing. This is not yet fully enforced
59         in the available bootstrap helpers.
60     */
61     template <class TS>
62     class BootstrapHelper : public Observer, public Observable {
63       public:
64         explicit BootstrapHelper(const Handle<Quote>& quote);
65         explicit BootstrapHelper(Real quote);
~BootstrapHelper()66         virtual ~BootstrapHelper() {}
67         //! \name BootstrapHelper interface
68         //@{
quote() const69         const Handle<Quote>& quote() const { return quote_; }
70         virtual Real impliedQuote() const = 0;
quoteError() const71         Real quoteError() const { return quote_->value() - impliedQuote(); }
72         //! sets the term structure to be used for pricing
73         /*! \warning Being a pointer and not a shared_ptr, the term
74                      structure is not guaranteed to remain allocated
75                      for the whole life of the rate helper. It is
76                      responsibility of the programmer to ensure that
77                      the pointer remains valid. It is advised that
78                      this method is called only inside the term
79                      structure being bootstrapped, setting the pointer
80                      to <b>this</b>, i.e., the term structure itself.
81         */
82         virtual void setTermStructure(TS*);
83 
84         //! earliest relevant date
85         /*! The earliest date at which data are needed by the
86             helper in order to provide a quote.
87         */
88         virtual Date earliestDate() const;
89 
90         //! instrument's maturity date
91         virtual Date maturityDate() const;
92 
93         //! latest relevant date
94         /*! The latest date at which data are needed by the helper
95             in order to provide a quote. It does not necessarily
96             equal the maturity of the underlying instrument.
97         */
98         virtual Date latestRelevantDate() const;
99 
100         //! pillar date
101         virtual Date pillarDate() const;
102 
103         //! latest date
104         /*! equal to pillarDate()
105         */
106         virtual Date latestDate() const;
107         //@}
108         //! \name Observer interface
109         //@{
110         virtual void update();
111         //@}
112         //! \name Visitability
113         //@{
114         virtual void accept(AcyclicVisitor&);
115         //@}
116       protected:
117         Handle<Quote> quote_;
118         TS* termStructure_;
119         Date earliestDate_, latestDate_;
120         Date maturityDate_, latestRelevantDate_, pillarDate_;
121     };
122 
123     //! Bootstrap helper with date schedule relative to global evaluation date
124     /*! Derived classes must takes care of rebuilding the date schedule when
125         the global evaluation date changes
126     */
127     template <class TS>
128     class RelativeDateBootstrapHelper : public BootstrapHelper<TS> {
129       public:
130         explicit RelativeDateBootstrapHelper(const Handle<Quote>& quote);
131         explicit RelativeDateBootstrapHelper(Real quote);
132         //! \name Observer interface
133         //@{
update()134         void update() {
135             if (evaluationDate_ != Settings::instance().evaluationDate()) {
136                 evaluationDate_ = Settings::instance().evaluationDate();
137                 initializeDates();
138             }
139             BootstrapHelper<TS>::update();
140         }
141         //@}
142       protected:
143         virtual void initializeDates() = 0;
144         Date evaluationDate_;
145     };
146 
147     // template definitions
148 
149     template <class TS>
BootstrapHelper(const Handle<Quote> & quote)150     BootstrapHelper<TS>::BootstrapHelper(const Handle<Quote>& quote)
151     : quote_(quote), termStructure_(0) {
152         registerWith(quote_);
153     }
154 
155     template <class TS>
BootstrapHelper(Real quote)156     BootstrapHelper<TS>::BootstrapHelper(Real quote)
157     : quote_(Handle<Quote>(ext::shared_ptr<Quote>(new SimpleQuote(quote)))),
158       termStructure_(0) {}
159 
160     template <class TS>
setTermStructure(TS * t)161     void BootstrapHelper<TS>::setTermStructure(TS* t) {
162         QL_REQUIRE(t != 0, "null term structure given");
163         termStructure_ = t;
164     }
165 
166     template <class TS>
earliestDate() const167     Date BootstrapHelper<TS>::earliestDate() const {
168         return earliestDate_;
169     }
170 
171     template <class TS>
maturityDate() const172     Date BootstrapHelper<TS>::maturityDate() const {
173         if (maturityDate_ == Date())
174             return latestRelevantDate();
175         return maturityDate_;
176     }
177 
178     template <class TS>
latestRelevantDate() const179     Date BootstrapHelper<TS>::latestRelevantDate() const {
180         if (latestRelevantDate_ == Date())
181             return latestDate();
182         return latestRelevantDate_;
183     }
184 
185     template <class TS>
pillarDate() const186     Date BootstrapHelper<TS>::pillarDate() const {
187         if (pillarDate_==Date())
188             return latestDate();
189         return pillarDate_;
190     }
191 
192     template <class TS>
latestDate() const193     Date BootstrapHelper<TS>::latestDate() const {
194         if (latestDate_ == Date())
195             return pillarDate_;
196         return latestDate_;
197     }
198 
199     template <class TS>
update()200     void BootstrapHelper<TS>::update() {
201         notifyObservers();
202     }
203 
204     template <class TS>
accept(AcyclicVisitor & v)205     void BootstrapHelper<TS>::accept(AcyclicVisitor& v) {
206         Visitor<BootstrapHelper<TS> >* v1 =
207             dynamic_cast<Visitor<BootstrapHelper<TS> >*>(&v);
208         if (v1 != 0)
209             v1->visit(*this);
210         else
211             QL_FAIL("not a bootstrap-helper visitor");
212     }
213 
214     template <class TS>
RelativeDateBootstrapHelper(const Handle<Quote> & quote)215     RelativeDateBootstrapHelper<TS>::RelativeDateBootstrapHelper(
216                                                     const Handle<Quote>& quote)
217     : BootstrapHelper<TS>(quote) {
218         this->registerWith(Settings::instance().evaluationDate());
219         evaluationDate_ = Settings::instance().evaluationDate();
220     }
221 
222     template <class TS>
RelativeDateBootstrapHelper(Real quote)223     RelativeDateBootstrapHelper<TS>::RelativeDateBootstrapHelper(Real quote)
224     : BootstrapHelper<TS>(quote) {
225         this->registerWith(Settings::instance().evaluationDate());
226         evaluationDate_ = Settings::instance().evaluationDate();
227     }
228 
operator <<(std::ostream & out,Pillar::Choice t)229     inline std::ostream& operator<<(std::ostream& out,
230                                     Pillar::Choice t) {
231         switch (t) {
232         case Pillar::MaturityDate:
233             return out << "MaturityPillarDate";
234         case Pillar::LastRelevantDate:
235             return out << "LastRelevantPillarDate";
236         case Pillar::CustomDate:
237             return out << "CustomPillarDate";
238         default:
239             QL_FAIL("unknown Pillar::Choice(" << Integer(t) << ")");
240         }
241     }
242 
243     namespace detail {
244 
245         class BootstrapHelperSorter {
246           public:
247             template <class Helper>
operator ()(const ext::shared_ptr<Helper> & h1,const ext::shared_ptr<Helper> & h2) const248             bool operator()(
249                     const ext::shared_ptr<Helper>& h1,
250                     const ext::shared_ptr<Helper>& h2) const {
251                 return (h1->pillarDate() < h2->pillarDate());
252             }
253         };
254 
255     }
256 
257 }
258 
259 #endif
260