QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
mcbarrierengine.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2003 Neil Firth
5 Copyright (C) 2003 Ferdinando Ametrano
6 Copyright (C) 2003, 2004, 2005 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#include <ql/pricingengines/barrier/mcbarrierengine.hpp>
23#include <utility>
24
25namespace QuantLib {
26
28 Real barrier,
29 Real rebate,
30 Option::Type type,
31 Real strike,
32 std::vector<DiscountFactor> discounts,
33 ext::shared_ptr<StochasticProcess1D> diffProcess,
34 PseudoRandom::ursg_type sequenceGen)
35 : barrierType_(barrierType), barrier_(barrier), rebate_(rebate),
36 diffProcess_(std::move(diffProcess)), sequenceGen_(std::move(sequenceGen)),
37 payoff_(type, strike), discounts_(std::move(discounts)) {
38 QL_REQUIRE(strike>=0.0,
39 "strike less than zero not allowed");
40 QL_REQUIRE(barrier>0.0,
41 "barrier less/equal zero not allowed");
42 }
43
44
46 static Size null = Null<Size>();
47 Size n = path.length();
48 QL_REQUIRE(n>1, "the path cannot be empty");
49
50 bool isOptionActive = false;
51 Size knockNode = null;
52 Real asset_price = path.front();
53 Real new_asset_price;
54 Real x, y;
55 Volatility vol;
56 const TimeGrid& timeGrid = path.timeGrid();
57 Time dt;
58 std::vector<Real> u = sequenceGen_.nextSequence().value;
59 Size i;
60
61 switch (barrierType_) {
62 case Barrier::DownIn:
63 isOptionActive = false;
64 for (i = 0; i < n-1; i++) {
65 new_asset_price = path[i+1];
66 // terminal or initial vol?
67 vol = diffProcess_->diffusion(timeGrid[i],asset_price);
68 dt = timeGrid.dt(i);
69
70 x = std::log(new_asset_price / asset_price);
71 y = 0.5*(x - std::sqrt (x*x - 2*vol*vol*dt*std::log(u[i])));
72 y = asset_price * std::exp(y);
73 if (y <= barrier_) {
74 isOptionActive = true;
75 if (knockNode == null)
76 knockNode = i+1;
77 }
78 asset_price = new_asset_price;
79 }
80 break;
81 case Barrier::UpIn:
82 isOptionActive = false;
83 for (i = 0; i < n-1; i++) {
84 new_asset_price = path[i+1];
85 // terminal or initial vol?
86 vol = diffProcess_->diffusion(timeGrid[i],asset_price);
87 dt = timeGrid.dt(i);
88
89 x = std::log(new_asset_price / asset_price);
90 y = 0.5*(x + std::sqrt(x*x - 2*vol*vol*dt*std::log((1-u[i]))));
91 y = asset_price * std::exp(y);
92 if (y >= barrier_) {
93 isOptionActive = true;
94 if (knockNode == null)
95 knockNode = i+1;
96 }
97 asset_price = new_asset_price;
98 }
99 break;
100 case Barrier::DownOut:
101 isOptionActive = true;
102 for (i = 0; i < n-1; i++) {
103 new_asset_price = path[i+1];
104 // terminal or initial vol?
105 vol = diffProcess_->diffusion(timeGrid[i],asset_price);
106 dt = timeGrid.dt(i);
107
108 x = std::log(new_asset_price / asset_price);
109 y = 0.5*(x - std::sqrt(x*x - 2*vol*vol*dt*std::log(u[i])));
110 y = asset_price * std::exp(y);
111 if (y <= barrier_) {
112 isOptionActive = false;
113 if (knockNode == null)
114 knockNode = i+1;
115 }
116 asset_price = new_asset_price;
117 }
118 break;
119 case Barrier::UpOut:
120 isOptionActive = true;
121 for (i = 0; i < n-1; i++) {
122 new_asset_price = path[i+1];
123 // terminal or initial vol?
124 vol = diffProcess_->diffusion(timeGrid[i],asset_price);
125 dt = timeGrid.dt(i);
126
127 x = std::log(new_asset_price / asset_price);
128 y = 0.5*(x + std::sqrt(x*x - 2*vol*vol*dt*std::log((1-u[i]))));
129 y = asset_price * std::exp(y);
130 if (y >= barrier_) {
131 isOptionActive = false;
132 if (knockNode == null)
133 knockNode = i+1;
134 }
135 asset_price = new_asset_price;
136 }
137 break;
138 default:
139 QL_FAIL("unknown barrier type");
140 }
141
142 if (isOptionActive) {
143 return payoff_(asset_price) * discounts_.back();
144 } else {
145 switch (barrierType_) {
146 case Barrier::UpIn:
147 case Barrier::DownIn:
148 return rebate_*discounts_.back();
149 case Barrier::UpOut:
150 case Barrier::DownOut:
151 return rebate_*discounts_[knockNode];
152 default:
153 QL_FAIL("unknown barrier type");
154 }
155 }
156 }
157
158
160 Real barrier,
161 Real rebate,
162 Option::Type type,
163 Real strike,
164 std::vector<DiscountFactor> discounts)
165 : barrierType_(barrierType), barrier_(barrier), rebate_(rebate), payoff_(type, strike),
166 discounts_(std::move(discounts)) {
167 QL_REQUIRE(strike>=0.0,
168 "strike less than zero not allowed");
169 QL_REQUIRE(barrier>0.0,
170 "barrier less/equal zero not allowed");
171 }
172
173
175 static Size null = Null<Size>();
176 Size n = path.length();
177 QL_REQUIRE(n>1, "the path cannot be empty");
178
179 bool isOptionActive = false;
180 Size knockNode = null;
181 Real asset_price = path.front();
182 Size i;
183
184 switch (barrierType_) {
185 case Barrier::DownIn:
186 isOptionActive = false;
187 for (i = 1; i < n; i++) {
188 asset_price = path[i];
189 if (asset_price <= barrier_) {
190 isOptionActive = true;
191 if (knockNode == null)
192 knockNode = i;
193 }
194 }
195 break;
196 case Barrier::UpIn:
197 isOptionActive = false;
198 for (i = 1; i < n; i++) {
199 asset_price = path[i];
200 if (asset_price >= barrier_) {
201 isOptionActive = true;
202 if (knockNode == null)
203 knockNode = i;
204 }
205 }
206 break;
207 case Barrier::DownOut:
208 isOptionActive = true;
209 for (i = 1; i < n; i++) {
210 asset_price = path[i];
211 if (asset_price <= barrier_) {
212 isOptionActive = false;
213 if (knockNode == null)
214 knockNode = i;
215 }
216 }
217 break;
218 case Barrier::UpOut:
219 isOptionActive = true;
220 for (i = 1; i < n; i++) {
221 asset_price = path[i];
222 if (asset_price >= barrier_) {
223 isOptionActive = false;
224 if (knockNode == null)
225 knockNode = i;
226 }
227 }
228 break;
229 default:
230 QL_FAIL("unknown barrier type");
231 }
232
233 if (isOptionActive) {
234 return payoff_(asset_price) * discounts_.back();
235 } else {
236 switch (barrierType_) {
237 case Barrier::UpIn:
238 case Barrier::DownIn:
239 return rebate_*discounts_.back();
240 case Barrier::UpOut:
241 case Barrier::DownOut:
242 return rebate_*discounts_[knockNode];
243 default:
244 QL_FAIL("unknown barrier type");
245 }
246 }
247 }
248
249}
std::vector< DiscountFactor > discounts_
PseudoRandom::ursg_type sequenceGen_
BarrierPathPricer(Barrier::Type barrierType, Real barrier, Real rebate, Option::Type type, Real strike, std::vector< DiscountFactor > discounts, ext::shared_ptr< StochasticProcess1D > diffProcess, PseudoRandom::ursg_type sequenceGen)
Real operator()(const Path &path) const override
ext::shared_ptr< StochasticProcess1D > diffProcess_
BiasedBarrierPathPricer(Barrier::Type barrierType, Real barrier, Real rebate, Option::Type type, Real strike, std::vector< DiscountFactor > discounts)
std::vector< DiscountFactor > discounts_
Real operator()(const Path &path) const override
template class providing a null value for a given type.
Definition: null.hpp:76
single-factor random walk
Definition: path.hpp:40
Size length() const
Definition: path.hpp:94
const TimeGrid & timeGrid() const
time grid
Definition: path.hpp:142
Real front() const
initial asset value
Definition: path.hpp:122
Random sequence generator based on a pseudo-random number generator.
const sample_type & nextSequence() const
time grid class
Definition: timegrid.hpp:43
Time dt(Size i) const
Definition: timegrid.hpp:154
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
Real Volatility
volatility
Definition: types.hpp:78
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
STL namespace.