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