QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
mceverestengine.hpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2008 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
24#ifndef quantlib_mc_everest_engine_hpp
25#define quantlib_mc_everest_engine_hpp
26
27#include <ql/exercise.hpp>
28#include <ql/experimental/exoticoptions/everestoption.hpp>
29#include <ql/pricingengines/mcsimulation.hpp>
30#include <ql/processes/blackscholesprocess.hpp>
31#include <ql/processes/stochasticprocessarray.hpp>
32#include <utility>
33
34namespace QuantLib {
35
36 template <class RNG = PseudoRandom, class S = Statistics>
38 public McSimulation<MultiVariate,RNG,S> {
39 public:
46 MCEverestEngine(ext::shared_ptr<StochasticProcessArray>,
47 Size timeSteps,
48 Size timeStepsPerYear,
49 bool brownianBridge,
50 bool antitheticVariate,
51 Size requiredSamples,
52 Real requiredTolerance,
53 Size maxSamples,
54 BigNatural seed);
55 void calculate() const override {
56
60 results_.value = this->mcModel_->sampleAccumulator().mean();
61
62 if (RNG::allowsErrorEstimate) {
64 this->mcModel_->sampleAccumulator().errorEstimate();
65 }
66
67 Real notional = arguments_.notional;
68 DiscountFactor discount = endDiscount();
69 results_.yield = results_.value/(notional * discount) - 1.0;
70 }
71
72 private:
74 // McEverest implementation
75 TimeGrid timeGrid() const override;
76 ext::shared_ptr<path_generator_type> pathGenerator() const override {
77
78 Size numAssets = processes_->size();
79
80 TimeGrid grid = timeGrid();
81 typename RNG::rsg_type gen =
82 RNG::make_sequence_generator(numAssets*(grid.size()-1),seed_);
83
84 return ext::shared_ptr<path_generator_type>(
86 grid, gen, brownianBridge_));
87 }
88 ext::shared_ptr<path_pricer_type> pathPricer() const override;
89
90 // data members
91 ext::shared_ptr<StochasticProcessArray> processes_;
98 };
99
100
102 template <class RNG = PseudoRandom, class S = Statistics>
104 public:
105 explicit MakeMCEverestEngine(ext::shared_ptr<StochasticProcessArray>);
106 // named parameters
115 // conversion to pricing engine
116 operator ext::shared_ptr<PricingEngine>() const;
117 private:
118 ext::shared_ptr<StochasticProcessArray> process_;
119 bool brownianBridge_ = false, antithetic_ = false;
123 };
124
125
126 class EverestMultiPathPricer : public PathPricer<MultiPath> {
127 public:
128 explicit EverestMultiPathPricer(Real notional,
129 Rate guarantee,
130 DiscountFactor discount);
131 Real operator()(const MultiPath& multiPath) const override;
132
133 private:
137 };
138
139
140 // template definitions
141
142 template <class RNG, class S>
144 ext::shared_ptr<StochasticProcessArray> processes,
145 Size timeSteps,
146 Size timeStepsPerYear,
147 bool brownianBridge,
148 bool antitheticVariate,
149 Size requiredSamples,
150 Real requiredTolerance,
151 Size maxSamples,
152 BigNatural seed)
153 : McSimulation<MultiVariate, RNG, S>(antitheticVariate, false),
154 processes_(std::move(processes)), timeSteps_(timeSteps), timeStepsPerYear_(timeStepsPerYear),
155 requiredSamples_(requiredSamples), maxSamples_(maxSamples),
156 requiredTolerance_(requiredTolerance), brownianBridge_(brownianBridge), seed_(seed) {
157 QL_REQUIRE(timeSteps != Null<Size>() ||
158 timeStepsPerYear != Null<Size>(),
159 "no time steps provided");
160 QL_REQUIRE(timeSteps == Null<Size>() ||
161 timeStepsPerYear == Null<Size>(),
162 "both time steps and time steps per year were provided");
163 QL_REQUIRE(timeSteps != 0,
164 "timeSteps must be positive, " << timeSteps <<
165 " not allowed");
166 QL_REQUIRE(timeStepsPerYear != 0,
167 "timeStepsPerYear must be positive, " << timeStepsPerYear <<
168 " not allowed");
170 }
171
172 template <class RNG, class S>
174 Time residualTime = processes_->time(
175 this->arguments_.exercise->lastDate());
176 if (timeSteps_ != Null<Size>()) {
177 return TimeGrid(residualTime, timeSteps_);
178 } else if (timeStepsPerYear_ != Null<Size>()) {
179 Size steps = static_cast<Size>(timeStepsPerYear_*residualTime);
180 return TimeGrid(residualTime, std::max<Size>(steps, 1));
181 } else {
182 QL_FAIL("time steps not specified");
183 }
184 }
185
186 template <class RNG, class S>
188 ext::shared_ptr<GeneralizedBlackScholesProcess> process =
189 ext::dynamic_pointer_cast<GeneralizedBlackScholesProcess>(
190 processes_->process(0));
191 QL_REQUIRE(process, "Black-Scholes process required");
192
193 return process->riskFreeRate()->discount(
194 arguments_.exercise->lastDate());
195 }
196
197 template <class RNG, class S>
198 inline ext::shared_ptr<typename MCEverestEngine<RNG,S>::path_pricer_type>
200
201 return ext::shared_ptr<
203 new EverestMultiPathPricer(arguments_.notional,
204 arguments_.guarantee,
205 endDiscount()));
206 }
207
208
209 template <class RNG, class S>
211 ext::shared_ptr<StochasticProcessArray> process)
212 : process_(std::move(process)), steps_(Null<Size>()), stepsPerYear_(Null<Size>()),
213 samples_(Null<Size>()), maxSamples_(Null<Size>()), tolerance_(Null<Real>()) {}
214
215 template <class RNG, class S>
218 steps_ = steps;
219 return *this;
220 }
221
222 template <class RNG, class S>
225 stepsPerYear_ = steps;
226 return *this;
227 }
228
229 template <class RNG, class S>
232 brownianBridge_ = brownianBridge;
233 return *this;
234 }
235
236 template <class RNG, class S>
239 antithetic_ = b;
240 return *this;
241 }
242
243 template <class RNG, class S>
246 QL_REQUIRE(tolerance_ == Null<Real>(),
247 "tolerance already set");
248 samples_ = samples;
249 return *this;
250 }
251
252 template <class RNG, class S>
255 QL_REQUIRE(samples_ == Null<Size>(),
256 "number of samples already set");
257 QL_REQUIRE(RNG::allowsErrorEstimate,
258 "chosen random generator policy "
259 "does not allow an error estimate");
260 tolerance_ = tolerance;
261 return *this;
262 }
263
264 template <class RNG, class S>
267 maxSamples_ = samples;
268 return *this;
269 }
270
271 template <class RNG, class S>
274 seed_ = seed;
275 return *this;
276 }
277
278 template <class RNG, class S>
279 inline
281 ext::shared_ptr<PricingEngine>() const {
282 QL_REQUIRE(steps_ != Null<Size>() || stepsPerYear_ != Null<Size>(),
283 "number of steps not given");
284 QL_REQUIRE(steps_ == Null<Size>() || stepsPerYear_ == Null<Size>(),
285 "number of steps overspecified");
286 return ext::shared_ptr<PricingEngine>(new
287 MCEverestEngine<RNG,S>(process_,
288 steps_,
289 stepsPerYear_,
290 brownianBridge_,
291 antithetic_,
292 samples_, tolerance_,
293 maxSamples_,
294 seed_));
295 }
296
297}
298
299
300#endif
Real operator()(const MultiPath &multiPath) const override
DiscountFactor endDiscount() const
MCEverestEngine(ext::shared_ptr< StochasticProcessArray >, Size timeSteps, Size timeStepsPerYear, bool brownianBridge, bool antitheticVariate, Size requiredSamples, Real requiredTolerance, Size maxSamples, BigNatural seed)
ext::shared_ptr< path_pricer_type > pathPricer() const override
ext::shared_ptr< path_generator_type > pathGenerator() const override
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< StochasticProcessArray > processes_
TimeGrid timeGrid() const override
Monte Carlo Everest-option engine factory.
MakeMCEverestEngine & withSamples(Size samples)
MakeMCEverestEngine & withSeed(BigNatural seed)
MakeMCEverestEngine & withStepsPerYear(Size steps)
MakeMCEverestEngine(ext::shared_ptr< StochasticProcessArray >)
MakeMCEverestEngine & withMaxSamples(Size samples)
ext::shared_ptr< StochasticProcessArray > process_
MakeMCEverestEngine & withBrownianBridge(bool b=true)
MakeMCEverestEngine & withAntitheticVariate(bool b=true)
MakeMCEverestEngine & withAbsoluteTolerance(Real tolerance)
MakeMCEverestEngine & withSteps(Size steps)
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 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
Real DiscountFactor
discount factor between dates
Definition: types.hpp:66
Real Rate
interest rates
Definition: types.hpp:70
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