1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2001, 2002, 2003 Sadruddin Rejeb
5 Copyright (C) 2004, 2005, 2006 StatPro Italia srl
6
7 This file is part of QuantLib, a free-software/open-source library
8 for financial quantitative analysts and developers - http://quantlib.org/
9
10 QuantLib is free software: you can redistribute it and/or modify it
11 under the terms of the QuantLib license. You should have received a
12 copy of the license along with this program; if not, please email
13 <quantlib-dev@lists.sf.net>. The license is also available online at
14 <http://quantlib.org/license.shtml>.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the license for more details.
19*/
20
21/*! \file discretizedasset.hpp
22 \brief Discretized asset classes
23*/
24
25#ifndef quantlib_discretized_asset_hpp
26#define quantlib_discretized_asset_hpp
27
28#include <ql/exercise.hpp>
29#include <ql/math/comparison.hpp>
30#include <ql/numericalmethod.hpp>
31#include <utility>
32
33namespace QuantLib {
34
35 //! Discretized asset class used by numerical methods
36 class DiscretizedAsset {
37 public:
38 DiscretizedAsset()
39 : latestPreAdjustment_(QL_MAX_REAL),
40 latestPostAdjustment_(QL_MAX_REAL) {}
41 virtual ~DiscretizedAsset() = default;
42
43 //! \name inspectors
44 //@{
45 Time time() const { return time_; }
46 Time& time() { return time_; }
47
48 const Array& values() const { return values_; }
49 Array& values() { return values_; }
50
51 const ext::shared_ptr<Lattice>& method() const {
52 return method_;
53 }
54 //@}
55
56 /*! \name High-level interface
57
58 Users of discretized assets should use these methods in
59 order to initialize, evolve and take the present value of
60 the assets. They call the corresponding methods in the
61 Lattice interface, to which we refer for
62 documentation.
63
64 @{
65 */
66 void initialize(const ext::shared_ptr<Lattice>&,
67 Time t);
68 void rollback(Time to);
69 void partialRollback(Time to);
70 Real presentValue();
71 //@}
72
73 /*! \name Low-level interface
74
75 These methods (that developers should override when
76 deriving from DiscretizedAsset) are to be used by
77 numerical methods and not directly by users, with the
78 exception of adjustValues(), preAdjustValues() and
79 postAdjustValues() that can be used together with
80 partialRollback().
81
82 @{
83 */
84
85 /*! This method should initialize the asset values to an Array
86 of the given size and with values depending on the
87 particular asset.
88 */
89 virtual void reset(Size size) = 0;
90
91 /*! This method will be invoked after rollback and before any
92 other asset (i.e., an option on this one) has any chance to
93 look at the values. For instance, payments happening at times
94 already spanned by the rollback will be added here.
95
96 This method is not virtual; derived classes must override
97 the protected preAdjustValuesImpl() method instead.
98 */
99 void preAdjustValues();
100
101 /*! This method will be invoked after rollback and after any
102 other asset had their chance to look at the values. For
103 instance, payments happening at the present time (and therefore
104 not included in an option to be exercised at this time) will be
105 added here.
106
107 This method is not virtual; derived classes must override
108 the protected postAdjustValuesImpl() method instead.
109 */
110 void postAdjustValues();
111
112 /*! This method performs both pre- and post-adjustment */
113 void adjustValues() {
114 preAdjustValues();
115 postAdjustValues();
116 }
117
118 /*! This method returns the times at which the numerical
119 method should stop while rolling back the asset. Typical
120 examples include payment times, exercise times and such.
121
122 \note The returned values are not guaranteed to be sorted.
123 */
124 virtual std::vector<Time> mandatoryTimes() const = 0;
125 //@}
126 protected:
127 /*! Indicates if a coupon should be adjusted in preAdjustValues() or postAdjustValues(). */
128 enum class CouponAdjustment { pre, post };
129
130 /*! This method checks whether the asset was rolled at the
131 given time. */
132 bool isOnTime(Time t) const;
133 /*! This method performs the actual pre-adjustment */
134 virtual void preAdjustValuesImpl() {}
135 /*! This method performs the actual post-adjustment */
136 virtual void postAdjustValuesImpl() {}
137
138 Time time_;
139 Time latestPreAdjustment_, latestPostAdjustment_;
140 Array values_;
141 private:
142 ext::shared_ptr<Lattice> method_;
143 };
144
145
146 //! Useful discretized discount bond asset
147 class DiscretizedDiscountBond : public DiscretizedAsset {
148 public:
149 DiscretizedDiscountBond() = default;
150 void reset(Size size) override { values_ = Array(size, 1.0); }
151 std::vector<Time> mandatoryTimes() const override { return std::vector<Time>(); }
152 };
153
154
155 //! Discretized option on a given asset
156 /*! \warning it is advised that derived classes take care of
157 creating and initializing themselves an instance of
158 the underlying.
159 */
160 class DiscretizedOption : public DiscretizedAsset {
161 public:
162 DiscretizedOption(ext::shared_ptr<DiscretizedAsset> underlying,
163 Exercise::Type exerciseType,
164 std::vector<Time> exerciseTimes)
165 : underlying_(std::move(underlying)), exerciseType_(exerciseType),
166 exerciseTimes_(std::move(exerciseTimes)) {}
167 void reset(Size size) override;
168 std::vector<Time> mandatoryTimes() const override;
169
170 protected:
171 void postAdjustValuesImpl() override;
172 void applyExerciseCondition();
173 ext::shared_ptr<DiscretizedAsset> underlying_;
174 Exercise::Type exerciseType_;
175 std::vector<Time> exerciseTimes_;
176 };
177
178
179
180 // inline definitions
181
182 inline void DiscretizedAsset::initialize(
183 const ext::shared_ptr<Lattice>& method,
184 Time t) {
185 method_ = method;
186 method_->initialize(*this, time: t);
187 }
188
189 inline void DiscretizedAsset::rollback(Time to) {
190 method_->rollback(*this, to);
191 }
192
193 inline void DiscretizedAsset::partialRollback(Time to) {
194 method_->partialRollback(*this, to);
195 }
196
197 inline Real DiscretizedAsset::presentValue() {
198 return method_->presentValue(*this);
199 }
200
201 inline void DiscretizedAsset::preAdjustValues() {
202 if (!close_enough(x: time(),y: latestPreAdjustment_)) {
203 preAdjustValuesImpl();
204 latestPreAdjustment_ = time();
205 }
206 }
207
208 inline void DiscretizedAsset::postAdjustValues() {
209 if (!close_enough(x: time(),y: latestPostAdjustment_)) {
210 postAdjustValuesImpl();
211 latestPostAdjustment_ = time();
212 }
213 }
214
215 inline bool DiscretizedAsset::isOnTime(Time t) const {
216 const TimeGrid& grid = method()->timeGrid();
217 return close_enough(x: grid[grid.index(t)],y: time());
218 }
219
220
221 inline void DiscretizedOption::reset(Size size) {
222 QL_REQUIRE(method() == underlying_->method(),
223 "option and underlying were initialized on "
224 "different methods");
225 values_ = Array(size, 0.0);
226 adjustValues();
227 }
228
229 inline std::vector<Time> DiscretizedOption::mandatoryTimes() const {
230 std::vector<Time> times = underlying_->mandatoryTimes();
231 // discard negative times...
232 auto i = std::find_if(first: exerciseTimes_.begin(), last: exerciseTimes_.end(),
233 pred: [](Time t){ return t >= 0.0; });
234 // and add the positive ones
235 times.insert(position: times.end(), first: i, last: exerciseTimes_.end());
236 return times;
237 }
238
239 inline void DiscretizedOption::applyExerciseCondition() {
240 for (Size i=0; i<values_.size(); i++)
241 values_[i] = std::max(a: underlying_->values()[i], b: values_[i]);
242 }
243
244
245}
246
247
248#endif
249

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of quantlib/ql/discretizedasset.hpp