QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
localvolsurface.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2003 Ferdinando Ametrano
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/quotes/simplequote.hpp>
21#include <ql/termstructures/volatility/equityfx/blackvoltermstructure.hpp>
22#include <ql/termstructures/volatility/equityfx/localvolsurface.hpp>
23#include <ql/termstructures/yieldtermstructure.hpp>
24#include <utility>
25
26namespace QuantLib {
27
28
30 return blackTS_->referenceDate();
31 }
32
34 return blackTS_->dayCounter();
35 }
36
38 return blackTS_->maxDate();
39 }
40
42 return blackTS_->minStrike();
43 }
44
46 return blackTS_->maxStrike();
47 }
48
52 Handle<Quote> underlying)
53 : LocalVolTermStructure(blackTS->businessDayConvention(), blackTS->dayCounter()),
54 blackTS_(blackTS), riskFreeTS_(std::move(riskFreeTS)), dividendTS_(std::move(dividendTS)),
55 underlying_(std::move(underlying)) {
60 }
61
65 Real underlying)
66 : LocalVolTermStructure(blackTS->businessDayConvention(), blackTS->dayCounter()),
67 blackTS_(blackTS), riskFreeTS_(std::move(riskFreeTS)), dividendTS_(std::move(dividendTS)),
68 underlying_(ext::shared_ptr<Quote>(new SimpleQuote(underlying))) {
72 }
73
75 auto* v1 = dynamic_cast<Visitor<LocalVolSurface>*>(&v);
76 if (v1 != nullptr)
77 v1->visit(*this);
78 else
80 }
81
83 const {
84
85 DiscountFactor dr = riskFreeTS_->discount(t, true);
86 DiscountFactor dq = dividendTS_->discount(t, true);
87 Real forwardValue = underlying_->value()*dq/dr;
88
89 // strike derivatives
90 Real strike, y, dy, strikep, strikem;
91 Real w, wp, wm, dwdy, d2wdy2;
92 strike = underlyingLevel;
93 y = std::log(strike/forwardValue);
94 dy = ((std::fabs(y) > 0.001) ? Real(y*0.0001) : 0.000001);
95 strikep=strike*std::exp(dy);
96 strikem=strike/std::exp(dy);
97 w = blackTS_->blackVariance(t, strike, true);
98 wp = blackTS_->blackVariance(t, strikep, true);
99 wm = blackTS_->blackVariance(t, strikem, true);
100 dwdy = (wp-wm)/(2.0*dy);
101 d2wdy2 = (wp-2.0*w+wm)/(dy*dy);
102
103 // time derivative
104 Real dt, wpt, wmt, dwdt;
105 if (t==0.0) {
106 dt = 0.0001;
107 DiscountFactor drpt = riskFreeTS_->discount(t+dt, true);
108 DiscountFactor dqpt = dividendTS_->discount(t+dt, true);
109 Real strikept = strike*dr*dqpt/(drpt*dq);
110
111 wpt = blackTS_->blackVariance(t+dt, strikept, true);
112 QL_ENSURE(wpt>=w,
113 "decreasing variance at strike " << strike
114 << " between time " << t << " and time " << t+dt);
115 dwdt = (wpt-w)/dt;
116 } else {
117 dt = std::min<Time>(0.0001, t/2.0);
118 DiscountFactor drpt = riskFreeTS_->discount(t+dt, true);
119 DiscountFactor drmt = riskFreeTS_->discount(t-dt, true);
120 DiscountFactor dqpt = dividendTS_->discount(t+dt, true);
121 DiscountFactor dqmt = dividendTS_->discount(t-dt, true);
122
123 Real strikept = strike*dr*dqpt/(drpt*dq);
124 Real strikemt = strike*dr*dqmt/(drmt*dq);
125
126 wpt = blackTS_->blackVariance(t+dt, strikept, true);
127 wmt = blackTS_->blackVariance(t-dt, strikemt, true);
128
129 QL_ENSURE(wpt>=w,
130 "decreasing variance at strike " << strike
131 << " between time " << t << " and time " << t+dt);
132 QL_ENSURE(w>=wmt,
133 "decreasing variance at strike " << strike
134 << " between time " << t-dt << " and time " << t);
135
136 dwdt = (wpt-wmt)/(2.0*dt);
137 }
138
139 if (dwdy==0.0 && d2wdy2==0.0) { // avoid /w where w might be 0.0
140 return std::sqrt(dwdt);
141 } else {
142 Real den1 = 1.0 - y/w*dwdy;
143 Real den2 = 0.25*(-0.25 - 1.0/w + y*y/w/w)*dwdy*dwdy;
144 Real den3 = 0.5*d2wdy2;
145 Real den = den1+den2+den3;
146 Real result = dwdt / den;
147
148 QL_ENSURE(result>=0.0,
149 "negative local vol^2 at strike " << strike
150 << " and time " << t
151 << "; the black vol surface is not smooth enough");
152
153 return std::sqrt(result);
154 }
155 }
156
157}
158
degenerate base class for the Acyclic Visitor pattern
Definition: visitor.hpp:33
Concrete date class.
Definition: date.hpp:125
day counter class
Definition: daycounter.hpp:44
Shared handle to an observable.
Definition: handle.hpp:41
LocalVolSurface(const Handle< BlackVolTermStructure > &blackTS, Handle< YieldTermStructure > riskFreeTS, Handle< YieldTermStructure > dividendTS, Handle< Quote > underlying)
Volatility localVolImpl(Time, Real) const override
local vol calculation
const Date & referenceDate() const override
the date at which discount = 1.0 and/or variance = 0.0
Real minStrike() const override
the minimum strike for which the term structure can return vols
void accept(AcyclicVisitor &) override
Handle< BlackVolTermStructure > blackTS_
DayCounter dayCounter() const override
the day counter used for date/time conversion
Handle< YieldTermStructure > riskFreeTS_
Date maxDate() const override
the latest date for which the curve can return values
Handle< YieldTermStructure > dividendTS_
Real maxStrike() const override
the maximum strike for which the term structure can return vols
virtual void accept(AcyclicVisitor &)
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Definition: observable.hpp:228
purely virtual base class for market observables
Definition: quote.hpp:37
market element returning a stored value
Definition: simplequote.hpp:33
Visitor for a specific class
Definition: visitor.hpp:40
virtual void visit(T &)=0
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
Real DiscountFactor
discount factor between dates
Definition: types.hpp:66
Real Volatility
volatility
Definition: types.hpp:78
Definition: any.hpp:35
STL namespace.