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