1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 3 /* 4 Copyright (C) 2014, 2015 Klaus Spanderen 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 /*! \file analyticpdfhestonengine.cpp 21 \brief Analytic engine for arbitrary European payoffs under the Heston model 22 */ 23 24 #include <ql/math/integrals/gausslobattointegral.hpp> 25 #include <ql/methods/finitedifferences/utilities/hestonrndcalculator.hpp> 26 #include <ql/experimental/exoticoptions/analyticpdfhestonengine.hpp> 27 #include <ql/functional.hpp> 28 29 namespace QuantLib { 30 AnalyticPDFHestonEngine(const ext::shared_ptr<HestonModel> & model,Real integrationEps_,Size maxIntegrationIterations)31 AnalyticPDFHestonEngine::AnalyticPDFHestonEngine( 32 const ext::shared_ptr<HestonModel>& model, 33 Real integrationEps_, 34 Size maxIntegrationIterations) 35 : maxIntegrationIterations_(maxIntegrationIterations), 36 integrationEps_(integrationEps_), 37 model_(model) { } 38 calculate() const39 void AnalyticPDFHestonEngine::calculate() const { 40 using namespace ext::placeholders; 41 42 // this is an European option pricer 43 QL_REQUIRE(arguments_.exercise->type() == Exercise::European, 44 "not an European option"); 45 46 const ext::shared_ptr<HestonProcess>& process = model_->process(); 47 48 const Time t = process->time(arguments_.exercise->lastDate()); 49 50 const Real xMax = 8.0 * std::sqrt(process->theta()*t 51 + (process->v0() - process->theta()) 52 *(1-std::exp(-process->kappa()*t))/process->kappa()); 53 54 const Real x0 = std::log(process->s0()->value()); 55 const Real rD = process->riskFreeRate()->discount(t); 56 const Real qD = process->dividendYield()->discount(t); 57 58 const Real drift = x0 + std::log(rD/qD); 59 60 results_.value = GaussLobattoIntegral( 61 maxIntegrationIterations_, integrationEps_)( 62 ext::bind(&AnalyticPDFHestonEngine::weightedPayoff, this,_1, t), 63 -xMax+drift, xMax+drift); 64 } 65 Pv(Real x_t,Time t) const66 Real AnalyticPDFHestonEngine::Pv(Real x_t, Time t) const { 67 return HestonRNDCalculator( 68 model_->process(), integrationEps_, maxIntegrationIterations_) 69 .pdf(x_t, t); 70 } 71 cdf(Real s,Time t) const72 Real AnalyticPDFHestonEngine::cdf(Real s, Time t) const { 73 const Real x_t = std::log(s); 74 return HestonRNDCalculator( 75 model_->process(), integrationEps_, maxIntegrationIterations_) 76 .cdf(x_t, t); 77 } 78 weightedPayoff(Real x_t,Time t) const79 Real AnalyticPDFHestonEngine::weightedPayoff(Real x_t, Time t) const { 80 const DiscountFactor rD 81 = model_->process()->riskFreeRate()->discount(t); 82 83 const Real s_t = std::exp(x_t); 84 const Real payoff = (*arguments_.payoff)(s_t); 85 86 return (payoff != 0.0) ? payoff*Pv(x_t, t)*rD : 0.0; 87 } 88 } 89 90