1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 
3 /*
4 Copyright (C) 2010 Adrian O' Neill
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 
20 #include <ql/experimental/variancegamma/fftvanillaengine.hpp>
21 #include <ql/exercise.hpp>
22 #include <ql/termstructures/volatility/equityfx/blackconstantvol.hpp>
23 #include <ql/auto_ptr.hpp>
24 #include <complex>
25 
26 namespace QuantLib {
27 
FFTVanillaEngine(const ext::shared_ptr<GeneralizedBlackScholesProcess> & process,Real logStrikeSpacing)28     FFTVanillaEngine::FFTVanillaEngine(
29         const ext::shared_ptr<GeneralizedBlackScholesProcess>& process, Real logStrikeSpacing)
30         : FFTEngine(process, logStrikeSpacing)
31     {
32     }
33 
clone() const34     QL_UNIQUE_OR_AUTO_PTR<FFTEngine> FFTVanillaEngine::clone() const
35     {
36         ext::shared_ptr<GeneralizedBlackScholesProcess> process =
37             ext::dynamic_pointer_cast<GeneralizedBlackScholesProcess>(process_);
38         return QL_UNIQUE_OR_AUTO_PTR<FFTEngine>(
39                                       new FFTVanillaEngine(process, lambda_));
40     }
41 
precalculateExpiry(Date d)42     void FFTVanillaEngine::precalculateExpiry(Date d)
43     {
44         ext::shared_ptr<GeneralizedBlackScholesProcess> process =
45             ext::dynamic_pointer_cast<GeneralizedBlackScholesProcess>(process_);
46 
47         dividendDiscount_ =
48             process->dividendYield()->discount(d);
49         riskFreeDiscount_ =
50             process->riskFreeRate()->discount(d);
51 
52         DayCounter rfdc  = process->riskFreeRate()->dayCounter();
53         t_ = rfdc.yearFraction(process->riskFreeRate()->referenceDate(), d);
54 
55         ext::shared_ptr<BlackConstantVol> constVol = ext::dynamic_pointer_cast<BlackConstantVol>
56             (*(process->blackVolatility()));
57         QL_REQUIRE(constVol, "Constant volatility required");
58         Real vol = constVol->blackVol(0.0, 0.0);
59         var_ = vol*vol;
60     }
61 
complexFourierTransform(std::complex<Real> u) const62     std::complex<Real> FFTVanillaEngine::complexFourierTransform(std::complex<Real> u) const
63     {
64         std::complex<Real> i1(0, 1);
65 
66         Real s = process_->x0();
67 
68         std::complex<Real> phi = std::exp(i1 * u * (std::log(s) - (var_ * t_) / 2.0)
69             - (var_ * u * u * t_) / 2.0);
70         phi = phi * std::pow(dividendDiscount_/ riskFreeDiscount_, i1 * u);
71         return phi;
72     }
73 
discountFactor(Date d) const74     Real FFTVanillaEngine::discountFactor(Date d) const
75     {
76         ext::shared_ptr<GeneralizedBlackScholesProcess> process =
77             ext::dynamic_pointer_cast<GeneralizedBlackScholesProcess>(process_);
78         return process->riskFreeRate()->discount(d);
79     }
80 
dividendYield(Date d) const81     Real FFTVanillaEngine::dividendYield(Date d) const
82     {
83         ext::shared_ptr<GeneralizedBlackScholesProcess> process =
84             ext::dynamic_pointer_cast<GeneralizedBlackScholesProcess>(process_);
85         return process->dividendYield()->discount(d);
86     }
87 
88 }
89