1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 
3 /*
4  Copyright (C) 2007, 2011 Ferdinando Ametrano
5  Copyright (C) 2007 François du Vignaud
6  Copyright (C) 2004, 2005, 2007, 2009 StatPro Italia srl
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 settings.hpp
23     \brief global repository for run-time library settings
24 */
25 
26 #ifndef quantlib_settings_hpp
27 #define quantlib_settings_hpp
28 
29 #include <ql/patterns/singleton.hpp>
30 #include <ql/time/date.hpp>
31 #include <ql/utilities/observablevalue.hpp>
32 #include <boost/optional.hpp>
33 
34 namespace QuantLib {
35 
36     //! global repository for run-time library settings
37     class Settings : public Singleton<Settings> {
38         friend class Singleton<Settings>;
39       private:
40         Settings();
41         class DateProxy : public ObservableValue<Date> {
42           public:
43             DateProxy();
44             DateProxy& operator=(const Date&);
45             operator Date() const;
46         };
47         friend std::ostream& operator<<(std::ostream&, const DateProxy&);
48       public:
49         //! the date at which pricing is to be performed.
50         /*! Client code can inspect the evaluation date, as in:
51             \code
52             Date d = Settings::instance().evaluationDate();
53             \endcode
54             where today's date is returned if the evaluation date is
55             set to the null date (its default value;) can set it to a
56             new value, as in:
57             \code
58             Settings::instance().evaluationDate() = d;
59             \endcode
60             and can register with it, as in:
61             \code
62             registerWith(Settings::instance().evaluationDate());
63             \endcode
64             to be notified when it is set to a new value.
65             \warning a notification is not sent when the evaluation
66                      date changes for natural causes---i.e., a date
67                      was not explicitly set (which results in today's
68                      date being used for pricing) and the current date
69                      changes as the clock strikes midnight.
70         */
71         DateProxy& evaluationDate();
72         const DateProxy& evaluationDate() const;
73 
74         /*! Call this to prevent the evaluation date to change at
75             midnight (and, incidentally, to gain quite a bit of
76             performance.)  If no evaluation date was previously set,
77             it is equivalent to setting the evaluation date to
78             Date::todaysDate(); if an evaluation date other than
79             Date() was already set, it has no effect.
80         */
81         void anchorEvaluationDate();
82         /*! Call this to reset the evaluation date to
83             Date::todaysDate() and allow it to change at midnight.  It
84             is equivalent to setting the evaluation date to Date().
85             This comes at the price of losing some performance, since
86             the evaluation date is re-evaluated each time it is read.
87         */
88         void resetEvaluationDate();
89 
90         /*! This flag specifies whether or not Events occurring on the reference
91             date should, by default, be taken into account as not happened yet.
92             It can be overridden locally when calling the Event::hasOccurred
93             method.
94         */
95         bool& includeReferenceDateEvents();
96         bool includeReferenceDateEvents() const;
97 
98         /*! If set, this flag specifies whether or not CashFlows
99             occurring on today's date should enter the NPV.  When the
100             NPV date (i.e., the date at which the cash flows are
101             discounted) equals today's date, this flag overrides the
102             behavior chosen for includeReferenceDate. It cannot be overridden
103             locally when calling the CashFlow::hasOccurred method.
104         */
105         boost::optional<bool>& includeTodaysCashFlows();
106         boost::optional<bool> includeTodaysCashFlows() const;
107 
108         bool& enforcesTodaysHistoricFixings();
109         bool enforcesTodaysHistoricFixings() const;
110       private:
111         DateProxy evaluationDate_;
112         bool includeReferenceDateEvents_;
113         boost::optional<bool> includeTodaysCashFlows_;
114         bool enforcesTodaysHistoricFixings_;
115     };
116 
117 
118     // helper class to temporarily and safely change the settings
119     class SavedSettings {
120       public:
121         SavedSettings();
122         ~SavedSettings();
123       private:
124         Date evaluationDate_;
125         bool includeReferenceDateEvents_;
126         boost::optional<bool> includeTodaysCashFlows_;
127         bool enforcesTodaysHistoricFixings_;
128     };
129 
130 
131     // inline
132 
operator Date() const133     inline Settings::DateProxy::operator Date() const {
134         if (value() == Date())
135             return Date::todaysDate();
136         else
137             return value();
138     }
139 
operator =(const Date & d)140     inline Settings::DateProxy& Settings::DateProxy::operator=(const Date& d) {
141         ObservableValue<Date>::operator=(d);
142         return *this;
143     }
144 
evaluationDate()145     inline Settings::DateProxy& Settings::evaluationDate() {
146         return evaluationDate_;
147     }
148 
evaluationDate() const149     inline const Settings::DateProxy& Settings::evaluationDate() const {
150         return evaluationDate_;
151     }
152 
includeReferenceDateEvents()153     inline bool& Settings::includeReferenceDateEvents() {
154         return includeReferenceDateEvents_;
155     }
156 
includeReferenceDateEvents() const157     inline bool Settings::includeReferenceDateEvents() const {
158         return includeReferenceDateEvents_;
159     }
160 
includeTodaysCashFlows()161     inline boost::optional<bool>& Settings::includeTodaysCashFlows() {
162         return includeTodaysCashFlows_;
163     }
164 
includeTodaysCashFlows() const165     inline boost::optional<bool> Settings::includeTodaysCashFlows() const {
166         return includeTodaysCashFlows_;
167     }
168 
enforcesTodaysHistoricFixings()169     inline bool& Settings::enforcesTodaysHistoricFixings() {
170         return enforcesTodaysHistoricFixings_;
171     }
172 
enforcesTodaysHistoricFixings() const173     inline bool Settings::enforcesTodaysHistoricFixings() const {
174         return enforcesTodaysHistoricFixings_;
175     }
176 
177 }
178 
179 #endif
180