30 : process_(
std::move(process)), lambda_(logStrikeSpacing) {
37 "not an European Option");
39 ext::shared_ptr<StrikedTypePayoff>
payoff =
40 ext::dynamic_pointer_cast<StrikedTypePayoff>(arguments_.payoff);
43 auto r1 =
resultMap_.find(arguments_.exercise->lastDate());
46 auto r2 = r1->second.find(
payoff);
47 if (r2 != r1->second.end())
64 VanillaOption::engine::update();
68 const ext::shared_ptr<Exercise>& exercise)
const {
70 std::vector<ext::shared_ptr<Instrument> > optionList;
71 optionList.push_back(option);
73 ext::shared_ptr<FFTEngine> tempEngine(
clone().release());
74 tempEngine->precalculate(optionList);
75 option->setPricingEngine(tempEngine);
84 typedef std::vector<ext::shared_ptr<StrikedTypePayoff> > PayoffList;
85 typedef std::map<Date, PayoffList> PayoffMap;
88 for (
const auto& optIt : optionList) {
89 ext::shared_ptr<VanillaOption> option = ext::dynamic_pointer_cast<VanillaOption>(optIt);
90 QL_REQUIRE(option,
"instrument must be option");
92 "not an European Option");
94 ext::shared_ptr<StrikedTypePayoff>
payoff =
95 ext::dynamic_pointer_cast<StrikedTypePayoff>(option->payoff());
98 payoffMap[option->exercise()->lastDate()].push_back(
payoff);
101 std::complex<Real> i1(0, 1);
104 for (PayoffMap::const_iterator payIt = payoffMap.begin(); payIt != payoffMap.end(); ++payIt)
106 Date expiryDate = payIt->first;
109 Real maxStrike = 0.0;
110 for (
const auto&
payoff : payIt->second) {
111 if (
payoff->strike() > maxStrike)
112 maxStrike =
payoff->strike();
115 Size log2_n = (
static_cast<Size>((std::log(nR) / std::log(2.0))) + 1);
116 Size n =
static_cast<std::size_t
>(1) << log2_n;
129 std::vector<std::complex<Real> > fti;
135 for (
Size i=0; i<
n; i++)
138 Real sw = eta * (3.0 + ((i % 2) == 0 ? -1.0 : 1.0) - ((i == 0) ? 1.0 : 0.0)) / 3.0;
143 fti[i] = std::exp(i1 *
b * v_j) * sw * psi;
147 std::vector<std::complex<Real> >
results(
n);
152 std::vector<Real> prices, strikes;
155 for (
Size i=0; i<
n; i++)
159 strikes[i] = std::exp(k_u);
162 for (
const auto&
payoff : payIt->second) {
164 prices.begin())(
payoff->strike());
165 switch (
payoff->optionType())
174 QL_FAIL(
"Invalid option type");
const Instrument::results * results_
FFTEngine(ext::shared_ptr< StochasticProcess1D > process, Real logStrikeSpacing)
virtual void precalculateExpiry(Date d)=0
void calculateUncached(const ext::shared_ptr< StrikedTypePayoff > &payoff, const ext::shared_ptr< Exercise > &exercise) const
void calculate() const override
ext::shared_ptr< StochasticProcess1D > process_
void precalculate(const std::vector< ext::shared_ptr< Instrument > > &optionList)
virtual Real dividendYield(Date d) const =0
virtual std::complex< Real > complexFourierTransform(std::complex< Real > u) const =0
virtual Real discountFactor(Date d) const =0
virtual std::unique_ptr< FFTEngine > clone() const =0
Linear interpolation between discrete points
Vanilla option (no discrete dividends, no barriers) on a single asset.
#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.
ext::function< Real(Real)> b
base class for FFT option pricing engines
std::size_t Size
size of a container
ext::shared_ptr< QuantLib::Payoff > payoff
linear interpolation between discrete points