QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
fdblackscholesvanillaengine.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2008 Andreas Gaida
5 Copyright (C) 2008, 2009 Ralph Schreyer
6 Copyright (C) 2008, 2009 Klaus Spanderen
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/exercise.hpp>
23#include <ql/methods/finitedifferences/meshers/fdmblackscholesmesher.hpp>
24#include <ql/methods/finitedifferences/utilities/escroweddividendadjustment.hpp>
25#include <ql/methods/finitedifferences/meshers/fdmmeshercomposite.hpp>
26#include <ql/methods/finitedifferences/operators/fdmlinearoplayout.hpp>
27#include <ql/methods/finitedifferences/solvers/fdmblackscholessolver.hpp>
28#include <ql/methods/finitedifferences/stepconditions/fdmstepconditioncomposite.hpp>
29#include <ql/methods/finitedifferences/utilities/fdminnervaluecalculator.hpp>
30#include <ql/methods/finitedifferences/utilities/fdmescrowedloginnervaluecalculator.hpp>
31#include <ql/methods/finitedifferences/utilities/fdmquantohelper.hpp>
32#include <ql/pricingengines/vanilla/fdblackscholesvanillaengine.hpp>
33#include <ql/processes/blackscholesprocess.hpp>
34
35namespace QuantLib {
36
38 ext::shared_ptr<GeneralizedBlackScholesProcess> process,
39 Size tGrid,
40 Size xGrid,
41 Size dampingSteps,
42 const FdmSchemeDesc& schemeDesc,
43 bool localVol,
44 Real illegalLocalVolOverwrite,
45 CashDividendModel cashDividendModel)
46 : process_(std::move(process)), explicitDividends_(false), tGrid_(tGrid), xGrid_(xGrid),
47 dampingSteps_(dampingSteps), schemeDesc_(schemeDesc), localVol_(localVol),
48 illegalLocalVolOverwrite_(illegalLocalVolOverwrite), cashDividendModel_(cashDividendModel) {
50 }
51
53 ext::shared_ptr<GeneralizedBlackScholesProcess> process,
54 DividendSchedule dividends,
55 Size tGrid,
56 Size xGrid,
57 Size dampingSteps,
58 const FdmSchemeDesc& schemeDesc,
59 bool localVol,
60 Real illegalLocalVolOverwrite,
61 CashDividendModel cashDividendModel)
62 : process_(std::move(process)), dividends_(std::move(dividends)), explicitDividends_(true),
63 tGrid_(tGrid), xGrid_(xGrid), dampingSteps_(dampingSteps), schemeDesc_(schemeDesc),
64 localVol_(localVol), illegalLocalVolOverwrite_(illegalLocalVolOverwrite),
65 cashDividendModel_(cashDividendModel) {
67 }
68
70 ext::shared_ptr<GeneralizedBlackScholesProcess> process,
71 ext::shared_ptr<FdmQuantoHelper> quantoHelper,
72 Size tGrid,
73 Size xGrid,
74 Size dampingSteps,
75 const FdmSchemeDesc& schemeDesc,
76 bool localVol,
77 Real illegalLocalVolOverwrite,
78 CashDividendModel cashDividendModel)
79 : process_(std::move(process)), explicitDividends_(false),
80 tGrid_(tGrid), xGrid_(xGrid), dampingSteps_(dampingSteps),
81 schemeDesc_(schemeDesc), localVol_(localVol),
82 illegalLocalVolOverwrite_(illegalLocalVolOverwrite), quantoHelper_(std::move(quantoHelper)),
83 cashDividendModel_(cashDividendModel) {
86 }
87
89 ext::shared_ptr<GeneralizedBlackScholesProcess> process,
90 DividendSchedule dividends,
91 ext::shared_ptr<FdmQuantoHelper> quantoHelper,
92 Size tGrid,
93 Size xGrid,
94 Size dampingSteps,
95 const FdmSchemeDesc& schemeDesc,
96 bool localVol,
97 Real illegalLocalVolOverwrite,
98 CashDividendModel cashDividendModel)
99 : process_(std::move(process)), dividends_(std::move(dividends)), explicitDividends_(true),
100 tGrid_(tGrid), xGrid_(xGrid), dampingSteps_(dampingSteps),
101 schemeDesc_(schemeDesc), localVol_(localVol),
102 illegalLocalVolOverwrite_(illegalLocalVolOverwrite), quantoHelper_(std::move(quantoHelper)),
103 cashDividendModel_(cashDividendModel) {
106 }
107
108
110
111 // dividends will eventually be moved out of arguments, but for now we need the switch
112 QL_DEPRECATED_DISABLE_WARNING
114 QL_DEPRECATED_ENABLE_WARNING
115
116 // 0. Cash dividend model
117 const Date exerciseDate = arguments_.exercise->lastDate();
118 const Time maturity = process_->time(exerciseDate);
119 const Date settlementDate = process_->riskFreeRate()->referenceDate();
120
121 Real spotAdjustment = 0.0;
122 DividendSchedule dividendSchedule = DividendSchedule();
123
124 ext::shared_ptr<EscrowedDividendAdjustment> escrowedDivAdj;
125
126 switch (cashDividendModel_) {
127 case Spot:
128 dividendSchedule = passedDividends;
129 break;
130 case Escrowed:
131 if (arguments_.exercise->type() != Exercise::European)
132 // add dividend dates as stopping times
133 for (const auto& cf: passedDividends)
134 dividendSchedule.push_back(
135 ext::make_shared<FixedDividend>(0.0, cf->date()));
136
137 QL_REQUIRE(quantoHelper_ == nullptr,
138 "Escrowed dividend model is not supported for Quanto-Options");
139
140 escrowedDivAdj = ext::make_shared<EscrowedDividendAdjustment>(
141 passedDividends,
142 process_->riskFreeRate(),
143 process_->dividendYield(),
144 [&](Date d){ return process_->time(d); },
145 maturity
146 );
147
148 spotAdjustment =
149 escrowedDivAdj->dividendAdjustment(process_->time(settlementDate));
150
151 QL_REQUIRE(process_->x0() + spotAdjustment > 0.0,
152 "spot minus dividends becomes negative");
153
154 break;
155 default:
156 QL_FAIL("unknwon cash dividend model");
157 }
158
159 // 1. Mesher
160 const ext::shared_ptr<StrikedTypePayoff> payoff =
161 ext::dynamic_pointer_cast<StrikedTypePayoff>(arguments_.payoff);
162
163 const ext::shared_ptr<Fdm1dMesher> equityMesher =
164 ext::make_shared<FdmBlackScholesMesher>(
165 xGrid_, process_, maturity, payoff->strike(),
166 Null<Real>(), Null<Real>(), 0.0001, 1.5,
167 std::pair<Real, Real>(payoff->strike(), 0.1),
168 dividendSchedule, quantoHelper_,
169 spotAdjustment);
170
171 const ext::shared_ptr<FdmMesher> mesher =
172 ext::make_shared<FdmMesherComposite>(equityMesher);
173
174 // 2. Calculator
175 ext::shared_ptr<FdmInnerValueCalculator> calculator;
176 switch (cashDividendModel_) {
177 case Spot:
178 calculator = ext::make_shared<FdmLogInnerValue>(
179 payoff, mesher, 0);
180 break;
181 case Escrowed:
182 calculator = ext::make_shared<FdmEscrowedLogInnerValueCalculator>(
183 escrowedDivAdj, payoff, mesher, 0);
184 break;
185 default:
186 QL_FAIL("unknwon cash dividend model");
187 }
188
189 // 3. Step conditions
190 const ext::shared_ptr<FdmStepConditionComposite> conditions =
192 dividendSchedule, arguments_.exercise, mesher, calculator,
193 process_->riskFreeRate()->referenceDate(),
194 process_->riskFreeRate()->dayCounter());
195
196 // 4. Boundary conditions
197 const FdmBoundaryConditionSet boundaries;
198
199 // 5. Solver
200 FdmSolverDesc solverDesc = { mesher, boundaries, conditions, calculator,
201 maturity, tGrid_, dampingSteps_ };
202
203 const ext::shared_ptr<FdmBlackScholesSolver> solver(
204 ext::make_shared<FdmBlackScholesSolver>(
206 payoff->strike(), solverDesc, schemeDesc_,
209
210 const Real spot = process_->x0() + spotAdjustment;
211
212 results_.value = solver->valueAt(spot);
213 results_.delta = solver->deltaAt(spot);
214 results_.gamma = solver->gammaAt(spot);
215 results_.theta = solver->thetaAt(spot);
216 }
217
219 ext::shared_ptr<GeneralizedBlackScholesProcess> process)
220 : process_(std::move(process)),
221 schemeDesc_(ext::make_shared<FdmSchemeDesc>(FdmSchemeDesc::Douglas())),
222 illegalLocalVolOverwrite_(-Null<Real>()) {}
223
226 const ext::shared_ptr<FdmQuantoHelper>& quantoHelper) {
227 quantoHelper_ = quantoHelper;
228 return *this;
229 }
230
233 tGrid_ = tGrid;
234 return *this;
235 }
236
239 xGrid_ = xGrid;
240 return *this;
241 }
242
245 dampingSteps_ = dampingSteps;
246 return *this;
247 }
248
251 const FdmSchemeDesc& schemeDesc) {
252 schemeDesc_ = ext::make_shared<FdmSchemeDesc>(schemeDesc);
253 return *this;
254 }
255
258 localVol_ = localVol;
259 return *this;
260 }
261
264 Real illegalLocalVolOverwrite) {
265 illegalLocalVolOverwrite_ = illegalLocalVolOverwrite;
266 return *this;
267 }
268
271 const std::vector<Date>& dividendDates,
272 const std::vector<Real>& dividendAmounts) {
273 dividends_ = DividendVector(dividendDates, dividendAmounts);
274 explicitDividends_ = true;
275 return *this;
276 }
277
281 cashDividendModel_ = cashDividendModel;
282 return *this;
283 }
284
285 MakeFdBlackScholesVanillaEngine::operator
286 ext::shared_ptr<PricingEngine>() const {
287 if (explicitDividends_) {
288 return ext::make_shared<FdBlackScholesVanillaEngine>(
289 process_,
290 dividends_,
291 quantoHelper_,
292 tGrid_, xGrid_, dampingSteps_,
293 *schemeDesc_,
294 localVol_,
295 illegalLocalVolOverwrite_,
296 cashDividendModel_);
297 } else {
298 return ext::make_shared<FdBlackScholesVanillaEngine>(
299 process_,
300 quantoHelper_,
301 tGrid_, xGrid_, dampingSteps_,
302 *schemeDesc_,
303 localVol_,
304 illegalLocalVolOverwrite_,
305 cashDividendModel_);
306 }
307 }
308
309}
Concrete date class.
Definition: date.hpp:125
ext::shared_ptr< GeneralizedBlackScholesProcess > process_
ext::shared_ptr< FdmQuantoHelper > quantoHelper_
FdBlackScholesVanillaEngine(ext::shared_ptr< GeneralizedBlackScholesProcess >, Size tGrid=100, Size xGrid=100, Size dampingSteps=0, const FdmSchemeDesc &schemeDesc=FdmSchemeDesc::Douglas(), bool localVol=false, Real illegalLocalVolOverwrite=-Null< Real >(), CashDividendModel cashDividendModel=Spot)
static ext::shared_ptr< FdmStepConditionComposite > vanillaComposite(const DividendSchedule &schedule, const ext::shared_ptr< Exercise > &exercise, const ext::shared_ptr< FdmMesher > &mesher, const ext::shared_ptr< FdmInnerValueCalculator > &calculator, const Date &refDate, const DayCounter &dayCounter)
Shared handle to an observable.
Definition: handle.hpp:41
MakeFdBlackScholesVanillaEngine & withIllegalLocalVolOverwrite(Real illegalLocalVolOverwrite)
MakeFdBlackScholesVanillaEngine & withLocalVol(bool localVol)
MakeFdBlackScholesVanillaEngine & withCashDividendModel(FdBlackScholesVanillaEngine::CashDividendModel cashDividendModel)
MakeFdBlackScholesVanillaEngine & withTGrid(Size tGrid)
MakeFdBlackScholesVanillaEngine(ext::shared_ptr< GeneralizedBlackScholesProcess > process)
FdBlackScholesVanillaEngine::CashDividendModel cashDividendModel_
MakeFdBlackScholesVanillaEngine & withDampingSteps(Size dampingSteps)
MakeFdBlackScholesVanillaEngine & withQuantoHelper(const ext::shared_ptr< FdmQuantoHelper > &quantoHelper)
MakeFdBlackScholesVanillaEngine & withXGrid(Size xGrid)
MakeFdBlackScholesVanillaEngine & withCashDividends(const std::vector< Date > &dividendDates, const std::vector< Real > &dividendAmounts)
MakeFdBlackScholesVanillaEngine & withFdmSchemeDesc(const FdmSchemeDesc &schemeDesc)
template class providing a null value for a given type.
Definition: null.hpp:76
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Definition: observable.hpp:228
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
std::vector< ext::shared_ptr< Dividend > > DividendSchedule
std::vector< ext::shared_ptr< Dividend > > DividendVector(const std::vector< Date > &dividendDates, const std::vector< Real > &dividends)
helper function building a sequence of fixed dividends
Definition: dividend.cpp:35
OperatorTraits< FdmLinearOp >::bc_set FdmBoundaryConditionSet
STL namespace.