27#ifndef quantlib_mc_longstaff_schwartz_engine_hpp
28#define quantlib_mc_longstaff_schwartz_engine_hpp
47 template <
class GenericEngine,
template <
class>
class MC,
48 class RNG,
class S =
Statistics,
class RNG_Calibration = RNG>
74 Size timeStepsPerYear,
76 bool antitheticVariate,
79 Real requiredTolerance,
83 ext::optional<bool> brownianBridgeCalibration =
ext::nullopt,
84 ext::optional<bool> antitheticVariateCalibration =
ext::nullopt,
90 virtual ext::shared_ptr<LongstaffSchwartzPathPricer<path_type> >
94 ext::shared_ptr<path_pricer_type>
pathPricer()
const override;
110 mutable ext::shared_ptr<LongstaffSchwartzPathPricer<path_type> >
112 mutable ext::shared_ptr<MonteCarloModel<MC, RNG_Calibration, S> >
121 class RNG_Calibration>
125 Size timeStepsPerYear,
127 bool antitheticVariate,
129 Size requiredSamples,
130 Real requiredTolerance,
133 Size nCalibrationSamples,
134 ext::optional<bool> brownianBridgeCalibration,
135 ext::optional<bool> antitheticVariateCalibration,
137 :
McSimulation<MC, RNG,
S>(antitheticVariate, controlVariate), process_(
std::move(process)),
138 timeSteps_(timeSteps), timeStepsPerYear_(timeStepsPerYear), brownianBridge_(brownianBridge),
139 requiredSamples_(requiredSamples), requiredTolerance_(requiredTolerance),
140 maxSamples_(maxSamples), seed_(seed),
141 nCalibrationSamples_((nCalibrationSamples ==
Null<
Size>()) ? 2048 : nCalibrationSamples),
143 brownianBridgeCalibration_(brownianBridgeCalibration ? *brownianBridgeCalibration :
145 antitheticVariateCalibration_(
147 antitheticVariateCalibration ? *antitheticVariateCalibration : antitheticVariate),
148 seedCalibration_(seedCalibration !=
Null<
Real>() ? seedCalibration :
149 (seed == 0 ? 0 : seed + 1768237423L)) {
152 "no time steps provided");
155 "both time steps and time steps per year were provided");
157 "timeSteps must be positive, " << timeSteps <<
160 "timeStepsPerYear must be positive, " << timeStepsPerYear <<
165 template <
class GenericEngine,
template <
class>
class MC,
class RNG,
166 class S,
class RNG_Calibration>
170 RNG_Calibration>::pathPricer()
const {
172 QL_REQUIRE(pathPricer_,
"path pricer unknown");
176 template <
class GenericEngine,
template <
class>
class MC,
class RNG,
177 class S,
class RNG_Calibration>
179 RNG_Calibration>::calculate()
const {
181 pathPricer_ = this->lsmPathPricer();
182 Size dimensions = process_->factors();
184 typename RNG_Calibration::rsg_type generator =
185 RNG_Calibration::make_sequence_generator(
186 dimensions * (grid.
size() - 1), seedCalibration_);
187 ext::shared_ptr<path_generator_type_calibration>
188 pathGeneratorCalibration =
189 ext::make_shared<path_generator_type_calibration>(
190 process_, grid, generator, brownianBridgeCalibration_);
191 mcModelCalibration_ =
192 ext::shared_ptr<MonteCarloModel<MC, RNG_Calibration, S> >(
194 pathGeneratorCalibration, pathPricer_,
stats_type(),
195 this->antitheticVariateCalibration_));
197 mcModelCalibration_->addSamples(nCalibrationSamples_);
198 pathPricer_->calibrate();
203 this->
results_.
value = this->mcModel_->sampleAccumulator().mean();
205 this->pathPricer_->exerciseProbability();
206 if (RNG::allowsErrorEstimate) {
208 this->mcModel_->sampleAccumulator().errorEstimate();
212 template <
class GenericEngine,
template <
class>
class MC,
class RNG,
213 class S,
class RNG_Calibration>
216 RNG_Calibration>::timeGrid()
const {
217 std::vector<Time> requiredTimes;
219 Date lastExerciseDate = this->arguments_.exercise->lastDate();
220 requiredTimes.push_back(process_->time(lastExerciseDate));
222 for (
Size i = 0; i < this->arguments_.exercise->dates().size();
224 Time t = process_->time(this->arguments_.exercise->date(i));
226 requiredTimes.push_back(
t);
230 return TimeGrid(requiredTimes.begin(), requiredTimes.end(),
232 }
else if (this->timeStepsPerYear_ !=
Null<Size>()) {
233 Size steps =
static_cast<Size>(this->timeStepsPerYear_ *
234 requiredTimes.back());
235 return TimeGrid(requiredTimes.begin(), requiredTimes.end(),
236 std::max<Size>(steps, 1));
238 QL_FAIL(
"time steps not specified");
242 template <
class GenericEngine,
template <
class>
class MC,
class RNG,
243 class S,
class RNG_Calibration>
247 RNG_Calibration>::pathGenerator()
const {
249 Size dimensions = process_->factors();
251 typename RNG::rsg_type generator =
252 RNG::make_sequence_generator(dimensions*(grid.
size()-1),seed_);
253 return ext::shared_ptr<path_generator_type>(
255 grid, generator, brownianBridge_));
const Instrument::results * results_
template base class for option pricing engines
std::map< std::string, ext::any > additionalResults
Longstaff-Schwarz Monte Carlo engine for early exercise options.
virtual ext::shared_ptr< LongstaffSchwartzPathPricer< path_type > > lsmPathPricer() const =0
ext::shared_ptr< StochasticProcess > process_
const Real requiredTolerance_
McSimulation< MC, RNG, S >::path_generator_type path_generator_type
const BigNatural seedCalibration_
MC< RNG >::path_type path_type
McSimulation< MC, RNG_Calibration, S >::path_generator_type path_generator_type_calibration
const bool brownianBridge_
void calculate() const override
McSimulation< MC, RNG, S >::path_pricer_type path_pricer_type
const Size requiredSamples_
ext::shared_ptr< path_generator_type > pathGenerator() const override
const bool antitheticVariateCalibration_
McSimulation< MC, RNG, S >::stats_type stats_type
const Size nCalibrationSamples_
ext::shared_ptr< LongstaffSchwartzPathPricer< path_type > > pathPricer_
ext::shared_ptr< path_pricer_type > pathPricer() const override
const Size timeStepsPerYear_
MCLongstaffSchwartzEngine(ext::shared_ptr< StochasticProcess > process, Size timeSteps, Size timeStepsPerYear, bool brownianBridge, bool antitheticVariate, bool controlVariate, Size requiredSamples, Real requiredTolerance, Size maxSamples, BigNatural seed, Size nCalibrationSamples=Null< Size >(), ext::optional< bool > brownianBridgeCalibration=ext::nullopt, ext::optional< bool > antitheticVariateCalibration=ext::nullopt, BigNatural seedCalibration=Null< Size >())
ext::shared_ptr< MonteCarloModel< MC, RNG_Calibration, S > > mcModelCalibration_
TimeGrid timeGrid() const override
const bool brownianBridgeCalibration_
base class for Monte Carlo engines
MonteCarloModel< MC, RNG, S >::path_generator_type path_generator_type
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.
template class providing a null value for a given type.
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
#define QL_FAIL(message)
throw an error (possibly with file and line information)
Option exercise classes and payoff function.
Real Time
continuous quantity with 1-year units
std::size_t Size
size of a container
Longstaff-Schwarz path pricer for early exercise options.
framework for Monte Carlo engines
const boost::none_t & nullopt
RiskStatistics Statistics
default statistics tool
unsigned QL_BIG_INTEGER BigNatural
large positive integer
Maps optional to either the boost or std implementation.