QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
analyticholderextensibleoptionengine.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) 2014 Master IMAFA - Polytech'Nice Sophia - Université de Nice Sophia Antipolis
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
20#include <ql/exercise.hpp>
23#include <utility>
24
25using std::pow;
26using std::log;
27using std::exp;
28using std::sqrt;
29
30namespace QuantLib {
31
33 ext::shared_ptr<GeneralizedBlackScholesProcess> process)
34 : process_(std::move(process)) {
36 }
37
39 //Spot
40 Real S = process_->x0();
42 Real b = r - dividendYield();
43 Real X1 = strike();
46 Time t1 = firstExpiryTime();
48
49
50 Real z1 = this->z1();
51
52 Real z2 = this->z2();
53
54 Real rho = sqrt(t1 / T2);
55
56
57 ext::shared_ptr<PlainVanillaPayoff> payoff =
58 ext::dynamic_pointer_cast<PlainVanillaPayoff>(arguments_.payoff);
59
60 //QuantLib requires sigma * sqrt(T) rather than just sigma/volatility
61 Real vol = volatility();
62
63 //calculate dividend discount factor assuming continuous compounding (e^-rt)
65 //calculate payoff discount factor assuming continuous compounding
66 DiscountFactor discount = riskFreeDiscount(t1);
67 Real result = 0;
68 constexpr double minusInf = -std::numeric_limits<double>::infinity();
69
70 Real y1 = this->y1(payoff->optionType()),
71 y2 = this->y2(payoff->optionType());
72 if (payoff->optionType() == Option::Call) {
73 //instantiate payoff function for a call
74 ext::shared_ptr<PlainVanillaPayoff> vanillaCallPayoff =
75 ext::make_shared<PlainVanillaPayoff>(Option::Call, X1);
76 Real BSM = BlackScholesCalculator(vanillaCallPayoff, S, growth, vol*sqrt(t1), discount).value();
77 result = BSM
78 + S*exp((b - r)*T2)*M2(y1, y2, minusInf, z1, rho)
79 - X2*exp(-r*T2)*M2(y1 - vol*sqrt(t1), y2 - vol*sqrt(t1), minusInf, z1 - vol*sqrt(T2), rho)
80 - S*exp((b - r)*t1)*N2(y1, z2) + X1*exp(-r*t1)*N2(y1 - vol*sqrt(t1), z2 - vol*sqrt(t1))
81 - A*exp(-r*t1)*N2(y1 - vol*sqrt(t1), y2 - vol*sqrt(t1));
82 } else {
83 //instantiate payoff function for a call
84 ext::shared_ptr<PlainVanillaPayoff> vanillaPutPayoff =
85 ext::make_shared<PlainVanillaPayoff>(Option::Put, X1);
86 result = BlackScholesCalculator(vanillaPutPayoff, S, growth, vol*sqrt(t1), discount).value()
87 - S*exp((b - r)*T2)*M2(y1, y2, minusInf, -z1, rho)
88 + X2*exp(-r*T2)*M2(y1 - vol*sqrt(t1), y2 - vol*sqrt(t1), minusInf, -z1 + vol*sqrt(T2), rho)
89 + S*exp((b - r)*t1)*N2(z2, y2) - X1*exp(-r*t1)*N2(z2 - vol*sqrt(t1), y2 - vol*sqrt(t1))
90 - A*exp(-r*t1)*N2(y1 - vol*sqrt(t1), y2 - vol*sqrt(t1));
91 }
92 this->results_.value = result;
93 }
94
96 Real Sv = process_->x0();
98
99 if(A==0)
100 {
101 return 0;
102 }
103 else
104 {
106 Real ci = bs.value();
107 Real dc = bs.delta();
108
109 Real yi = ci - A;
110 //da/ds = 0
111 Real di = dc - 0;
112 Real epsilon = 0.001;
113
114 //Newton-Raphson process
115 while (std::fabs(yi) > epsilon){
116 Sv = Sv - yi / di;
117
118 bs = bsCalculator(Sv, Option::Call);
119 ci = bs.value();
120 dc = bs.delta();
121
122 yi = ci - A;
123 di = dc - 0;
124 }
125 return Sv;
126 }
127 }
128
130 Real Sv = process_->x0();
131 Real X1 = strike();
134 Time T2 = secondExpiryTime();
135 Time t1 = firstExpiryTime();
137
138 Real val=X1-X2*std::exp(-r*(T2-t1));
139 if(A< val){
140 return std::numeric_limits<Real>::infinity();
141 } else {
143 Real ci = bs.value();
144 Real dc = bs.delta();
145
146 Real yi = ci - A - Sv + X1;
147 //da/ds = 1
148 Real di = dc - 1;
149 Real epsilon = 0.001;
150
151 //Newton-Raphson process
152 while (std::fabs(yi) > epsilon){
153 Sv = Sv - yi / di;
154
155 bs = bsCalculator(Sv, Option::Call);
156 ci = bs.value();
157 dc = bs.delta();
158
159 yi = ci - A - Sv + X1;
160 di = dc - 1;
161 }
162 return Sv;
163 }
164 }
165
167 Real Sv = process_->x0();
168 //Srtike
169 Real X1 = strike();
170 //Premium
172
174 Real pi = bs.value();
175 Real dc = bs.delta();
176
177 Real yi = pi - A + Sv - X1;
178 //da/ds = 1
179 Real di = dc - 1;
180 Real epsilon = 0.001;
181
182 //Newton-Raphson prosess
183 while (std::fabs(yi) > epsilon){
184 Sv = Sv - yi / di;
185
186 bs = bsCalculator(Sv, Option::Put);
187 pi = bs.value();
188 dc = bs.delta();
189
190 yi = pi - A + Sv - X1;
191 di = dc - 1;
192 }
193 return Sv;
194 }
195
197 Real Sv = process_->x0();
199 if(A==0){
200 return std::numeric_limits<Real>::infinity();
201 }
202 else{
204 Real pi = bs.value();
205 Real dc = bs.delta();
206
207 Real yi = pi - A;
208 //da/ds = 0
209 Real di = dc - 0;
210 Real epsilon = 0.001;
211
212 //Newton-Raphson prosess
213 while (std::fabs(yi) > epsilon){
214 Sv = Sv - yi / di;
215
216 bs = bsCalculator(Sv, Option::Put);
217 pi = bs.value();
218 dc = bs.delta();
219
220 yi = pi - A;
221 di = dc - 0;
222 }
223 return Sv;
224 }
225 }
226
227
229 Real spot, Option::Type optionType) const {
230 //Real spot = process_->x0();
231 Real vol;
232 DiscountFactor growth;
233 DiscountFactor discount;
235 Time T2 = secondExpiryTime();
236 Time t1 = firstExpiryTime();
237 Time t = T2 - t1;
238
239 //payoff
240 ext::shared_ptr<PlainVanillaPayoff > vanillaPayoff =
241 ext::make_shared<PlainVanillaPayoff>(optionType, X2);
242
243 //QuantLib requires sigma * sqrt(T) rather than just sigma/volatility
244 vol = volatility() * std::sqrt(t);
245 //calculate dividend discount factor assuming continuous compounding (e^-rt)
246 growth = dividendDiscount(t);
247 //calculate payoff discount factor assuming continuous compounding
248 discount = riskFreeDiscount(t);
249
250 BlackScholesCalculator bs(vanillaPayoff, spot, growth, vol, discount);
251 return bs;
252 }
253
256 return CmlNormDist(b, d) - CmlNormDist(a, d) - CmlNormDist(b, c) + CmlNormDist(a,c);
257 }
258
261 return NormDist(b) - NormDist(a);
262 }
263
265 ext::shared_ptr<PlainVanillaPayoff> payoff =
266 ext::dynamic_pointer_cast<PlainVanillaPayoff>(arguments_.payoff);
267 QL_REQUIRE(payoff, "non-plain payoff given");
268 return payoff->strike();
269 }
270
272 return process_->time(arguments_.exercise->lastDate());
273 }
274
277 }
278
280 return process_->blackVolatility()->blackVol(firstExpiryTime(), strike());
281 }
283 return process_->riskFreeRate()->zeroRate(firstExpiryTime(), Continuous,
285 }
287 return process_->dividendYield()->zeroRate(firstExpiryTime(),
289 }
290
292 return process_->dividendYield()->discount(t);
293 }
294
296 return process_->riskFreeRate()->discount(t);
297 }
298
300 Real S = process_->x0();
301 Real I2 = (type == Option::Call) ? I2Call() : I2Put();
302
304 Real vol = volatility();
305 Time t1 = firstExpiryTime();
306
307 return (log(S / I2) + (b + pow(vol, 2) / 2)*t1) / (vol*sqrt(t1));
308 }
309
311 Real S = process_->x0();
312 Real I1 = (type == Option::Call) ? I1Call() : I1Put();
313
315 Real vol = volatility();
316 Time t1 = firstExpiryTime();
317
318 return (log(S / I1) + (b + pow(vol, 2) / 2)*t1) / (vol*sqrt(t1));
319 }
320
322 Real S = process_->x0();
325 Real vol = volatility();
326 Time T2 = secondExpiryTime();
327
328 return (log(S / X2) + (b + pow(vol, 2) / 2)*T2) / (vol*sqrt(T2));
329 }
330
332 Real S = process_->x0();
333 Real X1 = strike();
334
336 Real vol = volatility();
337 Time t1 = firstExpiryTime();
338
339 return (log(S / X1) + (b + pow(vol, 2) / 2)*t1) / (vol*sqrt(t1));
340 }
341
342}
Analytic engine for holder-extensible options.
bivariate cumulative normal distribution
AnalyticHolderExtensibleOptionEngine(ext::shared_ptr< GeneralizedBlackScholesProcess > process)
BlackScholesCalculator bsCalculator(Real spot, Option::Type optionType) const
ext::shared_ptr< GeneralizedBlackScholesProcess > process_
Real M2(Real a, Real b, Real c, Real d, Real rho) const
Cumulative bivariate normal distribution function.
Black-Scholes 1973 calculator class.
Cumulative normal distribution function.
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Definition: observable.hpp:228
const DefaultType & t
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
Date d
Option exercise classes and payoff function.
ext::function< Real(Real)> b
@ NoFrequency
null frequency
Definition: frequency.hpp:37
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
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
Real rho
ext::shared_ptr< QuantLib::Payoff > payoff
Definition: any.hpp:35
STL namespace.
ext::shared_ptr< YieldTermStructure > r