QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
discretizeddoublebarrieroption.cpp
Go to the documentation of this file.
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2015 Thema Consulting SA
5
6 This file is part of QuantLib, a free-software/open-source library
7 for financial quantitative analysts and developers - http://quantlib.org/
8
9 QuantLib is free software: you can redistribute it and/or modify it
10 under the terms of the QuantLib license. You should have received a
11 copy of the license along with this program; if not, please email
12 <quantlib-dev@lists.sf.net>. The license is also available online at
13 <http://quantlib.org/license.shtml>.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the license for more details.
18*/
19
21#include <vector>
22
23namespace QuantLib {
24
27 const StochasticProcess& process,
28 const TimeGrid& grid)
29 : arguments_(args), vanilla_(arguments_, process, grid) {
30 QL_REQUIRE(!args.exercise->dates().empty(), "specify at least one stopping date");
31
32 stoppingTimes_.resize(args.exercise->dates().size());
33 for (Size i=0; i<stoppingTimes_.size(); ++i) {
35 process.time(args.exercise->date(i));
36 if (!grid.empty()) {
37 // adjust to the given grid
39 }
40 }
41 }
42
45 values_ = Array(size, 0.0);
47 }
48
52 }
53 Array grid = method()->grid(time());
54 checkBarrier(values_, grid);
55 }
56
57 void DiscretizedDoubleBarrierOption::checkBarrier(Array &optvalues, const Array &grid) const {
58
59 Time now = time();
60 bool endTime = isOnTime(stoppingTimes_.back());
61 bool stoppingTime = false;
62 switch (arguments_.exercise->type()) {
64 if (now <= stoppingTimes_[1] &&
65 now >= stoppingTimes_[0])
66 stoppingTime = true;
67 break;
70 stoppingTime = true;
71 break;
73 for (Real i : stoppingTimes_) {
74 if (isOnTime(i)) {
75 stoppingTime = true;
76 break;
77 }
78 }
79 break;
80 default:
81 QL_FAIL("invalid option type");
82 }
83 for (Size j=0; j<optvalues.size(); j++) {
84 switch (arguments_.barrierType) {
86 if (grid[j] <= arguments_.barrier_lo) {
87 // knocked in dn
88 if (stoppingTime) {
89 optvalues[j] = std::max(vanilla()[j],
90 (*arguments_.payoff)(grid[j]));
91 }
92 else
93 optvalues[j] = vanilla()[j];
94 }
95 else if (grid[j] >= arguments_.barrier_hi) {
96 // knocked in up
97 if (stoppingTime) {
98 optvalues[j] = std::max(vanilla()[j],
99 (*arguments_.payoff)(grid[j]));
100 }
101 else
102 optvalues[j] = vanilla()[j];
103 }
104 else if (endTime)
105 optvalues[j] = arguments_.rebate;
106 break;
108 if (grid[j] <= arguments_.barrier_lo)
109 optvalues[j] = arguments_.rebate; // knocked out lo
110 else if (grid[j] >= arguments_.barrier_hi)
111 optvalues[j] = arguments_.rebate; // knocked out hi
112 else if (stoppingTime)
113 optvalues[j] = std::max(optvalues[j],
114 (*arguments_.payoff)(grid[j]));
115 break;
117 // low barrier is KI, high is KO
118 if (grid[j] <= arguments_.barrier_lo) {
119 // knocked in dn
120 if (stoppingTime) {
121 optvalues[j] = std::max(vanilla()[j],
122 (*arguments_.payoff)(grid[j]));
123 }
124 else
125 optvalues[j] = vanilla()[j];
126 }
127 else if (grid[j] >= arguments_.barrier_hi)
128 optvalues[j] = arguments_.rebate; // knocked out hi
129 else if (endTime)
130 optvalues[j] = arguments_.rebate;
131 break;
133 // low barrier is KO, high is KI
134 if (grid[j] <= arguments_.barrier_lo)
135 optvalues[j] = arguments_.rebate; // knocked out lo
136 else if (grid[j] >= arguments_.barrier_hi) {
137 // knocked in up
138 if (stoppingTime) {
139 optvalues[j] = std::max(vanilla()[j],
140 (*arguments_.payoff)(grid[j]));
141 }
142 else
143 optvalues[j] = vanilla()[j];
144 }
145 else if (endTime)
146 optvalues[j] = arguments_.rebate;
147 break;
148 default:
149 QL_FAIL("invalid barrier type");
150 }
151 }
152 }
153
154
155
158 const StochasticProcess& process,
159 const TimeGrid& grid)
160 : unenhanced_(args, process, grid) {
161 }
162
165 values_ = Array(size, 0.0);
166 adjustValues();
167 }
168
171
172 Array grid = method()->grid(time());
173 unenhanced_.checkBarrier(values_, grid); // compute payoffs
174 adjustBarrier(values_, grid);
175 }
176
178 Real barrier_lo = unenhanced_.arguments().barrier_lo;
179 Real barrier_hi = unenhanced_.arguments().barrier_hi;
180 Real rebate = unenhanced_.arguments().rebate;
183 for (Size j=0; j<optvalues.size()-1; ++j) {
184 if (grid[j]<=barrier_lo && grid[j+1] > barrier_lo) {
185 // grid[j+1] above barrier_lo, grid[j] under (in),
186 // interpolate optvalues[j+1]
187 Real ltob = (barrier_lo-grid[j]);
188 Real htob = (grid[j+1]-barrier_lo);
189 Real htol = (grid[j+1]-grid[j]);
190 Real u1 = unenhanced_.values()[j+1];
191 Real t1 = unenhanced_.vanilla()[j+1];
192 optvalues[j+1] = std::max(0.0, (ltob*t1+htob*u1)/htol); // derman std
193 }
194 else if (grid[j] < barrier_hi && grid[j+1] >= barrier_hi) {
195 // grid[j+1] above barrier_hi (in), grid[j] under,
196 // interpolate optvalues[j]
197 Real ltob = (barrier_hi-grid[j]);
198 Real htob = (grid[j+1]-barrier_hi);
199 Real htol = (grid[j+1]-grid[j]);
200 Real u = unenhanced_.values()[j];
201 Real t = unenhanced_.vanilla()[j];
202 optvalues[j] = std::max(0.0, (ltob*u+htob*t)/htol); // derman std
203 }
204 }
205 break;
207 for (Size j=0; j<optvalues.size()-1; ++j) {
208 if (grid[j]<=barrier_lo && grid[j+1] > barrier_lo) {
209 // grid[j+1] above barrier_lo, grid[j] under (out),
210 // interpolate optvalues[j+1]
211 Real a = (barrier_lo-grid[j])*rebate;
212 Real b = (grid[j+1]-barrier_lo)*unenhanced_.values()[j+1];
213 Real c = (grid[j+1]-grid[j]);
214 optvalues[j+1] = std::max(0.0, (a+b)/c);
215 }
216 else if (grid[j] < barrier_hi && grid[j+1] >= barrier_hi) {
217 // grid[j+1] above barrier_hi (out), grid[j] under,
218 // interpolate optvalues[j]
219 Real a = (barrier_hi-grid[j])*unenhanced_.values()[j];
220 Real b = (grid[j+1]-barrier_hi)*rebate;
221 Real c = (grid[j+1]-grid[j]);
222 optvalues[j] = std::max(0.0, (a+b)/c);
223 }
224 }
225 break;
226 default:
227 QL_FAIL("unsupported barrier type");
228 break;
229 }
230 }
231
232}
1-D array used in linear algebra.
Definition: array.hpp:52
Size size() const
dimension of the array
Definition: array.hpp:495
const Array & values() const
const ext::shared_ptr< Lattice > & method() const
void initialize(const ext::shared_ptr< Lattice > &, Time t)
DiscretizedDermanKaniDoubleBarrierOption(const DoubleBarrierOption::arguments &, const StochasticProcess &process, const TimeGrid &grid=TimeGrid())
void checkBarrier(Array &optvalues, const Array &grid) const
const DoubleBarrierOption::arguments & arguments() const
DiscretizedDoubleBarrierOption(const DoubleBarrierOption::arguments &, const StochasticProcess &process, const TimeGrid &grid=TimeGrid())
Arguments for double barrier option calculation
multi-dimensional stochastic process class.
virtual Time time(const Date &) const
time grid class
Definition: timegrid.hpp:43
bool empty() const
Definition: timegrid.hpp:165
Time closestTime(Time t) const
returns the time on the grid closest to the given t
Definition: timegrid.hpp:148
const DefaultType & t
discretized double barrier option
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
#define QL_FAIL(message)
throw an error (possibly with file and line information)
Definition: errors.hpp:92
ext::function< Real(Real)> b
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
@ KOKI
lower barrier KI, upper KO