diff --git a/ql/cashflows/cashflows.cpp b/ql/cashflows/cashflows.cpp index c7b742a70c..c218b5a5ae 100644 --- a/ql/cashflows/cashflows.cpp +++ b/ql/cashflows/cashflows.cpp @@ -1142,55 +1142,6 @@ namespace QuantLib { } // Z-spread utility functions - namespace { - - class ZSpreadFinder { - public: - ZSpreadFinder(const Leg& leg, - const ext::shared_ptr& discountCurve, - Real npv, - const DayCounter& dc, - Compounding comp, - Frequency freq, - bool includeSettlementDateFlows, - Date settlementDate, - Date npvDate) - : leg_(leg), npv_(npv), zSpread_(new SimpleQuote(0.0)), - curve_(Handle(discountCurve), - Handle(zSpread_), comp, freq, dc), - includeSettlementDateFlows_(includeSettlementDateFlows), - settlementDate_(settlementDate), - npvDate_(npvDate) { - - if (settlementDate_ == Date()) - settlementDate_ = Settings::instance().evaluationDate(); - - if (npvDate_ == Date()) - npvDate_ = settlementDate_; - - // if the discount curve allows extrapolation, let's - // the spreaded curve do too. - curve_.enableExtrapolation( - discountCurve->allowsExtrapolation()); - } - Real operator()(Rate zSpread) const { - zSpread_->setValue(zSpread); - Real NPV = CashFlows::npv(leg_, curve_, - includeSettlementDateFlows_, - settlementDate_, npvDate_); - return npv_ - NPV; - } - private: - const Leg& leg_; - Real npv_; - ext::shared_ptr zSpread_; - ZeroSpreadedTermStructure curve_; - bool includeSettlementDateFlows_; - Date settlementDate_, npvDate_; - }; - - } // anonymous namespace ends here - Real CashFlows::npv(const Leg& leg, const ext::shared_ptr& discountCurve, Spread zSpread, @@ -1216,9 +1167,7 @@ namespace QuantLib { ZeroSpreadedTermStructure spreadedCurve(discountCurveHandle, zSpreadQuoteHandle, - comp, freq, dc); - - spreadedCurve.enableExtrapolation(discountCurveHandle->allowsExtrapolation()); + comp, freq); return npv(leg, spreadedCurve, includeSettlementDateFlows, @@ -1244,13 +1193,21 @@ namespace QuantLib { if (npvDate == Date()) npvDate = settlementDate; + auto zSpreadQuote = ext::make_shared(); + ZeroSpreadedTermStructure spreadedCurve(Handle(discount), + Handle(zSpreadQuote), + compounding, + frequency); + auto objFunction = [&](Rate zSpread) { + zSpreadQuote->setValue(zSpread); + Real NPV = CashFlows::npv(leg, spreadedCurve, + includeSettlementDateFlows, + settlementDate, npvDate); + return npv - NPV; + }; + Brent solver; solver.setMaxEvaluations(maxIterations); - ZSpreadFinder objFunction(leg, - discount, - npv, - dayCounter, compounding, frequency, includeSettlementDateFlows, - settlementDate, npvDate); Real step = 0.01; return solver.solve(objFunction, accuracy, guess, step); } diff --git a/ql/methods/finitedifferences/operators/fdmbatesop.cpp b/ql/methods/finitedifferences/operators/fdmbatesop.cpp index ad37e97c1e..72f49a5143 100644 --- a/ql/methods/finitedifferences/operators/fdmbatesop.cpp +++ b/ql/methods/finitedifferences/operators/fdmbatesop.cpp @@ -49,9 +49,7 @@ namespace QuantLib { Handle(ext::make_shared( batesProcess->dividendYield(), Handle(ext::shared_ptr(new SimpleQuote(lambda_ * m_))), - Continuous, - NoFrequency, - batesProcess->dividendYield()->dayCounter())), + Continuous)), batesProcess->s0(), batesProcess->v0(), batesProcess->kappa(), diff --git a/ql/termstructures/yield/piecewiseforwardspreadedtermstructure.hpp b/ql/termstructures/yield/piecewiseforwardspreadedtermstructure.hpp index bc8f5b75b9..0a8492e34e 100644 --- a/ql/termstructures/yield/piecewiseforwardspreadedtermstructure.hpp +++ b/ql/termstructures/yield/piecewiseforwardspreadedtermstructure.hpp @@ -49,10 +49,19 @@ namespace QuantLib { class InterpolatedPiecewiseForwardSpreadedTermStructure : public ForwardRateStructure { public: InterpolatedPiecewiseForwardSpreadedTermStructure(Handle, - std::vector > spreads, - const std::vector& dates, - DayCounter dc = DayCounter(), - const Interpolator& factory = Interpolator()); + std::vector> spreads, + std::vector dates, + Interpolator factory = Interpolator()); + + /*! \deprecated Use the constructor without a day counter. + Deprecated in version 1.41. + */ + [[deprecated("Use the constructor without DayCounter")]] + InterpolatedPiecewiseForwardSpreadedTermStructure(Handle, + std::vector> spreads, + std::vector dates, + DayCounter dc, + Interpolator factory = Interpolator()); //! \name YieldTermStructure interface //@{ DayCounter dayCounter() const override; @@ -78,23 +87,22 @@ namespace QuantLib { std::vector spreadValues_; Compounding comp_; Frequency freq_; - DayCounter dc_; Interpolator factory_; Interpolation interpolator_; }; // inline definitions + #ifndef __DOXYGEN__ + template inline InterpolatedPiecewiseForwardSpreadedTermStructure< T>::InterpolatedPiecewiseForwardSpreadedTermStructure(Handle h, - std::vector > spreads, - const std::vector& dates, - DayCounter dc, - const T& factory) - : originalCurve_(std::move(h)), spreads_(std::move(spreads)), dates_(dates), - times_(dates.size()), spreadValues_(dates.size()), dc_(std::move(dc)), - factory_(factory) { + std::vector> spreads, + std::vector dates, + T factory) + : originalCurve_(std::move(h)), spreads_(std::move(spreads)), dates_(std::move(dates)), + times_(dates_.size()), spreadValues_(dates_.size()), factory_(std::move(factory)) { QL_REQUIRE(!spreads_.empty(), "no spreads given"); QL_REQUIRE(spreads_.size() == dates_.size(), "spread and date vector have different sizes"); @@ -105,6 +113,19 @@ namespace QuantLib { updateInterpolation(); } + template + inline InterpolatedPiecewiseForwardSpreadedTermStructure< + T>::InterpolatedPiecewiseForwardSpreadedTermStructure(Handle h, + std::vector> spreads, + std::vector dates, + DayCounter dc, + T factory) + : InterpolatedPiecewiseForwardSpreadedTermStructure( + std::move(h), std::move(spreads), std::move(dates), std::move(factory) + ) {} + + #endif + template inline DayCounter InterpolatedPiecewiseForwardSpreadedTermStructure::dayCounter() const { return originalCurve_->dayCounter(); diff --git a/ql/termstructures/yield/piecewisezerospreadedtermstructure.hpp b/ql/termstructures/yield/piecewisezerospreadedtermstructure.hpp index e30064a004..155bb497d9 100644 --- a/ql/termstructures/yield/piecewisezerospreadedtermstructure.hpp +++ b/ql/termstructures/yield/piecewisezerospreadedtermstructure.hpp @@ -49,12 +49,23 @@ namespace QuantLib { class InterpolatedPiecewiseZeroSpreadedTermStructure : public ZeroYieldStructure { public: InterpolatedPiecewiseZeroSpreadedTermStructure(Handle, - std::vector > spreads, - const std::vector& dates, + std::vector> spreads, + std::vector dates, Compounding comp = Continuous, Frequency freq = NoFrequency, - DayCounter dc = DayCounter(), - const Interpolator& factory = Interpolator()); + Interpolator factory = Interpolator()); + + /*! \deprecated Use the constructor without a day counter. + Deprecated in version 1.41. + */ + [[deprecated("Use the constructor without DayCounter")]] + InterpolatedPiecewiseZeroSpreadedTermStructure(Handle, + std::vector> spreads, + std::vector dates, + Compounding comp, + Frequency freq, + DayCounter dc, + Interpolator factory = Interpolator()); //! \name YieldTermStructure interface //@{ DayCounter dayCounter() const override; @@ -78,7 +89,6 @@ namespace QuantLib { std::vector spreadValues_; Compounding comp_; Frequency freq_; - DayCounter dc_; Interpolator factory_; Interpolation interpolator_; }; @@ -91,18 +101,19 @@ namespace QuantLib { // inline definitions + #ifndef __DOXYGEN__ + template inline InterpolatedPiecewiseZeroSpreadedTermStructure< T>::InterpolatedPiecewiseZeroSpreadedTermStructure(Handle h, - std::vector > spreads, - const std::vector& dates, + std::vector> spreads, + std::vector dates, Compounding comp, Frequency freq, - DayCounter dc, - const T& factory) - : originalCurve_(std::move(h)), spreads_(std::move(spreads)), dates_(dates), - times_(dates.size()), spreadValues_(dates.size()), comp_(comp), freq_(freq), - dc_(std::move(dc)), factory_(factory) { + T factory) + : originalCurve_(std::move(h)), spreads_(std::move(spreads)), dates_(std::move(dates)), + times_(dates_.size()), spreadValues_(dates_.size()), comp_(comp), freq_(freq), + factory_(std::move(factory)) { QL_REQUIRE(!spreads_.empty(), "no spreads given"); QL_REQUIRE(spreads_.size() == dates_.size(), "spread and date vector have different sizes"); @@ -113,6 +124,21 @@ namespace QuantLib { updateInterpolation(); } + template + inline InterpolatedPiecewiseZeroSpreadedTermStructure< + T>::InterpolatedPiecewiseZeroSpreadedTermStructure(Handle h, + std::vector> spreads, + std::vector dates, + Compounding comp, + Frequency freq, + DayCounter dc, + T factory) + : InterpolatedPiecewiseZeroSpreadedTermStructure( + std::move(h), std::move(spreads), std::move(dates), comp, freq, std::move(factory) + ) {} + + #endif + template inline DayCounter InterpolatedPiecewiseZeroSpreadedTermStructure::dayCounter() const { return originalCurve_->dayCounter(); @@ -192,4 +218,4 @@ namespace QuantLib { } -#endif \ No newline at end of file +#endif diff --git a/ql/termstructures/yield/zerospreadedtermstructure.hpp b/ql/termstructures/yield/zerospreadedtermstructure.hpp index faff0f314c..1db4ba30c2 100644 --- a/ql/termstructures/yield/zerospreadedtermstructure.hpp +++ b/ql/termstructures/yield/zerospreadedtermstructure.hpp @@ -49,8 +49,17 @@ namespace QuantLib { ZeroSpreadedTermStructure(Handle, Handle spread, Compounding comp = Continuous, - Frequency freq = NoFrequency, - DayCounter dc = DayCounter()); + Frequency freq = NoFrequency); + + /*! \deprecated Use the constructor without a day counter. + Deprecated in version 1.41. + */ + [[deprecated("Use the constructor without DayCounter")]] + ZeroSpreadedTermStructure(Handle, + Handle spread, + Compounding comp, + Frequency freq, + DayCounter dc); //! \name YieldTermStructure interface //@{ DayCounter dayCounter() const override; @@ -75,22 +84,26 @@ namespace QuantLib { Handle spread_; Compounding comp_; Frequency freq_; - DayCounter dc_; }; inline ZeroSpreadedTermStructure::ZeroSpreadedTermStructure(Handle h, Handle spread, Compounding comp, - Frequency freq, - DayCounter dc) - : originalCurve_(std::move(h)), spread_(std::move(spread)), comp_(comp), freq_(freq), - dc_(std::move(dc)) { + Frequency freq) + : originalCurve_(std::move(h)), spread_(std::move(spread)), comp_(comp), freq_(freq) { if (!originalCurve_.empty()) enableExtrapolation(originalCurve_->allowsExtrapolation()); registerWith(originalCurve_); registerWith(spread_); } + inline ZeroSpreadedTermStructure::ZeroSpreadedTermStructure(Handle h, + Handle spread, + Compounding comp, + Frequency freq, + DayCounter dc) + : ZeroSpreadedTermStructure(std::move(h), std::move(spread), comp, freq) {} + inline DayCounter ZeroSpreadedTermStructure::dayCounter() const { return originalCurve_->dayCounter(); } diff --git a/test-suite/capfloor.cpp b/test-suite/capfloor.cpp index 94a72f37d4..4a8010369f 100644 --- a/test-suite/capfloor.cpp +++ b/test-suite/capfloor.cpp @@ -663,9 +663,7 @@ BOOST_AUTO_TEST_CASE(testOptionLetsDelta) { ext::shared_ptr spreadCurve(new ZeroSpreadedTermStructure( baseCurveHandle, Handle(spread), - Continuous, - Annual, - Actual360())); + Continuous)); vars.termStructure.linkTo(spreadCurve); Date startDate = vars.termStructure->referenceDate(); Leg leg = vars.makeLeg(startDate,20); @@ -784,9 +782,7 @@ BOOST_AUTO_TEST_CASE(testBachelierOptionLetsDelta) { ext::shared_ptr spreadCurve(new ZeroSpreadedTermStructure( baseCurveHandle, Handle(spread), - Continuous, - Annual, - Actual360())); + Continuous)); vars.termStructure.linkTo(spreadCurve); Date startDate = vars.termStructure->referenceDate(); Leg leg = vars.makeLeg(startDate,20); diff --git a/test-suite/piecewisezerospreadedtermstructure.cpp b/test-suite/piecewisezerospreadedtermstructure.cpp index a0d5e50939..e20bc06a9d 100644 --- a/test-suite/piecewisezerospreadedtermstructure.cpp +++ b/test-suite/piecewisezerospreadedtermstructure.cpp @@ -368,14 +368,11 @@ BOOST_AUTO_TEST_CASE(testSetInterpolationFactory) { Frequency freq = NoFrequency; - Cubic factory; - factory = Cubic(CubicInterpolation::Spline, false); - spreadedTermStructure = ext::make_shared >( Handle(vars.termStructure), spreads, spreadDates, vars.compounding, - freq, vars.dayCount,factory); + freq, Cubic(CubicInterpolation::Spline, false)); Time t = vars.dayCount.yearFraction(vars.today, interpolationDate); Rate interpolatedZeroRate = spreadedTermStructure->zeroRate(t,vars.compounding);