QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
analyticbarrierengine.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) 2000, 2001, 2002, 2003 RiskMap srl
5 Copyright (C) 2002, 2003 Ferdinando Ametrano
6 Copyright (C) 2002, 2003 Sadruddin Rejeb
7 Copyright (C) 2003 Neil Firth
8 Copyright (C) 2007 StatPro Italia srl
9
10 This file is part of QuantLib, a free-software/open-source library
11 for financial quantitative analysts and developers - http://quantlib.org/
12
13 QuantLib is free software: you can redistribute it and/or modify it
14 under the terms of the QuantLib license. You should have received a
15 copy of the license along with this program; if not, please email
16 <quantlib-dev@lists.sf.net>. The license is also available online at
17 <http://quantlib.org/license.shtml>.
18
19 This program is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
21 FOR A PARTICULAR PURPOSE. See the license for more details.
22*/
23
24#include <ql/exercise.hpp>
26#include <utility>
27
28namespace QuantLib {
29
31 ext::shared_ptr<GeneralizedBlackScholesProcess> process)
32 : process_(std::move(process)) {
34 }
35
37
38 ext::shared_ptr<PlainVanillaPayoff> payoff =
39 ext::dynamic_pointer_cast<PlainVanillaPayoff>(arguments_.payoff);
40 QL_REQUIRE(payoff, "non-plain payoff given");
41 QL_REQUIRE(payoff->strike()>0.0,
42 "strike must be positive");
43
44 QL_REQUIRE(arguments_.exercise->type() == Exercise::European,
45 "only european style option are supported");
46
47 Real strike = payoff->strike();
48 Real spot = process_->x0();
49 QL_REQUIRE(spot > 0.0, "negative or null underlying given");
50 QL_REQUIRE(!triggered(spot), "barrier touched");
51
53
54 switch (payoff->optionType()) {
55 case Option::Call:
56 switch (barrierType) {
57 case Barrier::DownIn:
58 if (strike >= barrier())
59 results_.value = C(1,1) + E(1);
60 else
61 results_.value = A(1) - B(1) + D(1,1) + E(1);
62 break;
63 case Barrier::UpIn:
64 if (strike >= barrier())
65 results_.value = A(1) + E(-1);
66 else
67 results_.value = B(1) - C(-1,1) + D(-1,1) + E(-1);
68 break;
70 if (strike >= barrier())
71 results_.value = A(1) - C(1,1) + F(1);
72 else
73 results_.value = B(1) - D(1,1) + F(1);
74 break;
75 case Barrier::UpOut:
76 if (strike >= barrier())
77 results_.value = F(-1);
78 else
79 results_.value = A(1) - B(1) + C(-1,1) - D(-1,1) + F(-1);
80 break;
81 }
82 break;
83 case Option::Put:
84 switch (barrierType) {
85 case Barrier::DownIn:
86 if (strike >= barrier())
87 results_.value = B(-1) - C(1,-1) + D(1,-1) + E(1);
88 else
89 results_.value = A(-1) + E(1);
90 break;
91 case Barrier::UpIn:
92 if (strike >= barrier())
93 results_.value = A(-1) - B(-1) + D(-1,-1) + E(-1);
94 else
95 results_.value = C(-1,-1) + E(-1);
96 break;
98 if (strike >= barrier())
99 results_.value = A(-1) - B(-1) + C(1,-1) - D(1,-1) + F(1);
100 else
101 results_.value = F(1);
102 break;
103 case Barrier::UpOut:
104 if (strike >= barrier())
105 results_.value = B(-1) - D(-1,-1) + F(-1);
106 else
107 results_.value = A(-1) - C(-1,-1) + F(-1);
108 break;
109 }
110 break;
111 default:
112 QL_FAIL("unknown type");
113 }
114 }
115
116
118 return process_->x0();
119 }
120
122 ext::shared_ptr<PlainVanillaPayoff> payoff =
123 ext::dynamic_pointer_cast<PlainVanillaPayoff>(arguments_.payoff);
124 QL_REQUIRE(payoff, "non-plain payoff given");
125 return payoff->strike();
126 }
127
129 return process_->blackVolatility()->blackVol(
130 arguments_.exercise->lastDate(),
131 strike());
132 }
133
135 return std::sqrt(process_->blackVolatility()->blackVariance(
136 arguments_.exercise->lastDate(),
137 strike()));
138 }
139
141 return arguments_.barrier;
142 }
143
145 return arguments_.rebate;
146 }
147
149 return process_->riskFreeRate()->zeroRate(
150 arguments_.exercise->lastDate(),
151 process_->riskFreeRate()->dayCounter(),
153 }
154
156 return process_->riskFreeRate()->discount(
157 arguments_.exercise->lastDate());
158 }
159
161 return process_->dividendYield()->zeroRate(
162 arguments_.exercise->lastDate(),
163 process_->dividendYield()->dayCounter(),
165 }
166
168 return process_->dividendYield()->discount(
169 arguments_.exercise->lastDate());
170 }
171
173 Volatility vol = volatility();
174 return (riskFreeRate() - dividendYield())/(vol * vol) - 0.5;
175 }
176
178 return (1 + mu()) * stdDeviation();
179 }
180
182 Real x1 =
183 std::log(underlying()/strike())/stdDeviation() + muSigma();
184 Real N1 = f_(phi*x1);
185 Real N2 = f_(phi*(x1-stdDeviation()));
186
187 return phi*(underlying() * dividendDiscount() * N1
188 - strike() * riskFreeDiscount() * N2);
189 }
190
192 Real x2 =
193 std::log(underlying()/barrier())/stdDeviation() + muSigma();
194 Real N1 = f_(phi*x2);
195 Real N2 = f_(phi*(x2-stdDeviation()));
196 return phi*(underlying() * dividendDiscount() * N1
197 - strike() * riskFreeDiscount() * N2);
198 }
199
201 Real HS = barrier()/underlying();
202 Real powHS0 = std::pow(HS, 2 * mu());
203 Real powHS1 = powHS0 * HS * HS;
204 Real y1 = std::log(barrier()*HS/strike())/stdDeviation() + muSigma();
205 Real N1 = f_(eta*y1);
206 Real N2 = f_(eta*(y1-stdDeviation()));
207 // when N1 or N2 are zero, the corresponding powHS might
208 // be infinity, resulting in a NaN for their products. The limit should be 0.
209 return phi*(underlying() * dividendDiscount() * (N1 == 0.0 ? Real(0.0) : Real(powHS1 * N1))
210 - strike() * riskFreeDiscount() * (N2 == 0.0 ? Real(0.0) : Real(powHS0 * N2)));
211 }
212
214 Real HS = barrier()/underlying();
215 Real powHS0 = std::pow(HS, 2 * mu());
216 Real powHS1 = powHS0 * HS * HS;
217 Real y2 = std::log(barrier()/underlying())/stdDeviation() + muSigma();
218 Real N1 = f_(eta*y2);
219 Real N2 = f_(eta*(y2-stdDeviation()));
220 // when N1 or N2 are zero, the corresponding powHS might
221 // be infinity, resulting in a NaN for their products. The limit should be 0.
222 return phi*(underlying() * dividendDiscount() * (N1 == 0.0 ? Real(0.0) : Real(powHS1 * N1))
223 - strike() * riskFreeDiscount() * (N2 == 0.0 ? Real(0.0) : Real(powHS0 * N2)));
224 }
225
227 if (rebate() > 0) {
228 Real powHS0 = std::pow(barrier()/underlying(), 2 * mu());
229 Real x2 =
230 std::log(underlying()/barrier())/stdDeviation() + muSigma();
231 Real y2 =
232 std::log(barrier()/underlying())/stdDeviation() + muSigma();
233 Real N1 = f_(eta*(x2 - stdDeviation()));
234 Real N2 = f_(eta*(y2 - stdDeviation()));
235 // when N2 is zero, powHS0 might be infinity, resulting in
236 // a NaN for their product. The limit should be 0.
237 return rebate() * riskFreeDiscount() * (N1 - (N2 == 0.0 ? Real(0.0) : Real(powHS0 * N2)));
238 } else {
239 return 0.0;
240 }
241 }
242
244 if (rebate() > 0) {
245 Rate m = mu();
246 Volatility vol = volatility();
247 Real lambda = std::sqrt(m*m + 2.0*riskFreeRate()/(vol * vol));
248 Real HS = barrier()/underlying();
249 Real powHSplus = std::pow(HS, m + lambda);
250 Real powHSminus = std::pow(HS, m - lambda);
251
252 Real sigmaSqrtT = stdDeviation();
253 Real z = std::log(barrier()/underlying())/sigmaSqrtT
254 + lambda * sigmaSqrtT;
255
256 Real N1 = f_(eta * z);
257 Real N2 = f_(eta * (z - 2.0 * lambda * sigmaSqrtT));
258 // when N1 or N2 are zero, the corresponding powHS might
259 // be infinity, resulting in a NaN for their product. The limit should be 0.
260 return rebate() * ((N1 == 0.0 ? Real(0.0) : Real(powHSplus * N1)) + (N2 == 0.0 ? Real(0.0) : Real(powHSminus * N2)));
261 } else {
262 return 0.0;
263 }
264 }
265
266}
Analytic barrier option engines.
Real C(Real eta, Real phi) const
CumulativeNormalDistribution f_
Real D(Real eta, Real phi) const
ext::shared_ptr< GeneralizedBlackScholesProcess > process_
AnalyticBarrierEngine(ext::shared_ptr< GeneralizedBlackScholesProcess > process)
bool triggered(Real underlying) const
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Definition: observable.hpp:228
#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
Option exercise classes and payoff function.
@ NoFrequency
null frequency
Definition: frequency.hpp:37
QL_REAL Real
real number
Definition: types.hpp:50
Real DiscountFactor
discount factor between dates
Definition: types.hpp:66
Real Volatility
volatility
Definition: types.hpp:78
Real Rate
interest rates
Definition: types.hpp:70
ext::shared_ptr< QuantLib::Payoff > payoff
Definition: any.hpp:35
STL namespace.
Real F
Definition: sabr.cpp:200