Coverage Report

Created: 2025-08-11 06:28

/src/quantlib/ql/experimental/variancegamma/fftvariancegammaengine.cpp
Line
Count
Source (jump to first uncovered line)
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/fftvariancegammaengine.hpp>
21
#include <ql/exercise.hpp>
22
23
namespace QuantLib {
24
25
    FFTVarianceGammaEngine::FFTVarianceGammaEngine(
26
        const ext::shared_ptr<VarianceGammaProcess>& process, Real logStrikeSpacing)
27
0
        : FFTEngine(process, logStrikeSpacing)
28
0
    {
29
0
    }
30
31
    std::unique_ptr<FFTEngine> FFTVarianceGammaEngine::clone() const
32
0
    {
33
0
        ext::shared_ptr<VarianceGammaProcess> process =
34
0
            ext::dynamic_pointer_cast<VarianceGammaProcess>(process_);
35
0
        return std::unique_ptr<FFTEngine>(new FFTVarianceGammaEngine(process, lambda_));
36
0
    }
37
38
    void FFTVarianceGammaEngine::precalculateExpiry(Date d)
39
0
    {
40
0
        ext::shared_ptr<VarianceGammaProcess> process =
41
0
            ext::dynamic_pointer_cast<VarianceGammaProcess>(process_);
42
43
0
        dividendDiscount_ =
44
0
            process->dividendYield()->discount(d);
45
0
        riskFreeDiscount_ =
46
0
            process->riskFreeRate()->discount(d);
47
48
0
        DayCounter rfdc  = process->riskFreeRate()->dayCounter();
49
0
        t_ = rfdc.yearFraction(process->riskFreeRate()->referenceDate(), d);
50
51
0
        sigma_ = process->sigma();
52
0
        nu_ = process->nu();
53
0
        theta_ = process->theta();
54
0
    }
55
56
    std::complex<Real> FFTVarianceGammaEngine::complexFourierTransform(std::complex<Real> u) const
57
0
    {
58
0
        Real s = process_->x0();
59
60
0
        std::complex<Real> i1(0, 1);
61
62
0
        Real omega = std::log(1.0 - theta_ * nu_ - sigma_*sigma_ * nu_ / 2.0) / nu_;
63
0
        std::complex<Real> phi = std::exp(i1 * u * (std::log(s) + omega * t_)) 
64
0
            * std::pow(dividendDiscount_/ riskFreeDiscount_, i1 * u);
65
0
        phi = phi * (std::pow((1.0 - i1 * theta_ * nu_ * u + sigma_*sigma_ * nu_ * u*u / 2.0), (-t_ / nu_)));
66
67
0
        return phi;
68
0
    }
69
70
    Real FFTVarianceGammaEngine::discountFactor(Date d) const
71
0
    {
72
0
        ext::shared_ptr<VarianceGammaProcess> process =
73
0
            ext::dynamic_pointer_cast<VarianceGammaProcess>(process_);
74
0
        return process->riskFreeRate()->discount(d);
75
0
    }
76
77
    Real FFTVarianceGammaEngine::dividendYield(Date d) const
78
0
    {
79
0
        ext::shared_ptr<VarianceGammaProcess> process =
80
0
            ext::dynamic_pointer_cast<VarianceGammaProcess>(process_);
81
0
        return process->dividendYield()->discount(d);
82
0
    }
83
84
}