QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
kahalesmilesection.hpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2013 Peter Caspers
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
34#ifndef quantlib_kahale_smile_section_hpp
35#define quantlib_kahale_smile_section_hpp
36
37#include <ql/termstructures/volatility/smilesection.hpp>
38#include <ql/pricingengines/blackformula.hpp>
39#include <ql/math/solvers1d/brent.hpp>
40#include <ql/termstructures/volatility/smilesectionutils.hpp>
41#include <boost/math/distributions/normal.hpp>
42#include <vector>
43#include <utility>
44
45// numerical constants, still experimental
46#define QL_KAHALE_FMAX QL_MAX_REAL
47#define QL_KAHALE_SMAX 5.0
48#define QL_KAHALE_ACC 1E-12
49#define QL_KAHALE_EPS QL_EPSILON
50
51namespace QuantLib {
52
54
55 public:
56 struct cFunction {
57 // this is just a helper class where we do not want virtual
58 // functions
60 : f_(f), s_(s), a_(a), b_(b), exponential_(false) {}
61 cFunction(Real a, Real b) : a_(a), b_(b), exponential_(true) {}
62 Real operator()(Real k) const {
63 if (exponential_)
64 return std::exp(-a_ * k + b_);
65 if (s_ < QL_EPSILON)
66 return std::max(f_ - k, 0.0) + a_ * k + b_;
67 boost::math::normal_distribution<Real> normal;
68 Real d1 = std::log(f_ / k) / s_ + s_ / 2.0;
69 Real d2 = d1 - s_;
70 return f_ * boost::math::cdf(normal, d1) -
71 k * boost::math::cdf(normal, d2) + a_ * k + b_;
72 }
74 const bool exponential_;
75 };
76
77 struct aHelper {
78 aHelper(Real k0, Real k1, Real c0, Real c1, Real c0p, Real c1p)
79 : k0_(k0), k1_(k1), c0_(c0), c1_(c1), c0p_(c0p), c1p_(c1p) {}
80 Real operator()(Real a) const {
81 boost::math::normal_distribution<Real> normal;
82 Real d20 = boost::math::quantile(normal, -c0p_ + a);
83 Real d21 = boost::math::quantile(normal, -c1p_ + a);
84 Real alpha = (d20 - d21) / (std::log(k0_) - std::log(k1_));
85 Real beta = d20 - alpha * std::log(k0_);
86 s_ = -1.0 / alpha;
87 f_ = std::exp(s_ * (beta + s_ / 2.0));
88 QL_REQUIRE(f_ < QL_KAHALE_FMAX, "dummy"); // this is caught
89 cFunction cTmp(f_, s_, a, 0.0);
90 b_ = c0_ - cTmp(k0_);
91 cFunction c(f_, s_, a, b_);
92 return c(k1_) - c1_;
93 }
95 mutable Real s_, f_, b_;
96 };
97
98 struct sHelper {
99 sHelper(Real k0, Real c0, Real c0p) : k0_(k0), c0_(c0), c0p_(c0p) {}
101 s = std::max(s, 0.0);
102 boost::math::normal_distribution<Real> normal;
103 Real d20 = boost::math::quantile(normal, -c0p_);
104 f_ = k0_ * std::exp(s * d20 + s * s / 2.0);
105 QL_REQUIRE(f_ < QL_KAHALE_FMAX, "dummy"); // this is caught
106 cFunction c(f_, s, 0.0, 0.0);
107 return c(k0_) - c0_;
108 }
110 mutable Real f_;
111 };
112
113 struct sHelper1 {
114 sHelper1(Real k1, Real c0, Real c1, Real c1p)
115 : k1_(k1), c0_(c0), c1_(c1), c1p_(c1p) {}
117 s = std::max(s, 0.0);
118 boost::math::normal_distribution<Real> normal;
119 Real d21 = boost::math::quantile(normal, -c1p_);
120 f_ = k1_ * std::exp(s * d21 + s * s / 2.0);
121 QL_REQUIRE(f_ < QL_KAHALE_FMAX, "dummy"); // this is caught
122 b_ = c0_ - f_;
123 cFunction c(f_, s, 0.0, b_);
124 return c(k1_) - c1_;
125 }
127 mutable Real f_, b_;
128 };
129
130 KahaleSmileSection(const ext::shared_ptr<SmileSection>& source,
131 Real atm = Null<Real>(),
132 bool interpolate = false,
133 bool exponentialExtrapolation = false,
134 bool deleteArbitragePoints = false,
135 const std::vector<Real>& moneynessGrid = std::vector<Real>(),
136 Real gap = 1.0E-5,
137 int forcedLeftIndex = -1,
138 int forcedRightIndex = QL_MAX_INTEGER);
139
140 Real minStrike() const override { return -shift(); }
141 Real maxStrike() const override { return QL_MAX_REAL; }
142 Real atmLevel() const override { return f_; }
143 const Date& exerciseDate() const override { return source_->exerciseDate(); }
144 Time exerciseTime() const override { return source_->exerciseTime(); }
145 const DayCounter& dayCounter() const override { return source_->dayCounter(); }
146 const Date& referenceDate() const override { return source_->referenceDate(); }
147 VolatilityType volatilityType() const override { return source_->volatilityType(); }
148 Real shift() const override { return source_->shift(); }
149
150 Real leftCoreStrike() const { return k_[leftIndex_]; }
151 Real rightCoreStrike() const { return k_[rightIndex_]; }
152
153 std::pair<Size, Size> coreIndices() const {
154 return std::make_pair(leftIndex_, rightIndex_);
155 }
156
157 Real optionPrice(Rate strike,
159 Real discount = 1.0) const override;
160
161 protected:
162 Volatility volatilityImpl(Rate strike) const override;
163
164 private:
165 Size index(Rate strike) const;
166 void compute();
167 ext::shared_ptr<SmileSection> source_;
168 std::vector<Real> moneynessGrid_, k_, c_;
170 const Real gap_;
172 std::vector<ext::shared_ptr<cFunction> > cFunctions_;
175 ext::shared_ptr<SmileSectionUtils> ssutils_;
176 };
177}
178
179#endif
Concrete date class.
Definition: date.hpp:125
day counter class
Definition: daycounter.hpp:44
Time exerciseTime() const override
std::pair< Size, Size > coreIndices() const
const Date & exerciseDate() const override
const Date & referenceDate() const override
std::vector< ext::shared_ptr< cFunction > > cFunctions_
VolatilityType volatilityType() const override
ext::shared_ptr< SmileSectionUtils > ssutils_
ext::shared_ptr< SmileSection > source_
Size index(Rate strike) const
const DayCounter & dayCounter() const override
Real optionPrice(Rate strike, Option::Type type=Option::Call, Real discount=1.0) const override
Volatility volatilityImpl(Rate strike) const override
template class providing a null value for a given type.
Definition: null.hpp:76
interest rate volatility smile section
#define QL_MAX_REAL
Definition: qldefines.hpp:176
#define QL_EPSILON
Definition: qldefines.hpp:178
#define QL_MAX_INTEGER
Definition: qldefines.hpp:174
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
Real Volatility
volatility
Definition: types.hpp:78
Real Rate
interest rates
Definition: types.hpp:70
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
aHelper(Real k0, Real k1, Real c0, Real c1, Real c0p, Real c1p)
cFunction(Real f, Real s, Real a, Real b)
sHelper1(Real k1, Real c0, Real c1, Real c1p)