26#ifndef quantlib_montecarlo_engine_hpp
27#define quantlib_montecarlo_engine_hpp
42 template <
template <
class>
class MC,
class RNG,
class S =
Statistics>
57 Size minSamples = 1023)
const;
67 Size maxSamples)
const;
73 virtual ext::shared_ptr<path_pricer_type>
pathPricer()
const = 0;
78 return ext::shared_ptr<path_pricer_type>();
80 virtual ext::shared_ptr<path_generator_type>
82 return ext::shared_ptr<path_generator_type>();
85 return ext::shared_ptr<PricingEngine>();
90 template <
class Sequence>
92 return *std::max_element(sequence.begin(), sequence.end());
98 mutable ext::shared_ptr<MonteCarloModel<MC,RNG,S> >
mcModel_;
104 template <
template <
class>
class MC,
class RNG,
class S>
108 Size minSamples)
const {
110 mcModel_->sampleAccumulator().samples();
111 if (sampleNumber<minSamples) {
112 mcModel_->addSamples(minSamples-sampleNumber);
113 sampleNumber = mcModel_->sampleAccumulator().samples();
118 result_type error(mcModel_->sampleAccumulator().errorEstimate());
119 while (maxError(error) > tolerance) {
121 "max number of samples (" << maxSamples
122 <<
") reached, while error (" << error
123 <<
") is still above tolerance (" << tolerance <<
")");
126 order = maxError(
Real(error*error))/tolerance/tolerance;
128 Size(std::max<Real>(
static_cast<Real>(sampleNumber)*order*0.8 -
static_cast<Real>(sampleNumber),
129 static_cast<Real>(minSamples)));
132 nextBatch = std::min(nextBatch, maxSamples-sampleNumber);
133 sampleNumber += nextBatch;
134 mcModel_->addSamples(nextBatch);
135 error =
result_type(mcModel_->sampleAccumulator().errorEstimate());
138 return result_type(mcModel_->sampleAccumulator().mean());
142 template <
template <
class>
class MC,
class RNG,
class S>
146 Size sampleNumber = mcModel_->sampleAccumulator().samples();
149 "number of already simulated samples (" << sampleNumber
150 <<
") greater than requested samples (" << samples <<
")");
152 mcModel_->addSamples(samples-sampleNumber);
154 return result_type(mcModel_->sampleAccumulator().mean());
158 template <
template <
class>
class MC,
class RNG,
class S>
160 Size requiredSamples,
161 Size maxSamples)
const {
165 "neither tolerance nor number of samples set");
168 if (this->controlVariate_) {
170 result_type controlVariateValue = this->controlVariateValue();
172 "engine does not provide "
173 "control-variation price");
175 ext::shared_ptr<path_pricer_type> controlPP =
176 this->controlPathPricer();
178 "engine does not provide "
179 "control-variation path pricer");
181 ext::shared_ptr<path_generator_type> controlPG =
182 this->controlPathGenerator();
185 ext::shared_ptr<MonteCarloModel<MC,RNG,S> >(
187 pathGenerator(), this->pathPricer(),
stats_type(),
188 this->antitheticVariate_, controlPP,
189 controlVariateValue, controlPG));
192 ext::shared_ptr<MonteCarloModel<MC,RNG,S> >(
194 pathGenerator(), this->pathPricer(),
S(),
195 this->antitheticVariate_));
200 this->value(requiredTolerance, maxSamples);
202 this->value(requiredTolerance);
204 this->valueWithSamples(requiredSamples);
209 template <
template <
class>
class MC,
class RNG,
class S>
212 return mcModel_->sampleAccumulator().errorEstimate();
215 template <
template <
class>
class MC,
class RNG,
class S>
218 return mcModel_->sampleAccumulator();
base class for Monte Carlo engines
virtual ext::shared_ptr< path_pricer_type > pathPricer() const =0
result_type valueWithSamples(Size samples) const
simulate a fixed number of samples
virtual result_type controlVariateValue() const
result_type errorEstimate() const
error estimated using the samples simulated so far
MonteCarloModel< MC, RNG, S >::stats_type stats_type
virtual ext::shared_ptr< path_generator_type > pathGenerator() const =0
virtual ext::shared_ptr< path_pricer_type > controlPathPricer() const
MonteCarloModel< MC, RNG, S >::path_generator_type path_generator_type
result_type value(Real tolerance, Size maxSamples=QL_MAX_INTEGER, Size minSamples=1023) const
add samples until the required absolute tolerance is reached
virtual TimeGrid timeGrid() const =0
static Real maxError(const Sequence &sequence)
MonteCarloModel< MC, RNG, S >::result_type result_type
McSimulation(bool antitheticVariate, bool controlVariate)
virtual ext::shared_ptr< PricingEngine > controlPricingEngine() const
static Real maxError(Real error)
const stats_type & sampleAccumulator() const
access to the sample accumulator for richer statistics
virtual ~McSimulation()=default
ext::shared_ptr< MonteCarloModel< MC, RNG, S > > mcModel_
virtual ext::shared_ptr< path_generator_type > controlPathGenerator() const
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
General-purpose Monte Carlo model for path samples.
MC< RNG >::path_pricer_type path_pricer_type
MC< RNG >::path_generator_type path_generator_type
path_pricer_type::result_type result_type
template class providing a null value for a given type.
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
std::size_t Size
size of a container
General-purpose Monte Carlo model.
RiskStatistics Statistics
default statistics tool