QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
mcdoublebarrierengine.hpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2020 Lew Wei Hao
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
24#ifndef quantlib_mc_double_barrier_engines_hpp
25#define quantlib_mc_double_barrier_engines_hpp
26
27#include <ql/exercise.hpp>
28#include <ql/instruments/doublebarrieroption.hpp>
29#include <ql/pricingengines/mcsimulation.hpp>
30#include <ql/processes/blackscholesprocess.hpp>
31#include <utility>
32
33namespace QuantLib {
34
35 template <class RNG = PseudoRandom, class S = Statistics>
37 public McSimulation<SingleVariate,RNG,S> {
38 public:
43 // constructor
44 MCDoubleBarrierEngine(ext::shared_ptr<GeneralizedBlackScholesProcess> process,
45 Size timeSteps,
46 Size timeStepsPerYear,
47 bool brownianBridge,
48 bool antithetic,
49 Size requiredSamples,
50 Real requiredTolerance,
51 Size maxSamples,
52 BigNatural seed);
53 void calculate() const override {
54 Real spot = process_->x0();
55 QL_REQUIRE(spot > 0.0, "negative or null underlying given");
56 QL_REQUIRE(!triggered(spot), "barrier touched");
60 results_.value = this->mcModel_->sampleAccumulator().mean();
61 if (RNG::allowsErrorEstimate)
63 this->mcModel_->sampleAccumulator().errorEstimate();
64 }
65
66 protected:
67 // McSimulation implementation
68 TimeGrid timeGrid() const override;
69 ext::shared_ptr<path_generator_type> pathGenerator() const override {
70 TimeGrid grid = timeGrid();
71 typename RNG::rsg_type gen =
72 RNG::make_sequence_generator(grid.size()-1,seed_);
73 return ext::shared_ptr<path_generator_type>(
75 grid, gen, brownianBridge_));
76 }
77 ext::shared_ptr<path_pricer_type> pathPricer() const override;
78 // data members
79 ext::shared_ptr<GeneralizedBlackScholesProcess> process_;
86 };
87
89 template <class RNG = PseudoRandom, class S = Statistics>
91 public:
92 explicit MakeMCDoubleBarrierEngine(ext::shared_ptr<GeneralizedBlackScholesProcess>);
93 // named parameters
102 // conversion to pricing engine
103 operator ext::shared_ptr<PricingEngine>() const;
104 private:
105 ext::shared_ptr<GeneralizedBlackScholesProcess> process_;
106 bool brownianBridge_ = false, antithetic_ = false;
110 };
111
112 class DoubleBarrierPathPricer : public PathPricer<Path> {
113 public:
115 Real barrierLow,
116 Real barrieHigh,
117 Real rebate,
118 Option::Type type,
119 Real strike,
120 std::vector<DiscountFactor> discounts);
121 Real operator()(const Path& path) const override;
122
123 private:
129 std::vector<DiscountFactor> discounts_;
130 };
131
132 // template definitions
133
134 template <class RNG, class S>
136 ext::shared_ptr<GeneralizedBlackScholesProcess> process,
137 Size timeSteps,
138 Size timeStepsPerYear,
139 bool brownianBridge,
140 bool antitheticVariate,
141 Size requiredSamples,
142 Real requiredTolerance,
143 Size maxSamples,
144 BigNatural seed)
145 : McSimulation<SingleVariate, RNG, S>(antitheticVariate, false), process_(std::move(process)),
146 timeSteps_(timeSteps), timeStepsPerYear_(timeStepsPerYear), requiredSamples_(requiredSamples),
147 maxSamples_(maxSamples), requiredTolerance_(requiredTolerance),
148 brownianBridge_(brownianBridge), seed_(seed) {
149 QL_REQUIRE(timeSteps != Null<Size>() ||
150 timeStepsPerYear != Null<Size>(),
151 "no time steps provided");
152 QL_REQUIRE(timeSteps == Null<Size>() ||
153 timeStepsPerYear == Null<Size>(),
154 "both time steps and time steps per year were provided");
155 QL_REQUIRE(timeSteps != 0,
156 "timeSteps must be positive, " << timeSteps <<
157 " not allowed");
158 QL_REQUIRE(timeStepsPerYear != 0,
159 "timeStepsPerYear must be positive, " << timeStepsPerYear <<
160 " not allowed");
162 }
163
164 template <class RNG, class S>
166
167 Time residualTime = process_->time(arguments_.exercise->lastDate());
168 if (timeSteps_ != Null<Size>()) {
169 return TimeGrid(residualTime, timeSteps_);
170 } else if (timeStepsPerYear_ != Null<Size>()) {
171 Size steps = static_cast<Size>(timeStepsPerYear_*residualTime);
172 return TimeGrid(residualTime, std::max<Size>(steps, 1));
173 } else {
174 QL_FAIL("time steps not specified");
175 }
176 }
177
178 template <class RNG, class S>
179 inline
180 ext::shared_ptr<typename MCDoubleBarrierEngine<RNG,S>::path_pricer_type>
182 ext::shared_ptr<PlainVanillaPayoff> payoff =
183 ext::dynamic_pointer_cast<PlainVanillaPayoff>(arguments_.payoff);
184 QL_REQUIRE(payoff, "non-plain payoff given");
185
186 TimeGrid grid = timeGrid();
187 std::vector<DiscountFactor> discounts(grid.size());
188 for (Size i=0; i<grid.size(); i++)
189 discounts[i] = process_->riskFreeRate()->discount(grid[i]);
190
191 return ext::shared_ptr<
194 arguments_.barrierType,
195 arguments_.barrier_lo,
196 arguments_.barrier_hi,
197 arguments_.rebate,
198 payoff->optionType(),
199 payoff->strike(),
200 discounts));
201 }
202
203 template <class RNG, class S>
205 ext::shared_ptr<GeneralizedBlackScholesProcess> process)
206 : process_(std::move(process)), steps_(Null<Size>()), stepsPerYear_(Null<Size>()),
207 samples_(Null<Size>()), maxSamples_(Null<Size>()), tolerance_(Null<Real>()) {}
208
209 template <class RNG, class S>
212 steps_ = steps;
213 return *this;
214 }
215
216 template <class RNG, class S>
219 stepsPerYear_ = steps;
220 return *this;
221 }
222
223 template <class RNG, class S>
226 brownianBridge_ = brownianBridge;
227 return *this;
228 }
229
230 template <class RNG, class S>
233 antithetic_ = b;
234 return *this;
235 }
236
237 template <class RNG, class S>
240 QL_REQUIRE(tolerance_ == Null<Real>(),
241 "tolerance already set");
242 samples_ = samples;
243 return *this;
244 }
245
246 template <class RNG, class S>
249 QL_REQUIRE(samples_ == Null<Size>(),
250 "number of samples already set");
251 QL_REQUIRE(RNG::allowsErrorEstimate,
252 "chosen random generator policy "
253 "does not allow an error estimate");
254 tolerance_ = tolerance;
255 return *this;
256 }
257
258 template <class RNG, class S>
261 maxSamples_ = samples;
262 return *this;
263 }
264
265 template <class RNG, class S>
268 seed_ = seed;
269 return *this;
270 }
271
272 template <class RNG, class S>
273 inline
274 MakeMCDoubleBarrierEngine<RNG,S>::operator ext::shared_ptr<PricingEngine>()
275 const {
276 QL_REQUIRE(steps_ != Null<Size>() || stepsPerYear_ != Null<Size>(),
277 "number of steps not given");
278 QL_REQUIRE(steps_ == Null<Size>() || stepsPerYear_ == Null<Size>(),
279 "number of steps overspecified");
280 return ext::shared_ptr<PricingEngine>(new
282 steps_,
283 stepsPerYear_,
284 brownianBridge_,
285 antithetic_,
286 samples_,
287 tolerance_,
288 maxSamples_,
289 seed_));
290 }
291
292}
293
294
295#endif
Double-Barrier-option engine base class
std::vector< DiscountFactor > discounts_
Real operator()(const Path &path) const override
McSimulation< SingleVariate, RNG, S >::path_generator_type path_generator_type
MCDoubleBarrierEngine(ext::shared_ptr< GeneralizedBlackScholesProcess > process, Size timeSteps, Size timeStepsPerYear, bool brownianBridge, bool antithetic, Size requiredSamples, Real requiredTolerance, Size maxSamples, BigNatural seed)
ext::shared_ptr< path_generator_type > pathGenerator() const override
ext::shared_ptr< path_pricer_type > pathPricer() const override
McSimulation< SingleVariate, RNG, S >::path_pricer_type path_pricer_type
ext::shared_ptr< GeneralizedBlackScholesProcess > process_
Monte Carlo double-barrier-option engine factory.
MakeMCDoubleBarrierEngine & withAbsoluteTolerance(Real tolerance)
MakeMCDoubleBarrierEngine & withSeed(BigNatural seed)
MakeMCDoubleBarrierEngine & withSamples(Size samples)
MakeMCDoubleBarrierEngine & withBrownianBridge(bool b=true)
MakeMCDoubleBarrierEngine(ext::shared_ptr< GeneralizedBlackScholesProcess >)
MakeMCDoubleBarrierEngine & withMaxSamples(Size samples)
MakeMCDoubleBarrierEngine & withSteps(Size steps)
MakeMCDoubleBarrierEngine & withAntitheticVariate(bool b=true)
MakeMCDoubleBarrierEngine & withStepsPerYear(Size steps)
ext::shared_ptr< GeneralizedBlackScholesProcess > process_
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
time grid class
Definition: timegrid.hpp:43
Size size() const
Definition: timegrid.hpp:164
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
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