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