QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
mcbarrierengine.hpp
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) 2003, 2004 Neil Firth
5 Copyright (C) 2003, 2004 Ferdinando Ametrano
6 Copyright (C) 2003, 2004, 2005, 2007, 2008 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/*! \file mcbarrierengine.hpp
23 \brief Monte Carlo barrier option engines
24*/
25
26#ifndef quantlib_mc_barrier_engines_hpp
27#define quantlib_mc_barrier_engines_hpp
28
29#include <ql/exercise.hpp>
33#include <utility>
34
35namespace QuantLib {
36
37 //! Pricing engine for barrier options using Monte Carlo simulation
38 /*! Uses the Brownian-bridge correction for the barrier found in
39 <i>
40 Going to Extremes: Correcting Simulation Bias in Exotic
41 Option Valuation - D.R. Beaglehole, P.H. Dybvig and G. Zhou
42 Financial Analysts Journal; Jan/Feb 1997; 53, 1. pg. 62-68
43 </i>
44 and
45 <i>
46 Simulating path-dependent options: A new approach -
47 M. El Babsiri and G. Noel
48 Journal of Derivatives; Winter 1998; 6, 2; pg. 65-83
49 </i>
50
51 \ingroup barrierengines
52
53 \test the correctness of the returned value is tested by
54 reproducing results available in literature.
55 */
56 template <class RNG = PseudoRandom, class S = Statistics>
58 public McSimulation<SingleVariate,RNG,S> {
59 public:
60 typedef
67 // constructor
68 MCBarrierEngine(ext::shared_ptr<GeneralizedBlackScholesProcess> process,
69 Size timeSteps,
70 Size timeStepsPerYear,
71 bool brownianBridge,
72 bool antitheticVariate,
73 Size requiredSamples,
74 Real requiredTolerance,
75 Size maxSamples,
76 bool isBiased,
77 BigNatural seed);
78 void calculate() const override {
79 Real spot = process_->x0();
80 QL_REQUIRE(spot > 0.0, "negative or null underlying given");
81 QL_REQUIRE(!triggered(spot), "barrier touched");
85 results_.value = this->mcModel_->sampleAccumulator().mean();
86 if (RNG::allowsErrorEstimate)
88 this->mcModel_->sampleAccumulator().errorEstimate();
89 }
90
91 protected:
92 // McSimulation implementation
93 TimeGrid timeGrid() const override;
94 ext::shared_ptr<path_generator_type> pathGenerator() const override {
95 TimeGrid grid = timeGrid();
96 typename RNG::rsg_type gen =
97 RNG::make_sequence_generator(grid.size()-1,seed_);
98 return ext::shared_ptr<path_generator_type>(
100 grid, gen, brownianBridge_));
101 }
102 ext::shared_ptr<path_pricer_type> pathPricer() const override;
103 // data members
104 ext::shared_ptr<GeneralizedBlackScholesProcess> process_;
111 };
112
113
114 //! Monte Carlo barrier-option engine factory
115 template <class RNG = PseudoRandom, class S = Statistics>
117 public:
118 MakeMCBarrierEngine(ext::shared_ptr<GeneralizedBlackScholesProcess>);
119 // named parameters
127 MakeMCBarrierEngine& withBias(bool b = true);
129 // conversion to pricing engine
130 operator ext::shared_ptr<PricingEngine>() const;
131 private:
132 ext::shared_ptr<GeneralizedBlackScholesProcess> process_;
133 bool brownianBridge_ = false, antithetic_ = false, biased_ = false;
137 };
138
139
140 class BarrierPathPricer : public PathPricer<Path> {
141 public:
143 Real barrier,
144 Real rebate,
145 Option::Type type,
146 Real strike,
147 std::vector<DiscountFactor> discounts,
148 ext::shared_ptr<StochasticProcess1D> diffProcess,
149 PseudoRandom::ursg_type sequenceGen);
150 Real operator()(const Path& path) const override;
151
152 private:
156 ext::shared_ptr<StochasticProcess1D> diffProcess_;
159 std::vector<DiscountFactor> discounts_;
160 };
161
162
163 class BiasedBarrierPathPricer : public PathPricer<Path> {
164 public:
166 Real barrier,
167 Real rebate,
168 Option::Type type,
169 Real strike,
170 std::vector<DiscountFactor> discounts);
171 Real operator()(const Path& path) const override;
172
173 private:
178 std::vector<DiscountFactor> discounts_;
179 };
180
181
182
183 // template definitions
184
185 template <class RNG, class S>
187 ext::shared_ptr<GeneralizedBlackScholesProcess> process,
188 Size timeSteps,
189 Size timeStepsPerYear,
190 bool brownianBridge,
191 bool antitheticVariate,
192 Size requiredSamples,
193 Real requiredTolerance,
194 Size maxSamples,
195 bool isBiased,
196 BigNatural seed)
197 : McSimulation<SingleVariate, RNG, S>(antitheticVariate, false), process_(std::move(process)),
198 timeSteps_(timeSteps), timeStepsPerYear_(timeStepsPerYear), requiredSamples_(requiredSamples),
199 maxSamples_(maxSamples), requiredTolerance_(requiredTolerance), isBiased_(isBiased),
200 brownianBridge_(brownianBridge), seed_(seed) {
201 QL_REQUIRE(timeSteps != Null<Size>() ||
202 timeStepsPerYear != Null<Size>(),
203 "no time steps provided");
204 QL_REQUIRE(timeSteps == Null<Size>() ||
205 timeStepsPerYear == Null<Size>(),
206 "both time steps and time steps per year were provided");
207 QL_REQUIRE(timeSteps != 0,
208 "timeSteps must be positive, " << timeSteps <<
209 " not allowed");
210 QL_REQUIRE(timeStepsPerYear != 0,
211 "timeStepsPerYear must be positive, " << timeStepsPerYear <<
212 " not allowed");
214 }
215
216 template <class RNG, class S>
218
219 Time residualTime = process_->time(arguments_.exercise->lastDate());
220 if (timeSteps_ != Null<Size>()) {
221 return TimeGrid(residualTime, timeSteps_);
222 } else if (timeStepsPerYear_ != Null<Size>()) {
223 Size steps = static_cast<Size>(timeStepsPerYear_*residualTime);
224 return TimeGrid(residualTime, std::max<Size>(steps, 1));
225 } else {
226 QL_FAIL("time steps not specified");
227 }
228 }
229
230
231 template <class RNG, class S>
232 inline
233 ext::shared_ptr<typename MCBarrierEngine<RNG,S>::path_pricer_type>
235 ext::shared_ptr<PlainVanillaPayoff> payoff =
236 ext::dynamic_pointer_cast<PlainVanillaPayoff>(arguments_.payoff);
237 QL_REQUIRE(payoff, "non-plain payoff given");
238
239 TimeGrid grid = timeGrid();
240 std::vector<DiscountFactor> discounts(grid.size());
241 for (Size i=0; i<grid.size(); i++)
242 discounts[i] = process_->riskFreeRate()->discount(grid[i]);
243
244 // do this with template parameters?
245 if (isBiased_) {
246 return ext::shared_ptr<
249 arguments_.barrierType,
250 arguments_.barrier,
251 arguments_.rebate,
252 payoff->optionType(),
253 payoff->strike(),
254 discounts));
255 } else {
256 PseudoRandom::ursg_type sequenceGen(grid.size()-1,
258 return ext::shared_ptr<
261 arguments_.barrierType,
262 arguments_.barrier,
263 arguments_.rebate,
264 payoff->optionType(),
265 payoff->strike(),
266 discounts,
267 process_,
268 sequenceGen));
269 }
270 }
271
272
273 template <class RNG, class S>
275 ext::shared_ptr<GeneralizedBlackScholesProcess> process)
276 : process_(std::move(process)), steps_(Null<Size>()), stepsPerYear_(Null<Size>()),
277 samples_(Null<Size>()), maxSamples_(Null<Size>()), tolerance_(Null<Real>()) {}
278
279 template <class RNG, class S>
282 steps_ = steps;
283 return *this;
284 }
285
286 template <class RNG, class S>
289 stepsPerYear_ = steps;
290 return *this;
291 }
292
293 template <class RNG, class S>
296 brownianBridge_ = brownianBridge;
297 return *this;
298 }
299
300 template <class RNG, class S>
303 antithetic_ = b;
304 return *this;
305 }
306
307 template <class RNG, class S>
310 QL_REQUIRE(tolerance_ == Null<Real>(),
311 "tolerance already set");
312 samples_ = samples;
313 return *this;
314 }
315
316 template <class RNG, class S>
319 QL_REQUIRE(samples_ == Null<Size>(),
320 "number of samples already set");
321 QL_REQUIRE(RNG::allowsErrorEstimate,
322 "chosen random generator policy "
323 "does not allow an error estimate");
324 tolerance_ = tolerance;
325 return *this;
326 }
327
328 template <class RNG, class S>
331 maxSamples_ = samples;
332 return *this;
333 }
334
335 template <class RNG, class S>
338 biased_ = biased;
339 return *this;
340 }
341
342 template <class RNG, class S>
345 seed_ = seed;
346 return *this;
347 }
348
349 template <class RNG, class S>
350 inline
351 MakeMCBarrierEngine<RNG,S>::operator ext::shared_ptr<PricingEngine>()
352 const {
353 QL_REQUIRE(steps_ != Null<Size>() || stepsPerYear_ != Null<Size>(),
354 "number of steps not given");
355 QL_REQUIRE(steps_ == Null<Size>() || stepsPerYear_ == Null<Size>(),
356 "number of steps overspecified");
357 return ext::shared_ptr<PricingEngine>(new
358 MCBarrierEngine<RNG,S>(process_,
359 steps_,
360 stepsPerYear_,
361 brownianBridge_,
362 antithetic_,
363 samples_, tolerance_,
364 maxSamples_,
365 biased_,
366 seed_));
367 }
368
369}
370
371
372#endif
Barrier option on a single asset.
Black-Scholes processes.
Barrier-option engine base class
bool triggered(Real underlying) const
std::vector< DiscountFactor > discounts_
PseudoRandom::ursg_type sequenceGen_
Real operator()(const Path &path) const override
ext::shared_ptr< StochasticProcess1D > diffProcess_
std::vector< DiscountFactor > discounts_
Real operator()(const Path &path) const override
Pricing engine for barrier options using Monte Carlo simulation.
McSimulation< SingleVariate, RNG, S >::path_generator_type path_generator_type
ext::shared_ptr< path_generator_type > pathGenerator() const override
ext::shared_ptr< path_pricer_type > pathPricer() const override
void calculate() const override
McSimulation< SingleVariate, RNG, S >::stats_type stats_type
MCBarrierEngine(ext::shared_ptr< GeneralizedBlackScholesProcess > process, Size timeSteps, Size timeStepsPerYear, bool brownianBridge, bool antitheticVariate, Size requiredSamples, Real requiredTolerance, Size maxSamples, bool isBiased, BigNatural seed)
McSimulation< SingleVariate, RNG, S >::path_pricer_type path_pricer_type
ext::shared_ptr< GeneralizedBlackScholesProcess > process_
TimeGrid timeGrid() const override
Monte Carlo barrier-option engine factory.
MakeMCBarrierEngine & withSamples(Size samples)
MakeMCBarrierEngine & withSeed(BigNatural seed)
MakeMCBarrierEngine & withMaxSamples(Size samples)
MakeMCBarrierEngine & withBrownianBridge(bool b=true)
MakeMCBarrierEngine & withBias(bool b=true)
MakeMCBarrierEngine & withSteps(Size steps)
MakeMCBarrierEngine & withStepsPerYear(Size steps)
MakeMCBarrierEngine & withAbsoluteTolerance(Real tolerance)
ext::shared_ptr< GeneralizedBlackScholesProcess > process_
MakeMCBarrierEngine(ext::shared_ptr< GeneralizedBlackScholesProcess >)
MakeMCBarrierEngine & withAntitheticVariate(bool b=true)
base class for Monte Carlo engines
MonteCarloModel< MC, RNG, S >::path_generator_type path_generator_type
ext::shared_ptr< MonteCarloModel< MC, RNG, S > > mcModel_
void calculate(Real requiredTolerance, Size requiredSamples, Size maxSamples) const
basic calculate method provided to inherited pricing engines
MonteCarloModel< MC, RNG, S >::path_pricer_type path_pricer_type
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
single-factor random walk
Definition: path.hpp:40
base class for path pricers
Definition: pathpricer.hpp:40
Plain-vanilla payoff.
Definition: payoffs.hpp:105
Random sequence generator based on a pseudo-random number generator.
time grid class
Definition: timegrid.hpp:43
Size size() const
Definition: timegrid.hpp:164
#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.
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
ext::shared_ptr< QuantLib::Payoff > payoff
framework for Monte Carlo engines
Definition: any.hpp:35
unsigned QL_BIG_INTEGER BigNatural
large positive integer
Definition: types.hpp:46
STL namespace.
default Monte Carlo traits for single-variate models
Definition: mctraits.hpp:39