diff --git a/QuantLib.vcxproj b/QuantLib.vcxproj
index 366c4417e73..28771422ec2 100644
--- a/QuantLib.vcxproj
+++ b/QuantLib.vcxproj
@@ -1727,6 +1727,8 @@
+
+
@@ -2753,6 +2755,7 @@
+
diff --git a/QuantLib.vcxproj.filters b/QuantLib.vcxproj.filters
index 5214b5342da..3c1cc862826 100644
--- a/QuantLib.vcxproj.filters
+++ b/QuantLib.vcxproj.filters
@@ -2049,6 +2049,12 @@
termstructures\volatility\equityfx
+
+ termstructures\volatility\equityfx
+
+
+ termstructures\volatility\equityfx
+
termstructures\volatility\equityfx
@@ -5600,6 +5606,9 @@
termstructures\volatility\equityfx
+
+ termstructures\volatility\equityfx
+
termstructures\volatility\equityfx
diff --git a/ql/CMakeLists.txt b/ql/CMakeLists.txt
index fd644d1f506..d399d99f69b 100644
--- a/ql/CMakeLists.txt
+++ b/ql/CMakeLists.txt
@@ -835,6 +835,7 @@ set(QL_SOURCES
termstructures/volatility/equityfx/andreasenhugevolatilityinterpl.cpp
termstructures/volatility/equityfx/blackvariancecurve.cpp
termstructures/volatility/equityfx/blackvariancesurface.cpp
+ termstructures/volatility/equityfx/blackvolsurfacedelta.cpp
termstructures/volatility/equityfx/blackvoltermstructure.cpp
termstructures/volatility/equityfx/fixedlocalvolsurface.cpp
termstructures/volatility/equityfx/gridmodellocalvolsurface.cpp
@@ -2103,6 +2104,8 @@ set(QL_HEADERS
termstructures/volatility/equityfx/blackconstantvol.hpp
termstructures/volatility/equityfx/blackvariancecurve.hpp
termstructures/volatility/equityfx/blackvariancesurface.hpp
+ termstructures/volatility/equityfx/blackvariancetimeextrapolation.hpp
+ termstructures/volatility/equityfx/blackvolsurfacedelta.hpp
termstructures/volatility/equityfx/blackvoltermstructure.hpp
termstructures/volatility/equityfx/fixedlocalvolsurface.hpp
termstructures/volatility/equityfx/gridmodellocalvolsurface.hpp
diff --git a/ql/termstructures/volatility/equityfx/Makefile.am b/ql/termstructures/volatility/equityfx/Makefile.am
index 38dbbf31eb6..94ae793d063 100644
--- a/ql/termstructures/volatility/equityfx/Makefile.am
+++ b/ql/termstructures/volatility/equityfx/Makefile.am
@@ -10,6 +10,8 @@ this_include_HEADERS = \
blackconstantvol.hpp \
blackvariancecurve.hpp \
blackvariancesurface.hpp \
+ blackvariancetimeextrapolation.hpp \
+ blackvolsurfacedelta.hpp \
blackvoltermstructure.hpp \
fixedlocalvolsurface.hpp \
gridmodellocalvolsurface.hpp \
@@ -27,6 +29,7 @@ cpp_files = \
andreasenhugevolatilityadapter.cpp \
blackvariancecurve.cpp \
blackvariancesurface.cpp \
+ blackvolsurfacedelta.cpp \
blackvoltermstructure.cpp \
fixedlocalvolsurface.cpp \
gridmodellocalvolsurface.cpp \
diff --git a/ql/termstructures/volatility/equityfx/blackvariancecurve.cpp b/ql/termstructures/volatility/equityfx/blackvariancecurve.cpp
index 2a2a6847057..0047ab512e3 100644
--- a/ql/termstructures/volatility/equityfx/blackvariancecurve.cpp
+++ b/ql/termstructures/volatility/equityfx/blackvariancecurve.cpp
@@ -20,6 +20,7 @@
#include
#include
+#include
#include
namespace QuantLib {
@@ -28,9 +29,10 @@ namespace QuantLib {
const std::vector& dates,
const std::vector& blackVolCurve,
DayCounter dayCounter,
- bool forceMonotoneVariance)
+ bool forceMonotoneVariance,
+ BlackVolTimeExtrapolation timeExtrapolation)
: BlackVarianceTermStructure(referenceDate), dayCounter_(std::move(dayCounter)),
- maxDate_(dates.back()) {
+ maxDate_(dates.back()), timeExtrapolation_(timeExtrapolation) {
QL_REQUIRE(dates.size()==blackVolCurve.size(),
"mismatch between date vector and black vol vector");
@@ -62,11 +64,15 @@ namespace QuantLib {
}
Real BlackVarianceCurve::blackVarianceImpl(Time t, Real) const {
- if (t<=times_.back()) {
- return varianceCurve_(t, true);
- } else {
+ if (t <= times_.back() || timeExtrapolation_ == BlackVolTimeExtrapolation::UseInterpolatorVariance) {
+ return std::max(varianceCurve_(t, true), 0.0);
+ } else if (timeExtrapolation_ == BlackVolTimeExtrapolation::FlatVolatility) {
// extrapolate with flat vol
- return varianceCurve_(times_.back(), true)*t/times_.back();
+ return timeExtrapolatationBlackVarianceFlat(t, times_, varianceCurve_);
+ } else if (timeExtrapolation_ == BlackVolTimeExtrapolation::UseInterpolatorVolatility) {
+ return timeExtrapolatationBlackVarianceInVolatility(t, times_, varianceCurve_);
+ } else {
+ QL_FAIL("Unknown time extrapolation method");
}
}
diff --git a/ql/termstructures/volatility/equityfx/blackvariancecurve.hpp b/ql/termstructures/volatility/equityfx/blackvariancecurve.hpp
index cc34f71c79a..8b2dbf0e02a 100644
--- a/ql/termstructures/volatility/equityfx/blackvariancecurve.hpp
+++ b/ql/termstructures/volatility/equityfx/blackvariancecurve.hpp
@@ -50,7 +50,8 @@ namespace QuantLib {
const std::vector& dates,
const std::vector& blackVolCurve,
DayCounter dayCounter,
- bool forceMonotoneVariance = true);
+ bool forceMonotoneVariance = true,
+ BlackVolTimeExtrapolation timeExtrapolation = BlackVolTimeExtrapolation::FlatVolatility);
//! \name TermStructure interface
//@{
DayCounter dayCounter() const override { return dayCounter_; }
@@ -84,6 +85,7 @@ namespace QuantLib {
std::vector