25#ifndef quantlib_fd_multi_period_engine_hpp
26#define quantlib_fd_multi_period_engine_hpp
41 template <
template <
class>
class Scheme = CrankNicolson>
42 class [[deprecated(
"Use the new finite-differences framework instead")]]
49 const ext::shared_ptr<GeneralizedBlackScholesProcess>& process,
50 Size timeSteps = 100,
Size gridPoints = 100,
51 bool timeDependent =
false);
52 mutable std::vector<ext::shared_ptr<Event> >
events_;
61 const std::vector<ext::shared_ptr<Event> >& schedule)
const {
63 FDVanillaEngine::setupArguments(args);
66 stoppingTimes_.clear();
67 Size n = schedule.size();
68 stoppingTimes_.reserve(
n);
69 for (
Size i=0; i<
n; ++i)
70 stoppingTimes_.push_back(process_->time(events_[i]->date()));
75 FDVanillaEngine::setupArguments(a);
81 Size n = args->exercise->dates().size();
82 stoppingTimes_.resize(
n);
83 for (
Size i=0; i<
n; ++i)
85 process_->time(args->exercise->date(i));
92 mutable ext::shared_ptr<model_type>
model_;
94 virtual void initializeStepCondition()
const;
95 virtual void initializeModel()
const;
97 return stoppingTimes_[i];
106 template <
template <
class>
class Scheme>
108 const ext::shared_ptr<GeneralizedBlackScholesProcess>& process,
109 Size timeSteps,
Size gridPoints,
bool timeDependent)
111 timeStepPerPeriod_(timeSteps) {}
113 template <
template <
class>
class Scheme>
118 Time beginDate, endDate;
119 Size dateNumber = stoppingTimes_.size();
120 bool lastDateIsResTime =
false;
123 bool firstDateIsZero =
false;
124 Time firstNonZeroDate = getResidualTime();
126 Real dateTolerance = 1e-6;
128 if (dateNumber > 0) {
130 "first date (" << getDividendTime(0)
131 <<
") cannot be negative");
132 if(getDividendTime(0) < getResidualTime() * dateTolerance ){
133 firstDateIsZero =
true;
136 firstNonZeroDate = getDividendTime(1);
139 if (std::fabs(getDividendTime(lastIndex) - getResidualTime())
141 lastDateIsResTime =
true;
142 lastIndex =
Integer(dateNumber) - 2;
145 if (!firstDateIsZero)
146 firstNonZeroDate = getDividendTime(0);
148 if (dateNumber >= 2) {
149 for (
Size j = 1; j < dateNumber; j++)
150 QL_REQUIRE(getDividendTime(j-1) < getDividendTime(j),
151 "dates must be in increasing order: "
152 << getDividendTime(j-1)
153 <<
" is not strictly smaller than "
154 << getDividendTime(j));
158 Time dt = getResidualTime()/(timeStepPerPeriod_*(dateNumber+1));
161 if (firstNonZeroDate <= dt)
162 dt = firstNonZeroDate/2.0;
165 initializeInitialCondition();
166 initializeOperator();
167 initializeBoundaryConditions();
169 initializeStepCondition();
171 prices_ = intrinsicValues_;
172 if(lastDateIsResTime)
173 executeIntermediateStep(dateNumber - 1);
177 if (j ==
Integer(dateNumber) - 1)
178 beginDate = getResidualTime();
180 beginDate = getDividendTime(j+1);
183 endDate = getDividendTime(j);
187 model_->rollback(prices_.values(),
189 timeStepPerPeriod_, *stepCondition_);
191 executeIntermediateStep(j);
192 }
while (--j >= firstIndex);
194 model_->rollback(prices_.values(), dt, 0, 1, *stepCondition_);
197 executeIntermediateStep(0);
199 results->value = prices_.valueAtCenter();
200 results->delta = prices_.firstDerivativeAtCenter();
201 results->gamma = prices_.secondDerivativeAtCenter();
202 results->additionalResults[
"priceCurve"] = prices_;
205 template <
template <
class>
class Scheme>
207 stepCondition_ = ext::shared_ptr<StandardStepCondition>(
211 template <
template <
class>
class Scheme>
213 model_ = ext::shared_ptr<model_type>(
214 new model_type(finiteDifferenceOperator_,BCs_));
virtual void initializeModel() const
std::vector< Time > stoppingTimes_
FDMultiPeriodEngine(const ext::shared_ptr< GeneralizedBlackScholesProcess > &process, Size timeSteps=100, Size gridPoints=100, bool timeDependent=false)
QL_DEPRECATED_ENABLE_WARNING ext::shared_ptr< model_type > model_
virtual QL_DEPRECATED_ENABLE_WARNING void setupArguments(const PricingEngine::arguments *args, const std::vector< ext::shared_ptr< Event > > &schedule) const
virtual void calculate(PricingEngine::results *) const
QL_DEPRECATED_DISABLE_WARNING ext::shared_ptr< StandardStepCondition > stepCondition_
void setupArguments(const PricingEngine::arguments *a) const override
Time getDividendTime(Size i) const
FiniteDifferenceModel< Scheme< TridiagonalOperator > > model_type
virtual void executeIntermediateStep(Size step) const =0
QL_DEPRECATED_DISABLE_WARNING SampledCurve prices_
virtual void initializeStepCondition() const
std::vector< ext::shared_ptr< Event > > events_
Generic finite difference model.
Results from single-asset option calculation
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Base class for events associated with a given date.
Option exercise classes and payoff function.
default choices for template instantiations
Finite-differences vanilla-option engine.
Real Time
continuous quantity with 1-year units
QL_INTEGER Integer
integer number
std::size_t Size
size of a container
Option on a single asset.
ext::shared_ptr< YieldTermStructure > r
#define QL_DEPRECATED_DISABLE_WARNING
#define QL_DEPRECATED_ENABLE_WARNING