22#include <ql/experimental/fx/blackdeltacalculator.hpp>
23#include <ql/math/comparison.hpp>
24#include <ql/math/interpolations/cubicinterpolation.hpp>
25#include <ql/math/interpolations/linearinterpolation.hpp>
26#include <ql/math/optimization/levenbergmarquardt.hpp>
27#include <ql/pricingengines/blackformula.hpp>
32 Date referenceDate,
const std::vector<Date>& dates,
const std::vector<std::vector<Real>>&
strikes,
33 const std::vector<std::vector<Real>>& strikeQuotes,
const DayCounter& dayCounter,
const Calendar& calendar,
34 const Handle<Quote>& spot,
const Size spotDays,
const Calendar spotCalendar,
35 const Handle<YieldTermStructure>& domesticTS,
const Handle<YieldTermStructure>& foreignTS,
36 const DeltaVolQuote::DeltaType dt,
const DeltaVolQuote::AtmType at,
const Period& switchTenor,
37 const DeltaVolQuote::DeltaType ltdt,
const DeltaVolQuote::AtmType ltat,
const SmileInterpolation smileInterpolation,
38 const bool flatExtrapolation)
39 : BlackVolatilityTermStructure(referenceDate, calendar, Following, dayCounter), dates_(dates), strikes_(
strikes),
40 strikeQuotes_(strikeQuotes), spot_(spot), spotDays_(spotDays), spotCalendar_(spotCalendar),
41 domesticTS_(domesticTS), foreignTS_(foreignTS), dt_(dt), at_(at), switchTenor_(switchTenor), ltdt_(ltdt),
42 ltat_(ltat), smileInterpolation_(smileInterpolation), flatExtrapolation_(flatExtrapolation) {
46 QL_REQUIRE(!
dates_.empty(),
"BlackVolatilitySurfaceAbsolute: no expiry dates given");
47 QL_REQUIRE(!
strikes_.empty(),
"BlackVolatilitySurfaceAbsolute: no strikes given");
49 for (Size i = 0; i <
strikes_.size(); ++i) {
51 for (Size j = 0; j <
strikes_[i].size() - 1; ++j) {
53 "BlackVolatilitySurfaceAbsolute: strikes are not strictly ascending at index "
60 QL_REQUIRE(
strikeQuotes_.size() ==
dates_.size(),
"BlackVolatilitySurfaceAbsolute: strikeQuotes ("
64 <<
strikeQuotes_.size() <<
") mismatch with number of dates in strikes ("
66 for (Size i = 0; i <
strikes_.size(); ++i) {
67 QL_REQUIRE(
strikeQuotes_[i].size() ==
strikes_[i].size(),
"BlackVolatilitySurfaceAbsolute: strikeQuotes inner vector ("
75 for (
auto const& d :
dates_) {
90 CubicInterpolation::SecondDerivative, 0.0, CubicInterpolation::SecondDerivative, 0.0);
93 QL_FAIL(
"BlackVolatilitySurfaceAbsolute: Invalid interpolation type.");
110 BlackVolatilityTermStructure::update();
117 t = std::max(t, 1.0 / 365.0);
132 Size index_m = index_p == 0 ? Null<Size>() : index_p - 1;
134 index_p = Null<Size>();
137 Volatility vol_p = 0, vol_m = 0;
138 if (index_p != Null<Size>()) {
145 if (index_m != Null<Size>()) {
157 if (index_p == Null<Size>()) {
159 }
else if (index_m == Null<Size>()) {
164 vol = (1.0 - a) * vol_m + a * vol_p;
Black volatility surface based on absolute quotes.
std::vector< Date > settlementDates_
std::vector< QuantLib::ext::shared_ptr< Interpolation > > interpolation_
std::vector< std::vector< Real > > strikes_
std::vector< Date > dates_
Handle< YieldTermStructure > foreignTS_
Handle< YieldTermStructure > domesticTS_
std::vector< Real > expiryTimes_
std::vector< std::vector< Real > > strikeQuotes_
BlackVolatilitySurfaceAbsolute(Date referenceDate, const std::vector< Date > &dates, const std::vector< std::vector< Real > > &strikes, const std::vector< std::vector< Real > > &strikeQuotes, const DayCounter &dayCounter, const Calendar &calendar, const Handle< Quote > &spot, const Size spotDays, const Calendar spotCalendar, const Handle< YieldTermStructure > &domesticTS, const Handle< YieldTermStructure > &foreignTS, const DeltaVolQuote::DeltaType dt=DeltaVolQuote::DeltaType::Spot, const DeltaVolQuote::AtmType at=DeltaVolQuote::AtmType::AtmDeltaNeutral, const Period &switchTenor=2 *Years, const DeltaVolQuote::DeltaType ltdt=DeltaVolQuote::DeltaType::Fwd, const DeltaVolQuote::AtmType ltat=DeltaVolQuote::AtmType::AtmDeltaNeutral, const SmileInterpolation smileInterpolation=SmileInterpolation::Cubic, const bool flatExtrapolation=true)
Volatility blackVolImpl(Time t, Real strike) const override
SmileInterpolation smileInterpolation_
std::map< std::pair< Real, Real >, Real > cachedInterpolatedVols_
Filter close_enough(const RandomVariable &x, const RandomVariable &y)