QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
mcpathbasketengine.hpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2008 Andrea Odetti
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_path_basket_engine_hpp
25#define quantlib_mc_path_basket_engine_hpp
26
27#include <ql/experimental/mcbasket/pathmultiassetoption.hpp>
28#include <ql/experimental/mcbasket/pathpayoff.hpp>
29#include <ql/pricingengines/mcsimulation.hpp>
30#include <ql/processes/blackscholesprocess.hpp>
31#include <ql/processes/stochasticprocessarray.hpp>
32#include <ql/termstructures/yield/impliedtermstructure.hpp>
33#include <ql/timegrid.hpp>
34#include <utility>
35
36namespace QuantLib {
37
39 // Monte Carlo simulation
40 template <class RNG = PseudoRandom, class S = Statistics>
42 public McSimulation<MultiVariate,RNG,S> {
43 public:
50 // constructor
51 MCPathBasketEngine(ext::shared_ptr<StochasticProcessArray>,
52 Size timeSteps,
53 Size timeStepsPerYear,
54 bool brownianBridge,
55 bool antitheticVariate,
56 bool controlVariate,
57 Size requiredSamples,
58 Real requiredTolerance,
59 Size maxSamples,
60 BigNatural seed);
61
62 void calculate() const override {
66 results_.value = this->mcModel_->sampleAccumulator().mean();
67 if (RNG::allowsErrorEstimate)
69 this->mcModel_->sampleAccumulator().errorEstimate();
70 }
71
72 protected:
73
74 // McSimulation implementation
75 TimeGrid timeGrid() const;
76 ext::shared_ptr<path_generator_type> pathGenerator() const;
77 ext::shared_ptr<path_pricer_type> pathPricer() const;
78
79 // data members
80 ext::shared_ptr<StochasticProcessArray> process_;
88 };
89
90
91 class EuropeanPathMultiPathPricer : public PathPricer<MultiPath> {
92 public:
93 EuropeanPathMultiPathPricer(ext::shared_ptr<PathPayoff>& payoff,
94 std::vector<Size> timePositions,
95 std::vector<Handle<YieldTermStructure> > forwardTermStructures,
96 Array discounts);
97 Real operator()(const MultiPath& multiPath) const override;
98
99 private:
100 ext::shared_ptr<PathPayoff> payoff_;
101 std::vector<Size> timePositions_;
102 std::vector<Handle<YieldTermStructure> > forwardTermStructures_;
104 };
105
106
107 // template definitions
108
109 template <class RNG, class S>
111 ext::shared_ptr<StochasticProcessArray> process,
112 Size timeSteps,
113 Size timeStepsPerYear,
114 bool brownianBridge,
115 bool antitheticVariate,
116 bool controlVariate,
117 Size requiredSamples,
118 Real requiredTolerance,
119 Size maxSamples,
120 BigNatural seed)
121 : McSimulation<MultiVariate, RNG, S>(antitheticVariate, controlVariate),
122 process_(std::move(process)), timeSteps_(timeSteps), timeStepsPerYear_(timeStepsPerYear),
123 requiredSamples_(requiredSamples), maxSamples_(maxSamples),
124 requiredTolerance_(requiredTolerance), brownianBridge_(brownianBridge), seed_(seed) {
125 QL_REQUIRE(timeSteps != Null<Size>() ||
126 timeStepsPerYear != Null<Size>(),
127 "no time steps provided");
128 QL_REQUIRE(timeSteps == Null<Size>() ||
129 timeStepsPerYear == Null<Size>(),
130 "both time steps and time steps per year were provided");
131 QL_REQUIRE(timeSteps != 0,
132 "timeSteps must be positive, " << timeSteps <<
133 " not allowed");
134 QL_REQUIRE(timeStepsPerYear != 0,
135 "timeStepsPerYear must be positive, "
136 << timeStepsPerYear << " not allowed");
137 this->registerWith(process_);
138 }
139
140
141 template<class RNG, class S>
142 inline
143 ext::shared_ptr<typename MCPathBasketEngine<RNG,S>::path_generator_type>
145
146 ext::shared_ptr<PathPayoff> payoff = arguments_.payoff;
147 QL_REQUIRE(payoff, "non-basket payoff given");
148
149 Size numAssets = process_->size();
150
151 TimeGrid grid = timeGrid();
152
153 typename RNG::rsg_type gen =
154 RNG::make_sequence_generator(numAssets * (grid.size() - 1), seed_);
155
156 return ext::shared_ptr<path_generator_type>(
157 new path_generator_type(process_,
158 grid, gen, brownianBridge_));
159 }
160
161 template <class RNG, class S>
163 const std::vector<Date> & fixings = this->arguments_.fixingDates;
164 const Size numberOfFixings = fixings.size();
165
166 std::vector<Time> fixingTimes(numberOfFixings);
167 for (Size i = 0; i < numberOfFixings; ++i) {
168 fixingTimes[i] =
169 this->process_->time(fixings[i]);
170 }
171
172 const Size numberOfTimeSteps = timeSteps_ != Null<Size>() ? timeSteps_ : static_cast<Size>(timeStepsPerYear_ * fixingTimes.back());
173
174 return TimeGrid(fixingTimes.begin(), fixingTimes.end(), numberOfTimeSteps);
175 }
176
177 template <class RNG, class S>
178 inline
179 ext::shared_ptr<typename MCPathBasketEngine<RNG,S>::path_pricer_type>
181
182 ext::shared_ptr<PathPayoff> payoff = arguments_.payoff;
183 QL_REQUIRE(payoff, "non-basket payoff given");
184
185 ext::shared_ptr<GeneralizedBlackScholesProcess> process =
186 ext::dynamic_pointer_cast<GeneralizedBlackScholesProcess>(
187 process_->process(0));
188 QL_REQUIRE(process, "Black-Scholes process required");
189
190 const TimeGrid theTimeGrid = timeGrid();
191
192 const std::vector<Time> & times = theTimeGrid.mandatoryTimes();
193 const Size numberOfTimes = times.size();
194
195 const std::vector<Date> & fixings = this->arguments_.fixingDates;
196
197 QL_REQUIRE(fixings.size() == numberOfTimes, "Invalid dates/times");
198
199 std::vector<Size> timePositions(numberOfTimes);
200 Array discountFactors(numberOfTimes);
201 std::vector<Handle<YieldTermStructure> > forwardTermStructures(numberOfTimes);
202
203 const Handle<YieldTermStructure> & riskFreeRate = process->riskFreeRate();
204
205 for (Size i = 0; i < numberOfTimes; ++i) {
206 timePositions[i] = theTimeGrid.index(times[i]);
207 discountFactors[i] = riskFreeRate->discount(times[i]);
208 forwardTermStructures[i] = Handle<YieldTermStructure>(
209 ext::make_shared<ImpliedTermStructure>(riskFreeRate,
210 fixings[i]));
211 }
212
213 return ext::shared_ptr<
215 new EuropeanPathMultiPathPricer(payoff, timePositions,
216 forwardTermStructures,
217 discountFactors));
218 }
219
220
222 template <class RNG = PseudoRandom, class S = Statistics>
224 public:
225 explicit MakeMCPathBasketEngine(ext::shared_ptr<StochasticProcessArray>);
226 // named parameters
236 // conversion to pricing engine
237 operator ext::shared_ptr<PricingEngine>() const;
238 private:
239 ext::shared_ptr<StochasticProcessArray> process_;
240 bool antithetic_ = false, controlVariate_ = false;
243 bool brownianBridge_ = false;
245 };
246
247 template <class RNG, class S>
249 ext::shared_ptr<StochasticProcessArray> process)
250 : process_(std::move(process)), steps_(Null<Size>()), stepsPerYear_(Null<Size>()),
251 samples_(Null<Size>()), maxSamples_(Null<Size>()), tolerance_(Null<Real>()) {}
252
253 template <class RNG, class S>
256 steps_ = steps;
257 return *this;
258 }
259
260 template <class RNG, class S>
263 stepsPerYear_ = steps;
264 return *this;
265 }
266
267 template <class RNG, class S>
270 QL_REQUIRE(tolerance_ == Null<Real>(),
271 "tolerance already set");
272 samples_ = samples;
273 return *this;
274 }
275
276 template <class RNG, class S>
279 QL_REQUIRE(samples_ == Null<Size>(),
280 "number of samples already set");
281 QL_REQUIRE(RNG::allowsErrorEstimate,
282 "chosen random generator policy "
283 "does not allow an error estimate");
284 tolerance_ = tolerance;
285 return *this;
286 }
287
288 template <class RNG, class S>
291 maxSamples_ = samples;
292 return *this;
293 }
294
295 template <class RNG, class S>
298 seed_ = seed;
299 return *this;
300 }
301
302 template <class RNG, class S>
305 brownianBridge_ = brownianBridge;
306 return *this;
307 }
308
309 template <class RNG, class S>
312 antithetic_ = b;
313 return *this;
314 }
315
316 template <class RNG, class S>
319 controlVariate_ = b;
320 return *this;
321 }
322
323 template <class RNG, class S>
324 inline
325 MakeMCPathBasketEngine<RNG,S>::operator ext::shared_ptr<PricingEngine>()
326 const {
327 return ext::shared_ptr<PricingEngine>(new
329 steps_,
330 stepsPerYear_,
331 brownianBridge_,
332 antithetic_,
333 controlVariate_,
334 samples_,
335 tolerance_,
336 maxSamples_,
337 seed_));
338 }
339
340}
341
342
343#endif
1-D array used in linear algebra.
Definition: array.hpp:52
ext::shared_ptr< PathPayoff > payoff_
std::vector< Handle< YieldTermStructure > > forwardTermStructures_
Real operator()(const MultiPath &multiPath) const override
Shared handle to an observable.
Definition: handle.hpp:41
Pricing engine for path dependent basket options using.
MCPathBasketEngine(ext::shared_ptr< StochasticProcessArray >, Size timeSteps, Size timeStepsPerYear, bool brownianBridge, bool antitheticVariate, bool controlVariate, Size requiredSamples, Real requiredTolerance, Size maxSamples, BigNatural seed)
ext::shared_ptr< path_generator_type > pathGenerator() const
void calculate() const override
McSimulation< MultiVariate, RNG, S >::path_pricer_type path_pricer_type
McSimulation< MultiVariate, RNG, S >::stats_type stats_type
McSimulation< MultiVariate, RNG, S >::path_generator_type path_generator_type
ext::shared_ptr< path_pricer_type > pathPricer() const
ext::shared_ptr< StochasticProcessArray > process_
Monte Carlo Path Basket engine factory.
MakeMCPathBasketEngine & withSamples(Size samples)
MakeMCPathBasketEngine & withControlVariate(bool b=true)
MakeMCPathBasketEngine & withStepsPerYear(Size steps)
MakeMCPathBasketEngine & withMaxSamples(Size samples)
MakeMCPathBasketEngine & withSeed(BigNatural seed)
MakeMCPathBasketEngine & withSteps(Size steps)
MakeMCPathBasketEngine & withAbsoluteTolerance(Real tolerance)
MakeMCPathBasketEngine & withBrownianBridge(bool b=true)
ext::shared_ptr< StochasticProcessArray > process_
MakeMCPathBasketEngine & withAntitheticVariate(bool b=true)
MakeMCPathBasketEngine(ext::shared_ptr< StochasticProcessArray >)
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
Correlated multiple asset paths.
Definition: multipath.hpp:39
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
base class for path pricers
Definition: pathpricer.hpp:40
time grid class
Definition: timegrid.hpp:43
Size index(Time t) const
returns the index i such that grid[i] = t
Definition: timegrid.cpp:43
Size size() const
Definition: timegrid.hpp:164
const std::vector< Time > & mandatoryTimes() const
Definition: timegrid.hpp:151
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 multi-variate models
Definition: mctraits.hpp:50