QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
analyticcevengine.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2018 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
22#include <ql/exercise.hpp>
23#include <ql/math/functional.hpp>
24#include <ql/pricingengines/vanilla/analyticcevengine.hpp>
25#include <boost/math/distributions/non_central_chi_squared.hpp>
26#include <boost/math/special_functions/gamma.hpp>
27#include <utility>
28
29namespace QuantLib {
30
32 : f0_(f0),
33 alpha_(alpha),
34 beta_(beta),
35 delta_((1.0-2.0*beta)/(1.0-beta)),
36 x0_(X(f0)) { }
37
39 return std::pow(f, 2.0*(1.0-beta_))/squared(alpha_*(1.0-beta_));
40 }
41
43 Option::Type optionType, Real strike, Time t) const {
44
45 typedef boost::math::non_central_chi_squared_distribution<Real>
46 nc_chi2;
47
48 const Real kTilde = X(strike);
49
50 if (optionType == Option::Call) {
51 if (delta_ < 2.0) {
52 return f0_ * (1.0 - boost::math::cdf(
53 nc_chi2(4.0-delta_, x0_/t), kTilde/t))
54 - strike * boost::math::cdf(
55 nc_chi2(2.0-delta_, kTilde/t), x0_/t);
56 }
57 else {
58 const Real g =
59 boost::math::gamma_p(0.5*delta_-1.0,x0_/(2.0*t));
60
61 return f0_ * (g - boost::math::cdf(
62 nc_chi2(delta_-2.0, kTilde/t), x0_/t))
63 - strike * boost::math::cdf(
64 nc_chi2(delta_, x0_/t), kTilde/t);
65 }
66 }
67 else if (optionType == Option::Put) {
68 if (delta_ < 2.0) {
69 return - f0_ * boost::math::cdf(
70 nc_chi2(4.0-delta_, x0_/t), kTilde/t)
71 + strike * (1.0 - boost::math::cdf(
72 nc_chi2(2.0-delta_, kTilde/t), x0_/t));
73 }
74 else {
75 return - f0_ * boost::math::cdf(
76 nc_chi2(delta_-2.0, kTilde/t), x0_/t)
77 + strike * (1.0 - boost::math::cdf(
78 nc_chi2(delta_, x0_/t), kTilde/t));
79 }
80 }
81 else
82 QL_FAIL("unknown option type");
83
84 }
85
87 Real alpha,
88 Real beta,
89 Handle<YieldTermStructure> discountCurve)
90 : calculator_(ext::make_shared<CEVCalculator>(f0, alpha, beta)),
91 discountCurve_(std::move(discountCurve)) {
92 registerWith(discountCurve_);
93 }
94
96
97 QL_REQUIRE(arguments_.exercise->type() == Exercise::European,
98 "not an European option");
99
100 ext::shared_ptr<StrikedTypePayoff> payoff =
101 ext::dynamic_pointer_cast<StrikedTypePayoff>(arguments_.payoff);
102 QL_REQUIRE(payoff, "non-striked payoff given");
103
104 const Date exerciseDate = arguments_.exercise->lastDate();
105
106 results_.value = calculator_->value(
107 payoff->optionType(),
108 payoff->strike(),
109 discountCurve_->timeFromReference(exerciseDate))
110 * discountCurve_->discount(exerciseDate);
111 }
112
113}
const Handle< YieldTermStructure > discountCurve_
void calculate() const override
AnalyticCEVEngine(Real f0, Real alpha, Real beta, Handle< YieldTermStructure > discountCurve)
const ext::shared_ptr< CEVCalculator > calculator_
constant elasticity of variance process (absorbing boundary at f=0)
CEVCalculator(Real f0, Real alpha, Real beta)
Real value(Option::Type optionType, Real strike, Time t) const
Concrete date class.
Definition: date.hpp:125
Shared handle to an observable.
Definition: handle.hpp:41
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
Definition: any.hpp:35
T squared(T x)
Definition: functional.hpp:37
STL namespace.