diff --git a/Examples/BermudanSwaption/BermudanSwaption.vcxproj b/Examples/BermudanSwaption/BermudanSwaption.vcxproj index 10e0742a28b..8d4016855db 100644 --- a/Examples/BermudanSwaption/BermudanSwaption.vcxproj +++ b/Examples/BermudanSwaption/BermudanSwaption.vcxproj @@ -541,9 +541,6 @@ - - - {ad0a27da-91da-46a2-acbd-296c419ed3aa} diff --git a/Examples/BermudanSwaption/BermudanSwaption.vcxproj.filters b/Examples/BermudanSwaption/BermudanSwaption.vcxproj.filters index 5b7af0d4a19..004440ef99e 100644 --- a/Examples/BermudanSwaption/BermudanSwaption.vcxproj.filters +++ b/Examples/BermudanSwaption/BermudanSwaption.vcxproj.filters @@ -19,7 +19,4 @@ Source Files - - - \ No newline at end of file diff --git a/Examples/Bonds/Bonds.vcxproj b/Examples/Bonds/Bonds.vcxproj index 2a64851b84a..3b4d358d64b 100644 --- a/Examples/Bonds/Bonds.vcxproj +++ b/Examples/Bonds/Bonds.vcxproj @@ -541,9 +541,6 @@ - - - {ad0a27da-91da-46a2-acbd-296c419ed3aa} diff --git a/Examples/Bonds/Bonds.vcxproj.filters b/Examples/Bonds/Bonds.vcxproj.filters index ac42798ff69..6e10879169d 100644 --- a/Examples/Bonds/Bonds.vcxproj.filters +++ b/Examples/Bonds/Bonds.vcxproj.filters @@ -19,7 +19,4 @@ Source Files - - - \ No newline at end of file diff --git a/Examples/CDS/CDS.vcxproj b/Examples/CDS/CDS.vcxproj index 8e9b380ee54..865994bf49b 100644 --- a/Examples/CDS/CDS.vcxproj +++ b/Examples/CDS/CDS.vcxproj @@ -541,9 +541,6 @@ - - - {ad0a27da-91da-46a2-acbd-296c419ed3aa} diff --git a/Examples/CDS/CDS.vcxproj.filters b/Examples/CDS/CDS.vcxproj.filters index 40cad38d9c4..8e1cb235c33 100644 --- a/Examples/CDS/CDS.vcxproj.filters +++ b/Examples/CDS/CDS.vcxproj.filters @@ -19,7 +19,4 @@ Source Files - - - \ No newline at end of file diff --git a/Examples/CallableBonds/CallableBonds.vcxproj b/Examples/CallableBonds/CallableBonds.vcxproj index 0d723dc1f83..643f6ad5f60 100644 --- a/Examples/CallableBonds/CallableBonds.vcxproj +++ b/Examples/CallableBonds/CallableBonds.vcxproj @@ -541,9 +541,6 @@ - - - {ad0a27da-91da-46a2-acbd-296c419ed3aa} diff --git a/Examples/CallableBonds/CallableBonds.vcxproj.filters b/Examples/CallableBonds/CallableBonds.vcxproj.filters index a0b20df3419..f2a71ae5f92 100644 --- a/Examples/CallableBonds/CallableBonds.vcxproj.filters +++ b/Examples/CallableBonds/CallableBonds.vcxproj.filters @@ -19,7 +19,4 @@ Source Files - - - \ No newline at end of file diff --git a/Examples/ConvertibleBonds/ConvertibleBonds.vcxproj b/Examples/ConvertibleBonds/ConvertibleBonds.vcxproj index 14f8cf443b1..0bdc2db8ceb 100644 --- a/Examples/ConvertibleBonds/ConvertibleBonds.vcxproj +++ b/Examples/ConvertibleBonds/ConvertibleBonds.vcxproj @@ -541,9 +541,6 @@ - - - {ad0a27da-91da-46a2-acbd-296c419ed3aa} diff --git a/Examples/ConvertibleBonds/ConvertibleBonds.vcxproj.filters b/Examples/ConvertibleBonds/ConvertibleBonds.vcxproj.filters index 3179756bb72..883f48e300c 100644 --- a/Examples/ConvertibleBonds/ConvertibleBonds.vcxproj.filters +++ b/Examples/ConvertibleBonds/ConvertibleBonds.vcxproj.filters @@ -19,7 +19,4 @@ Source Files - - - \ No newline at end of file diff --git a/Examples/DiscreteHedging/DiscreteHedging.vcxproj b/Examples/DiscreteHedging/DiscreteHedging.vcxproj index 090d68e0176..8e99c3b6535 100644 --- a/Examples/DiscreteHedging/DiscreteHedging.vcxproj +++ b/Examples/DiscreteHedging/DiscreteHedging.vcxproj @@ -541,9 +541,6 @@ - - - {ad0a27da-91da-46a2-acbd-296c419ed3aa} diff --git a/Examples/DiscreteHedging/DiscreteHedging.vcxproj.filters b/Examples/DiscreteHedging/DiscreteHedging.vcxproj.filters index 2fd3d9dfe14..71b9eafe734 100644 --- a/Examples/DiscreteHedging/DiscreteHedging.vcxproj.filters +++ b/Examples/DiscreteHedging/DiscreteHedging.vcxproj.filters @@ -19,7 +19,4 @@ Source Files - - - \ No newline at end of file diff --git a/Examples/EquityOption/EquityOption.vcxproj b/Examples/EquityOption/EquityOption.vcxproj index cadb435b1c5..85aa7b4381b 100644 --- a/Examples/EquityOption/EquityOption.vcxproj +++ b/Examples/EquityOption/EquityOption.vcxproj @@ -541,9 +541,6 @@ - - - {ad0a27da-91da-46a2-acbd-296c419ed3aa} diff --git a/Examples/EquityOption/EquityOption.vcxproj.filters b/Examples/EquityOption/EquityOption.vcxproj.filters index 4cb6c92e385..8a96eee6e22 100644 --- a/Examples/EquityOption/EquityOption.vcxproj.filters +++ b/Examples/EquityOption/EquityOption.vcxproj.filters @@ -19,7 +19,4 @@ Source Files - - - \ No newline at end of file diff --git a/Examples/FRA/FRA.vcxproj b/Examples/FRA/FRA.vcxproj index 7a46954545a..14422084dca 100644 --- a/Examples/FRA/FRA.vcxproj +++ b/Examples/FRA/FRA.vcxproj @@ -541,9 +541,6 @@ - - - {ad0a27da-91da-46a2-acbd-296c419ed3aa} diff --git a/Examples/FRA/FRA.vcxproj.filters b/Examples/FRA/FRA.vcxproj.filters index d840cc9983e..80f0c29acde 100644 --- a/Examples/FRA/FRA.vcxproj.filters +++ b/Examples/FRA/FRA.vcxproj.filters @@ -19,7 +19,4 @@ Source Files - - - \ No newline at end of file diff --git a/Examples/FittedBondCurve/FittedBondCurve.vcxproj b/Examples/FittedBondCurve/FittedBondCurve.vcxproj index ee1f87c7113..b45c62b2978 100644 --- a/Examples/FittedBondCurve/FittedBondCurve.vcxproj +++ b/Examples/FittedBondCurve/FittedBondCurve.vcxproj @@ -541,9 +541,6 @@ - - - {ad0a27da-91da-46a2-acbd-296c419ed3aa} diff --git a/Examples/FittedBondCurve/FittedBondCurve.vcxproj.filters b/Examples/FittedBondCurve/FittedBondCurve.vcxproj.filters index d607a2e8c64..daabc39980b 100644 --- a/Examples/FittedBondCurve/FittedBondCurve.vcxproj.filters +++ b/Examples/FittedBondCurve/FittedBondCurve.vcxproj.filters @@ -19,7 +19,4 @@ Source Files - - - \ No newline at end of file diff --git a/Examples/Gaussian1dModels/Gaussian1dModels.vcxproj b/Examples/Gaussian1dModels/Gaussian1dModels.vcxproj index b2f23031c9d..754e4ec84b1 100644 --- a/Examples/Gaussian1dModels/Gaussian1dModels.vcxproj +++ b/Examples/Gaussian1dModels/Gaussian1dModels.vcxproj @@ -541,9 +541,6 @@ - - - {ad0a27da-91da-46a2-acbd-296c419ed3aa} diff --git a/Examples/Gaussian1dModels/Gaussian1dModels.vcxproj.filters b/Examples/Gaussian1dModels/Gaussian1dModels.vcxproj.filters index 20bc3244771..d604deb5a99 100644 --- a/Examples/Gaussian1dModels/Gaussian1dModels.vcxproj.filters +++ b/Examples/Gaussian1dModels/Gaussian1dModels.vcxproj.filters @@ -19,7 +19,4 @@ Source Files - - - - + \ No newline at end of file diff --git a/Examples/GlobalOptimizer/GlobalOptimizer.vcxproj b/Examples/GlobalOptimizer/GlobalOptimizer.vcxproj index 7871d1808d4..c71632d12d0 100644 --- a/Examples/GlobalOptimizer/GlobalOptimizer.vcxproj +++ b/Examples/GlobalOptimizer/GlobalOptimizer.vcxproj @@ -541,9 +541,6 @@ - - - {ad0a27da-91da-46a2-acbd-296c419ed3aa} diff --git a/Examples/GlobalOptimizer/GlobalOptimizer.vcxproj.filters b/Examples/GlobalOptimizer/GlobalOptimizer.vcxproj.filters index d18a3fce861..c9b80673ba5 100644 --- a/Examples/GlobalOptimizer/GlobalOptimizer.vcxproj.filters +++ b/Examples/GlobalOptimizer/GlobalOptimizer.vcxproj.filters @@ -19,7 +19,4 @@ Source Files - - - \ No newline at end of file diff --git a/Examples/MarketModels/MarketModels.vcxproj b/Examples/MarketModels/MarketModels.vcxproj index b0cd019851b..9574d384aaa 100644 --- a/Examples/MarketModels/MarketModels.vcxproj +++ b/Examples/MarketModels/MarketModels.vcxproj @@ -541,9 +541,6 @@ - - - {ad0a27da-91da-46a2-acbd-296c419ed3aa} diff --git a/Examples/MarketModels/MarketModels.vcxproj.filters b/Examples/MarketModels/MarketModels.vcxproj.filters index 27b031d5ad0..35fe4aa9438 100644 --- a/Examples/MarketModels/MarketModels.vcxproj.filters +++ b/Examples/MarketModels/MarketModels.vcxproj.filters @@ -19,7 +19,4 @@ Source Files - - - \ No newline at end of file diff --git a/Examples/Replication/Replication.vcxproj b/Examples/Replication/Replication.vcxproj index d011e0af002..b5498e0b72a 100644 --- a/Examples/Replication/Replication.vcxproj +++ b/Examples/Replication/Replication.vcxproj @@ -541,9 +541,6 @@ - - - {ad0a27da-91da-46a2-acbd-296c419ed3aa} diff --git a/Examples/Replication/Replication.vcxproj.filters b/Examples/Replication/Replication.vcxproj.filters index 81d2dd2dfbd..d5e7a80a0ee 100644 --- a/Examples/Replication/Replication.vcxproj.filters +++ b/Examples/Replication/Replication.vcxproj.filters @@ -19,7 +19,4 @@ Source Files - - - \ No newline at end of file diff --git a/Examples/Repo/Repo.vcxproj b/Examples/Repo/Repo.vcxproj index 2a2caad3a91..8e3b4891b1c 100644 --- a/Examples/Repo/Repo.vcxproj +++ b/Examples/Repo/Repo.vcxproj @@ -541,9 +541,6 @@ - - - {ad0a27da-91da-46a2-acbd-296c419ed3aa} diff --git a/Examples/Repo/Repo.vcxproj.filters b/Examples/Repo/Repo.vcxproj.filters index 4acaf8e19f8..e6b3e66fefd 100644 --- a/Examples/Repo/Repo.vcxproj.filters +++ b/Examples/Repo/Repo.vcxproj.filters @@ -19,7 +19,4 @@ Source Files - - - \ No newline at end of file diff --git a/LICENSE.TXT b/LICENSE.TXT index 280a414985f..a3643d6c6dd 100644 --- a/LICENSE.TXT +++ b/LICENSE.TXT @@ -10,7 +10,7 @@ QuantLib is Copyright (C) 2003 Kawanishi Tomoya Copyright (C) 2003 Niels Elken Sønderby Copyright (C) 2003, 2004 Roman Gitlin - Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2014, 2015, 2016, 2017, 2018, 2019, 2020 StatPro Italia srl + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 StatPro Italia srl Copyright (C) 2003, 2004, 2007 Neil Firth Copyright (C) 2004 FIMAT Group diff --git a/ql/cashflows/overnightindexedcoupon.cpp b/ql/cashflows/overnightindexedcoupon.cpp index 2e6c4ce4998..786a1c01ac1 100644 --- a/ql/cashflows/overnightindexedcoupon.cpp +++ b/ql/cashflows/overnightindexedcoupon.cpp @@ -22,6 +22,7 @@ */ #include +#include #include #include #include @@ -124,7 +125,8 @@ namespace QuantLib { const Date& refPeriodStart, const Date& refPeriodEnd, const DayCounter& dayCounter, - bool telescopicValueDates) + bool telescopicValueDates, + OvernightAveraging::Type averagingMethod) : FloatingRateCoupon(paymentDate, nominal, startDate, endDate, overnightIndex->fixingDays(), overnightIndex, gearing, spread, @@ -193,8 +195,18 @@ namespace QuantLib { for (Size i=0; i(new - OvernightIndexedCouponPricer)); + switch (averagingMethod) { + case OvernightAveraging::Simple: + setPricer(ext::shared_ptr( + new ArithmeticAveragedOvernightIndexedCouponPricer(telescopicValueDates))); + break; + case OvernightAveraging::Compound: + setPricer( + ext::shared_ptr(new OvernightIndexedCouponPricer)); + break; + default: + QL_FAIL("unknown compounding convention (" << Integer(averagingMethod) << ")"); + } } const vector& OvernightIndexedCoupon::indexFixings() const { @@ -215,7 +227,8 @@ namespace QuantLib { OvernightLeg::OvernightLeg(const Schedule& schedule, ext::shared_ptr i) : schedule_(schedule), overnightIndex_(std::move(i)), paymentCalendar_(schedule.calendar()), - paymentAdjustment_(Following), paymentLag_(0), telescopicValueDates_(false) {} + paymentAdjustment_(Following), paymentLag_(0), telescopicValueDates_(false), + averagingMethod_(OvernightAveraging::Compound) {} OvernightLeg& OvernightLeg::withNotionals(Real notional) { notionals_ = vector(1, notional); @@ -273,6 +286,11 @@ namespace QuantLib { return *this; } + OvernightLeg& OvernightLeg::withAveragingMethod(OvernightAveraging::Type averagingMethod) { + averagingMethod_ = averagingMethod; + return *this; + } + OvernightLeg::operator Leg() const { QL_REQUIRE(!notionals_.empty(), "no notional given"); @@ -308,7 +326,8 @@ namespace QuantLib { detail::get(spreads_, i, 0.0), refStart, refEnd, paymentDayCounter_, - telescopicValueDates_))); + telescopicValueDates_, + averagingMethod_))); } return cashflows; } diff --git a/ql/cashflows/overnightindexedcoupon.hpp b/ql/cashflows/overnightindexedcoupon.hpp index e17b7b50750..6c226495e7a 100644 --- a/ql/cashflows/overnightindexedcoupon.hpp +++ b/ql/cashflows/overnightindexedcoupon.hpp @@ -34,8 +34,26 @@ namespace QuantLib { + //! overnight coupon averaging method + /*! It allows to configure how interest is accrued in the overnight coupon. + */ + struct OvernightAveraging { + enum Type { + Simple, /*!< Under the simple convention the amount of + interest is calculated by applying the daily + rate to the principal, and the payment due + at the end of the period is the sum of those + amounts. */ + Compound /*!< Under the compound convention, the additional + amount of interest owed each day is calculated + by applying the rate both to the principal + and the accumulated unpaid interest. */ + }; + }; + //! overnight coupon - /*! %Coupon paying the compounded interest due to daily overnight fixings. + /*! %Coupon paying the interest, depending on the averaging convention, + due to daily overnight fixings. \warning telescopicValueDates optimizes the schedule for calculation speed, but might fail to produce correct results if the coupon ages by more than @@ -57,7 +75,8 @@ namespace QuantLib { const Date& refPeriodStart = Date(), const Date& refPeriodEnd = Date(), const DayCounter& dayCounter = DayCounter(), - bool telescopicValueDates = false); + bool telescopicValueDates = false, + OvernightAveraging::Type averagingMethod = OvernightAveraging::Compound); //! \name Inspectors //@{ //! fixing dates for the rates to be compounded @@ -101,6 +120,7 @@ namespace QuantLib { OvernightLeg& withSpreads(Spread spread); OvernightLeg& withSpreads(const std::vector& spreads); OvernightLeg& withTelescopicValueDates(bool telescopicValueDates); + OvernightLeg& withAveragingMethod(OvernightAveraging::Type averagingMethod); operator Leg() const; private: Schedule schedule_; @@ -113,6 +133,7 @@ namespace QuantLib { std::vector gearings_; std::vector spreads_; bool telescopicValueDates_; + OvernightAveraging::Type averagingMethod_; }; } diff --git a/ql/experimental/averageois/averageoiscouponpricer.hpp b/ql/experimental/averageois/averageoiscouponpricer.hpp index 95694c68572..2310d528c9d 100644 --- a/ql/experimental/averageois/averageoiscouponpricer.hpp +++ b/ql/experimental/averageois/averageoiscouponpricer.hpp @@ -42,6 +42,10 @@ namespace QuantLib { bool byApprox = false) // TRUE to use Katsumi Takada approximation : byApprox_(byApprox), mrs_(meanReversion), vol_(volatility) {} + ArithmeticAveragedOvernightIndexedCouponPricer( + bool byApprox = false) // Simplified constructor assuming no convexity correction + : ArithmeticAveragedOvernightIndexedCouponPricer(0.03, 0.0, byApprox) {} + void initialize(const FloatingRateCoupon& coupon) override; Rate swapletRate() const override; Real swapletPrice() const override { QL_FAIL("swapletPrice not available"); } diff --git a/ql/experimental/futures/overnightindexfuture.cpp b/ql/experimental/futures/overnightindexfuture.cpp index 939d99e8e4c..686183806fa 100644 --- a/ql/experimental/futures/overnightindexfuture.cpp +++ b/ql/experimental/futures/overnightindexfuture.cpp @@ -31,7 +31,7 @@ namespace QuantLib { const Date& maturityDate, const Handle& discountCurve, Handle convexityAdjustment, - const NettingType subPeriodsNettingType) + OvernightAveraging::Type averagingMethod) : Forward(overnightIndex->dayCounter(), overnightIndex->fixingCalendar(), overnightIndex->businessDayConvention(), @@ -41,7 +41,7 @@ namespace QuantLib { maturityDate, discountCurve), overnightIndex_(overnightIndex), convexityAdjustment_(std::move(convexityAdjustment)), - subPeriodsNettingType_(subPeriodsNettingType) {} + averagingMethod_(averagingMethod) {} Real OvernightIndexFuture::averagedSpotValue() const { Date today = Settings::instance().evaluationDate(); @@ -106,16 +106,15 @@ namespace QuantLib { } Real OvernightIndexFuture::spotValue() const { - switch (subPeriodsNettingType_) { - case Averaging: + switch (averagingMethod_) { + case OvernightAveraging::Simple: underlyingSpotValue_ = averagedSpotValue(); break; - case Compounding: + case OvernightAveraging::Compound: underlyingSpotValue_ = compoundedSpotValue(); break; default: - QL_FAIL("unknown compounding convention (" - << Integer(subPeriodsNettingType_) << ")"); + QL_FAIL("unknown compounding convention (" << Integer(averagingMethod_) << ")"); } return underlyingSpotValue_; } diff --git a/ql/experimental/futures/overnightindexfuture.hpp b/ql/experimental/futures/overnightindexfuture.hpp index 794798ab238..71e9bcb2847 100644 --- a/ql/experimental/futures/overnightindexfuture.hpp +++ b/ql/experimental/futures/overnightindexfuture.hpp @@ -27,6 +27,7 @@ #include #include +#include namespace QuantLib { @@ -36,15 +37,13 @@ namespace QuantLib { */ class OvernightIndexFuture : public Forward { public: - enum NettingType { Averaging, Compounding }; - OvernightIndexFuture(const ext::shared_ptr& overnightIndex, const ext::shared_ptr& payoff, const Date& valueDate, const Date& maturityDate, const Handle& discountCurve, Handle convexityAdjustment = Handle(), - NettingType subPeriodsNettingType = Compounding); + OvernightAveraging::Type averagingMethod = OvernightAveraging::Compound); //! returns spot value/price of an underlying financial instrument Real spotValue() const override; @@ -61,7 +60,7 @@ namespace QuantLib { Real compoundedSpotValue() const; ext::shared_ptr overnightIndex_; Handle convexityAdjustment_; - NettingType subPeriodsNettingType_; + OvernightAveraging::Type averagingMethod_; }; } diff --git a/ql/experimental/futures/overnightindexfutureratehelper.cpp b/ql/experimental/futures/overnightindexfutureratehelper.cpp index c2a47a739dc..1ba321e7c59 100644 --- a/ql/experimental/futures/overnightindexfutureratehelper.cpp +++ b/ql/experimental/futures/overnightindexfutureratehelper.cpp @@ -53,12 +53,12 @@ namespace QuantLib { const Date& maturityDate, const ext::shared_ptr& overnightIndex, const Handle& convexityAdjustment, - const OvernightIndexFuture::NettingType subPeriodsNettingType) + OvernightAveraging::Type averagingMethod) : RateHelper(price) { ext::shared_ptr payoff; future_ = ext::make_shared( overnightIndex, payoff, valueDate, maturityDate, termStructureHandle_, - convexityAdjustment, subPeriodsNettingType); + convexityAdjustment, averagingMethod); earliestDate_ = valueDate; latestDate_ = maturityDate; } @@ -97,13 +97,13 @@ namespace QuantLib { Frequency referenceFreq, const ext::shared_ptr& overnightIndex, const Handle& convexityAdjustment, - const OvernightIndexFuture::NettingType subPeriodsNettingType) + OvernightAveraging::Type averagingMethod) : OvernightIndexFutureRateHelper(price, getValidSofrStart(referenceMonth, referenceYear, referenceFreq), getValidSofrEnd(referenceMonth, referenceYear, referenceFreq), overnightIndex, convexityAdjustment, - subPeriodsNettingType) { + averagingMethod) { QL_REQUIRE(referenceFreq == Quarterly || referenceFreq == Monthly, "only monthly and quarterly SOFR futures accepted"); if (referenceFreq == Quarterly) { @@ -120,14 +120,14 @@ namespace QuantLib { Frequency referenceFreq, const ext::shared_ptr& overnightIndex, Real convexityAdjustment, - const OvernightIndexFuture::NettingType subPeriodsNettingType) + OvernightAveraging::Type averagingMethod) : OvernightIndexFutureRateHelper( Handle(ext::make_shared(price)), getValidSofrStart(referenceMonth, referenceYear, referenceFreq), getValidSofrEnd(referenceMonth, referenceYear, referenceFreq), overnightIndex, Handle(ext::make_shared(convexityAdjustment)), - subPeriodsNettingType) { + averagingMethod) { QL_REQUIRE(referenceFreq == Quarterly || referenceFreq == Monthly, "only monthly and quarterly SOFR futures accepted"); if (referenceFreq == Quarterly) { diff --git a/ql/experimental/futures/overnightindexfutureratehelper.hpp b/ql/experimental/futures/overnightindexfutureratehelper.hpp index 6a1efacfdbd..a2b734fdfaa 100644 --- a/ql/experimental/futures/overnightindexfutureratehelper.hpp +++ b/ql/experimental/futures/overnightindexfutureratehelper.hpp @@ -40,8 +40,7 @@ namespace QuantLib { const Date& maturityDate, const ext::shared_ptr& overnightIndex, const Handle& convexityAdjustment = Handle(), - OvernightIndexFuture::NettingType subPeriodsNettingType = - OvernightIndexFuture::Compounding); + OvernightAveraging::Type averagingMethod = OvernightAveraging::Compound); //! \name RateHelper interface //@{ @@ -74,16 +73,14 @@ namespace QuantLib { Frequency referenceFreq, const ext::shared_ptr& overnightIndex, const Handle& convexityAdjustment = Handle(), - OvernightIndexFuture::NettingType subPeriodsNettingType = - OvernightIndexFuture::Compounding); + OvernightAveraging::Type averagingMethod = OvernightAveraging::Compound); SofrFutureRateHelper(Real price, Month referenceMonth, Year referenceYear, Frequency referenceFreq, const ext::shared_ptr& overnightIndex, Real convexityAdjustment = 0, - OvernightIndexFuture::NettingType subPeriodsNettingType = - OvernightIndexFuture::Compounding); + OvernightAveraging::Type averagingMethod = OvernightAveraging::Compound); }; } diff --git a/ql/indexes/swapindex.cpp b/ql/indexes/swapindex.cpp index 93c0a4e005b..af64e395157 100644 --- a/ql/indexes/swapindex.cpp +++ b/ql/indexes/swapindex.cpp @@ -188,7 +188,8 @@ namespace QuantLib { Natural settlementDays, const Currency& currency, const ext::shared_ptr& overnightIndex, - bool telescopicValueDates) + bool telescopicValueDates, + OvernightAveraging::Type averagingMethod) : SwapIndex(familyName, tenor, settlementDays, @@ -198,7 +199,9 @@ namespace QuantLib { ModifiedFollowing, overnightIndex->dayCounter(), overnightIndex), - overnightIndex_(overnightIndex), telescopicValueDates_(telescopicValueDates) {} + overnightIndex_(overnightIndex), + telescopicValueDates_(telescopicValueDates), + averagingMethod_(averagingMethod) {} ext::shared_ptr @@ -212,7 +215,8 @@ namespace QuantLib { lastSwap_ = MakeOIS(tenor_, overnightIndex_, fixedRate) .withEffectiveDate(valueDate(fixingDate)) .withFixedLegDayCount(dayCounter_) - .withTelescopicValueDates(telescopicValueDates_); + .withTelescopicValueDates(telescopicValueDates_) + .withAveragingMethod(averagingMethod_); lastFixingDate_ = fixingDate; } return lastSwap_; diff --git a/ql/indexes/swapindex.hpp b/ql/indexes/swapindex.hpp index 0f60561778d..a888a84ea7d 100644 --- a/ql/indexes/swapindex.hpp +++ b/ql/indexes/swapindex.hpp @@ -25,6 +25,7 @@ #include #include +#include namespace QuantLib { @@ -113,7 +114,8 @@ namespace QuantLib { Natural settlementDays, const Currency& currency, const ext::shared_ptr& overnightIndex, - bool telescopicValueDates = false); + bool telescopicValueDates = false, + OvernightAveraging::Type averagingMethod = OvernightAveraging::Compound); //! \name Inspectors //@{ ext::shared_ptr overnightIndex() const; @@ -126,6 +128,7 @@ namespace QuantLib { protected: ext::shared_ptr overnightIndex_; bool telescopicValueDates_; + OvernightAveraging::Type averagingMethod_; // cache data to avoid swap recreation when the same fixing date // is used multiple time to forecast changing fixing mutable ext::shared_ptr lastSwap_; diff --git a/ql/instruments/makeois.cpp b/ql/instruments/makeois.cpp index d8612ec9d10..55b36f9d0cc 100644 --- a/ql/instruments/makeois.cpp +++ b/ql/instruments/makeois.cpp @@ -44,7 +44,9 @@ namespace QuantLib { isDefaultEOM_(true), type_(OvernightIndexedSwap::Payer), nominal_(1.0), overnightSpread_(0.0), - fixedDayCount_(overnightIndex->dayCounter()), telescopicValueDates_(false) {} + fixedDayCount_(overnightIndex->dayCounter()), + telescopicValueDates_(false), + averagingMethod_(OvernightAveraging::Compound) {} MakeOIS::operator OvernightIndexedSwap() const { ext::shared_ptr ois = *this; @@ -124,7 +126,8 @@ namespace QuantLib { usedFixedRate, fixedDayCount_, overnightIndex_, overnightSpread_, paymentLag_, paymentAdjustment_, - paymentCalendar_, telescopicValueDates_)); + paymentCalendar_, telescopicValueDates_, + averagingMethod_)); if (engine_ == nullptr) { Handle disc = @@ -233,8 +236,11 @@ namespace QuantLib { MakeOIS& MakeOIS::withTelescopicValueDates(bool telescopicValueDates) { telescopicValueDates_ = telescopicValueDates; return *this; - } + MakeOIS& MakeOIS::withAveragingMethod(OvernightAveraging::Type averagingMethod) { + averagingMethod_ = averagingMethod; + return *this; + } } diff --git a/ql/instruments/makeois.hpp b/ql/instruments/makeois.hpp index ef2ca228b65..1cf92dc1082 100644 --- a/ql/instruments/makeois.hpp +++ b/ql/instruments/makeois.hpp @@ -71,6 +71,8 @@ namespace QuantLib { MakeOIS &withTelescopicValueDates(bool telescopicValueDates); + MakeOIS& withAveragingMethod(OvernightAveraging::Type averagingMethod); + MakeOIS& withPricingEngine( const ext::shared_ptr& engine); private: @@ -100,6 +102,7 @@ namespace QuantLib { ext::shared_ptr engine_; bool telescopicValueDates_; + OvernightAveraging::Type averagingMethod_; }; } diff --git a/ql/instruments/overnightindexedswap.cpp b/ql/instruments/overnightindexedswap.cpp index 1d723df53f8..9f5fb761e93 100644 --- a/ql/instruments/overnightindexedswap.cpp +++ b/ql/instruments/overnightindexedswap.cpp @@ -21,7 +21,6 @@ */ #include -#include #include #include @@ -37,13 +36,14 @@ namespace QuantLib { Natural paymentLag, BusinessDayConvention paymentAdjustment, const Calendar& paymentCalendar, - bool telescopicValueDates) + bool telescopicValueDates, + OvernightAveraging::Type averagingMethod) : Swap(2), type_(type), nominals_(std::vector(1, nominal)), paymentFrequency_(schedule.tenor().frequency()), paymentCalendar_(paymentCalendar.empty() ? schedule.calendar() : paymentCalendar), paymentAdjustment_(paymentAdjustment), paymentLag_(paymentLag), fixedRate_(fixedRate), fixedDC_(std::move(fixedDC)), overnightIndex_(std::move(overnightIndex)), spread_(spread), - telescopicValueDates_(telescopicValueDates) { + telescopicValueDates_(telescopicValueDates), averagingMethod_(averagingMethod) { initialize(schedule); } @@ -58,13 +58,14 @@ namespace QuantLib { Natural paymentLag, BusinessDayConvention paymentAdjustment, const Calendar& paymentCalendar, - bool telescopicValueDates) + bool telescopicValueDates, + OvernightAveraging::Type averagingMethod) : Swap(2), type_(type), nominals_(std::move(nominals)), paymentFrequency_(schedule.tenor().frequency()), paymentCalendar_(paymentCalendar.empty() ? schedule.calendar() : paymentCalendar), paymentAdjustment_(paymentAdjustment), paymentLag_(paymentLag), fixedRate_(fixedRate), fixedDC_(std::move(fixedDC)), overnightIndex_(std::move(overnightIndex)), spread_(spread), - telescopicValueDates_(telescopicValueDates) { + telescopicValueDates_(telescopicValueDates), averagingMethod_(averagingMethod) { initialize(schedule); } @@ -85,7 +86,8 @@ namespace QuantLib { .withTelescopicValueDates(telescopicValueDates_) .withPaymentLag(paymentLag_) .withPaymentAdjustment(paymentAdjustment_) - .withPaymentCalendar(paymentCalendar_); + .withPaymentCalendar(paymentCalendar_) + .withAveragingMethod(averagingMethod_); for (Size j=0; j<2; ++j) { for (auto& i : legs_[j]) diff --git a/ql/instruments/overnightindexedswap.hpp b/ql/instruments/overnightindexedswap.hpp index c0d5625096c..00d527ad660 100644 --- a/ql/instruments/overnightindexedswap.hpp +++ b/ql/instruments/overnightindexedswap.hpp @@ -28,6 +28,7 @@ #define quantlib_overnight_indexed_swap_hpp #include +#include #include #include #include @@ -51,7 +52,8 @@ namespace QuantLib { Natural paymentLag = 0, BusinessDayConvention paymentAdjustment = Following, const Calendar& paymentCalendar = Calendar(), - bool telescopicValueDates = false); + bool telescopicValueDates = false, + OvernightAveraging::Type averagingMethod = OvernightAveraging::Compound); OvernightIndexedSwap(Type type, std::vector nominals, @@ -63,7 +65,8 @@ namespace QuantLib { Natural paymentLag = 0, BusinessDayConvention paymentAdjustment = Following, const Calendar& paymentCalendar = Calendar(), - bool telescopicValueDates = false); + bool telescopicValueDates = false, + OvernightAveraging::Type averagingMethod = OvernightAveraging::Compound); //! \name Inspectors //@{ @@ -71,7 +74,6 @@ namespace QuantLib { Real nominal() const; std::vector nominals() const { return nominals_; } - //const Schedule& schedule() { return schedule_; } Frequency paymentFrequency() { return paymentFrequency_; } Rate fixedRate() const { return fixedRate_; } @@ -82,6 +84,8 @@ namespace QuantLib { const Leg& fixedLeg() const { return legs_[0]; } const Leg& overnightLeg() const { return legs_[1]; } + + OvernightAveraging::Type averagingMethod() const { return averagingMethod_; } //@} //! \name Results @@ -112,6 +116,7 @@ namespace QuantLib { ext::shared_ptr overnightIndex_; Spread spread_; bool telescopicValueDates_; + OvernightAveraging::Type averagingMethod_; }; diff --git a/ql/settings.hpp b/ql/settings.hpp index 0a3aeedf55d..3bbd4e7bca5 100644 --- a/ql/settings.hpp +++ b/ql/settings.hpp @@ -138,7 +138,8 @@ namespace QuantLib { } inline Settings::DateProxy& Settings::DateProxy::operator=(const Date& d) { - ObservableValue::operator=(d); + if (value() != d) // avoid notifications if the date doesn't actually change + ObservableValue::operator=(d); return *this; } diff --git a/ql/termstructures/yield/oisratehelper.cpp b/ql/termstructures/yield/oisratehelper.cpp index 46cc80c08d7..c8237e804af 100644 --- a/ql/termstructures/yield/oisratehelper.cpp +++ b/ql/termstructures/yield/oisratehelper.cpp @@ -39,13 +39,15 @@ namespace QuantLib { const Period& forwardStart, const Spread overnightSpread, Pillar::Choice pillar, - Date customPillarDate) + Date customPillarDate, + OvernightAveraging::Type averagingMethod) : RelativeDateRateHelper(fixedRate), pillarChoice_(pillar), settlementDays_(settlementDays), tenor_(tenor), overnightIndex_(std::move(overnightIndex)), discountHandle_(std::move(discount)), telescopicValueDates_(telescopicValueDates), paymentLag_(paymentLag), paymentConvention_(paymentConvention), paymentFrequency_(paymentFrequency), paymentCalendar_(std::move(paymentCalendar)), - forwardStart_(forwardStart), overnightSpread_(overnightSpread) { + forwardStart_(forwardStart), overnightSpread_(overnightSpread), + averagingMethod_(averagingMethod) { registerWith(overnightIndex_); registerWith(discountHandle_); @@ -72,7 +74,8 @@ namespace QuantLib { .withPaymentAdjustment(paymentConvention_) .withPaymentFrequency(paymentFrequency_) .withPaymentCalendar(paymentCalendar_) - .withOvernightLegSpread(overnightSpread_); + .withOvernightLegSpread(overnightSpread_) + .withAveragingMethod(averagingMethod_); earliestDate_ = swap_->startDate(); maturityDate_ = swap_->maturityDate(); @@ -142,9 +145,11 @@ namespace QuantLib { const Handle& fixedRate, const ext::shared_ptr& overnightIndex, Handle discount, - bool telescopicValueDates) + bool telescopicValueDates, + OvernightAveraging::Type averagingMethod) : RateHelper(fixedRate), discountHandle_(std::move(discount)), - telescopicValueDates_(telescopicValueDates) { + telescopicValueDates_(telescopicValueDates), + averagingMethod_(averagingMethod) { registerWith(overnightIndex); registerWith(discountHandle_); @@ -162,7 +167,8 @@ namespace QuantLib { .withDiscountingTermStructure(discountRelinkableHandle_) .withEffectiveDate(startDate) .withTerminationDate(endDate) - .withTelescopicValueDates(telescopicValueDates_); + .withTelescopicValueDates(telescopicValueDates_) + .withAveragingMethod(averagingMethod_); earliestDate_ = swap_->startDate(); Date lastPaymentDate = std::max(swap_->overnightLeg().back()->date(), diff --git a/ql/termstructures/yield/oisratehelper.hpp b/ql/termstructures/yield/oisratehelper.hpp index 8081588f784..c3cd66bffa4 100644 --- a/ql/termstructures/yield/oisratehelper.hpp +++ b/ql/termstructures/yield/oisratehelper.hpp @@ -47,7 +47,8 @@ namespace QuantLib { const Period& forwardStart = 0 * Days, Spread overnightSpread = 0.0, Pillar::Choice pillar = Pillar::LastRelevantDate, - Date customPillarDate = Date()); + Date customPillarDate = Date(), + OvernightAveraging::Type averagingMethod = OvernightAveraging::Compound); //! \name RateHelper interface //@{ Real impliedQuote() const override; @@ -82,6 +83,7 @@ namespace QuantLib { Calendar paymentCalendar_; Period forwardStart_; Spread overnightSpread_; + OvernightAveraging::Type averagingMethod_; }; //! Rate helper for bootstrapping over Overnight Indexed Swap rates @@ -94,7 +96,8 @@ namespace QuantLib { const ext::shared_ptr& overnightIndex, // exogenous discounting curve Handle discountingCurve = Handle(), - bool telescopicValueDates = false); + bool telescopicValueDates = false, + OvernightAveraging::Type averagingMethod = OvernightAveraging::Compound); //! \name RateHelper interface //@{ Real impliedQuote() const override; @@ -111,6 +114,7 @@ namespace QuantLib { Handle discountHandle_; bool telescopicValueDates_; RelinkableHandle discountRelinkableHandle_; + OvernightAveraging::Type averagingMethod_; }; } diff --git a/test-suite/CMakeLists.txt b/test-suite/CMakeLists.txt index 5639491455a..be4cf03629a 100644 --- a/test-suite/CMakeLists.txt +++ b/test-suite/CMakeLists.txt @@ -131,6 +131,7 @@ set(QuantLib-Test_SRC rounding.cpp sampledcurve.cpp schedule.cpp + settings.cpp shortratemodels.cpp sofrfutures.cpp solvers.cpp @@ -293,6 +294,7 @@ set(QuantLib-Test_HDR rounding.hpp sampledcurve.hpp schedule.hpp + settings.hpp shortratemodels.hpp sofrfutures.hpp solvers.hpp diff --git a/test-suite/Makefile.am b/test-suite/Makefile.am index 1ba7e58d9b1..dc86b3de527 100644 --- a/test-suite/Makefile.am +++ b/test-suite/Makefile.am @@ -129,6 +129,7 @@ QL_TEST_SRCS = \ rounding.cpp \ sampledcurve.cpp \ schedule.cpp \ + settings.cpp \ shortratemodels.cpp \ sofrfutures.cpp \ solvers.cpp \ @@ -288,6 +289,7 @@ QL_TEST_HDRS = \ rounding.hpp \ sampledcurve.hpp \ schedule.hpp \ + settings.hpp \ shortratemodels.hpp \ sofrfutures.hpp \ solvers.hpp \ diff --git a/test-suite/overnightindexedswap.cpp b/test-suite/overnightindexedswap.cpp index cc10f3bce24..e775b711aa8 100644 --- a/test-suite/overnightindexedswap.cpp +++ b/test-suite/overnightindexedswap.cpp @@ -134,19 +134,22 @@ namespace overnight_indexed_swap_test { SavedSettings backup; // utilities - ext::shared_ptr makeSwap(Period length, - Rate fixedRate, - Spread spread, - bool telescopicValueDates, - Date effectiveDate = Null(), - Natural paymentLag = 0) { - return MakeOIS(length, eoniaIndex, fixedRate) + ext::shared_ptr + makeSwap(Period length, + Rate fixedRate, + Spread spread, + bool telescopicValueDates, + Date effectiveDate = Null(), + Natural paymentLag = 0, + OvernightAveraging::Type averagingMethod = OvernightAveraging::Compound) { + return MakeOIS(length, eoniaIndex, fixedRate, 0 * Days) .withEffectiveDate(effectiveDate == Null() ? settlement : effectiveDate) .withOvernightLegSpread(spread) .withNominal(nominal) .withPaymentLag(paymentLag) .withDiscountingTermStructure(eoniaTermStructure) - .withTelescopicValueDates(telescopicValueDates); + .withTelescopicValueDates(telescopicValueDates) + .withAveragingMethod(averagingMethod); } CommonVars() { @@ -298,7 +301,9 @@ void OvernightIndexedSwapTest::testCachedValue() { } namespace overnight_indexed_swap_test { -void testBootstrap(bool telescopicValueDates) { + void testBootstrap(bool telescopicValueDates, + OvernightAveraging::Type averagingMethod, + Real tolerance = 1.0e-8) { CommonVars vars; @@ -327,9 +332,22 @@ void testBootstrap(bool telescopicValueDates) { ext::shared_ptr simple = ext::make_shared(rate); ext::shared_ptr quote (simple); Period term = i.n * i.unit; - ext::shared_ptr helper( - new OISRateHelper(i.settlementDays, term, Handle(quote), eonia, - Handle(), telescopicValueDates, paymentLag)); + ext::shared_ptr helper(new + OISRateHelper(i.settlementDays, + term, + Handle(quote), + eonia, + Handle(), + telescopicValueDates, + paymentLag, + Following, + Annual, + Calendar(), + 0 * Days, + 0.0, + Pillar::LastRelevantDate, + Date(), + averagingMethod)); eoniaHelpers.push_back(helper); } @@ -339,13 +357,12 @@ void testBootstrap(bool telescopicValueDates) { vars.eoniaTermStructure.linkTo(eoniaTS); // test curve consistency - Real tolerance = 1.0e-8; for (auto& i : eoniaSwapData) { Rate expected = i.rate / 100; Period term = i.n * i.unit; // test telescopic value dates (in bootstrap) against non telescopic value dates (swap here) - ext::shared_ptr swap = vars.makeSwap(term, 0.0, 0.0, false, - Null(), paymentLag); + ext::shared_ptr swap = + vars.makeSwap(term, 0.0, 0.0, false, Null(), paymentLag, averagingMethod); Rate calculated = swap->fairRate(); Rate error = std::fabs(expected-calculated); @@ -361,14 +378,28 @@ void testBootstrap(bool telescopicValueDates) { } // anonymous namespace void OvernightIndexedSwapTest::testBootstrap() { - BOOST_TEST_MESSAGE("Testing Eonia-swap curve building..."); - overnight_indexed_swap_test::testBootstrap(false); + BOOST_TEST_MESSAGE("Testing Eonia-swap curve building with daily compounded ON rates..."); + overnight_indexed_swap_test::testBootstrap(false, OvernightAveraging::Compound); +} + +void OvernightIndexedSwapTest::testBootstrapWithArithmeticAverage() { + BOOST_TEST_MESSAGE("Testing Eonia-swap curve building with arithmetic average ON rates..."); + overnight_indexed_swap_test::testBootstrap(false, OvernightAveraging::Simple); } void OvernightIndexedSwapTest::testBootstrapWithTelescopicDates() { BOOST_TEST_MESSAGE( - "Testing Eonia-swap curve building with telescopic value dates..."); - overnight_indexed_swap_test::testBootstrap(true); + "Testing Eonia-swap curve building with telescopic value dates and DCON rates..."); + overnight_indexed_swap_test::testBootstrap(true, OvernightAveraging::Compound); +} + +void OvernightIndexedSwapTest::testBootstrapWithTelescopicDatesAndArithmeticAverage() { + BOOST_TEST_MESSAGE( + "Testing Eonia-swap curve building with telescopic value dates and AAON rates..."); + // Given that we are using an approximation that omits + // the required convexity correction, a lower tolerance + // is needed. + overnight_indexed_swap_test::testBootstrap(true, OvernightAveraging::Simple, 1.0e-5); } void OvernightIndexedSwapTest::testSeasonedSwaps() { @@ -482,8 +513,11 @@ test_suite* OvernightIndexedSwapTest::suite() { suite->add(QUANTLIB_TEST_CASE(&OvernightIndexedSwapTest::testFairSpread)); suite->add(QUANTLIB_TEST_CASE(&OvernightIndexedSwapTest::testCachedValue)); suite->add(QUANTLIB_TEST_CASE(&OvernightIndexedSwapTest::testBootstrap)); + suite->add(QUANTLIB_TEST_CASE(&OvernightIndexedSwapTest::testBootstrapWithArithmeticAverage)); suite->add(QUANTLIB_TEST_CASE( &OvernightIndexedSwapTest::testBootstrapWithTelescopicDates)); + suite->add(QUANTLIB_TEST_CASE( + &OvernightIndexedSwapTest::testBootstrapWithTelescopicDatesAndArithmeticAverage)); suite->add(QUANTLIB_TEST_CASE(&OvernightIndexedSwapTest::testSeasonedSwaps)); suite->add(QUANTLIB_TEST_CASE(&OvernightIndexedSwapTest::testBootstrapRegression)); return suite; diff --git a/test-suite/overnightindexedswap.hpp b/test-suite/overnightindexedswap.hpp index 1963386ad63..6eba0099f80 100644 --- a/test-suite/overnightindexedswap.hpp +++ b/test-suite/overnightindexedswap.hpp @@ -32,7 +32,9 @@ class OvernightIndexedSwapTest { static void testFairSpread(); static void testCachedValue(); static void testBootstrap(); + static void testBootstrapWithArithmeticAverage(); static void testBootstrapWithTelescopicDates(); + static void testBootstrapWithTelescopicDatesAndArithmeticAverage(); static void testSeasonedSwaps(); static void testBootstrapRegression(); static boost::unit_test_framework::test_suite* suite(); diff --git a/test-suite/quantlibtestsuite.cpp b/test-suite/quantlibtestsuite.cpp index 139c5946209..437daa617ae 100644 --- a/test-suite/quantlibtestsuite.cpp +++ b/test-suite/quantlibtestsuite.cpp @@ -190,6 +190,7 @@ #include "rounding.hpp" #include "sampledcurve.hpp" #include "schedule.hpp" +#include "settings.hpp" #include "shortratemodels.hpp" #include "sofrfutures.hpp" #include "solvers.hpp" @@ -466,6 +467,7 @@ test_suite* init_unit_test_suite(int, char* []) { test->add(RoundingTest::suite()); test->add(SampledCurveTest::suite()); test->add(ScheduleTest::suite()); + test->add(SettingsTest::suite()); test->add(ShortRateModelTest::suite(speed)); // fails with QL_USE_INDEXED_COUPON test->add(Solver1DTest::suite()); test->add(StatisticsTest::suite()); diff --git a/test-suite/settings.cpp b/test-suite/settings.cpp new file mode 100644 index 00000000000..590c8ac182a --- /dev/null +++ b/test-suite/settings.cpp @@ -0,0 +1,67 @@ +/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* + Copyright (C) 2021 StatPro Italia srl + + This file is part of QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + + QuantLib is free software: you can redistribute it and/or modify it + under the terms of the QuantLib license. You should have received a + copy of the license along with this program; if not, please email + . The license is also available online at + . + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +#include "settings.hpp" +#include "utilities.hpp" +#include + +using namespace QuantLib; +using namespace boost::unit_test_framework; + + +void SettingsTest::testNotificationsOnDateChange() { + BOOST_TEST_MESSAGE("Testing notifications on evaluation-date change..."); + + SavedSettings rollback; + +#ifdef QL_HIGH_RESOLUTION_DATE + + Date d1(11, February, 2021, 9, 17, 0); + Date d2(11, February, 2021, 10, 21, 0); + +#else + + Date d1(11, February, 2021); + Date d2(12, February, 2021); + +#endif + + Settings::instance().evaluationDate() = d1; + + Flag flag; + flag.registerWith(Settings::instance().evaluationDate()); + + // Set to same date, no notification + Settings::instance().evaluationDate() = d1; + + if (flag.isUp()) + BOOST_ERROR("unexpected notification"); + + // Set to different date, notification expected + Settings::instance().evaluationDate() = d2; + + if (!flag.isUp()) + BOOST_ERROR("missing notification"); +} + +test_suite* SettingsTest::suite() { + auto* suite = BOOST_TEST_SUITE("SettingsTest tests"); + suite->add(QUANTLIB_TEST_CASE(&SettingsTest::testNotificationsOnDateChange)); + return suite; +} diff --git a/test-suite/settings.hpp b/test-suite/settings.hpp new file mode 100644 index 00000000000..b1543e12e2b --- /dev/null +++ b/test-suite/settings.hpp @@ -0,0 +1,35 @@ +/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* + Copyright (C) 2021 StatPro Italia srl + + This file is part of QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + + QuantLib is free software: you can redistribute it and/or modify it + under the terms of the QuantLib license. You should have received a + copy of the license along with this program; if not, please email + . The license is also available online at + . + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +#ifndef quantlib_test_settings_hpp +#define quantlib_test_settings_hpp + +#include + +/* remember to document new and/or updated tests in the Doxygen + comment block of the corresponding class */ + +class SettingsTest { + public: + static void testNotificationsOnDateChange(); + static boost::unit_test_framework::test_suite* suite(); +}; + + +#endif diff --git a/test-suite/sofrfutures.cpp b/test-suite/sofrfutures.cpp index e9ba2fe4723..e77b7823b8c 100644 --- a/test-suite/sofrfutures.cpp +++ b/test-suite/sofrfutures.cpp @@ -36,7 +36,7 @@ namespace { Month month; Year year; Real price; - OvernightIndexFuture::NettingType subPeriodsNettingType; + OvernightAveraging::Type averagingMethod; }; } @@ -51,22 +51,19 @@ void SofrFuturesTest::testBootstrap() { Settings::instance().evaluationDate() = today; const SofrQuotes sofrQuotes[] = { - {Monthly, Oct, 2018, 97.8175, OvernightIndexFuture::Averaging}, - {Monthly, Nov, 2018, 97.770, OvernightIndexFuture::Averaging}, - {Monthly, Dec, 2018, 97.685, OvernightIndexFuture::Averaging}, - {Monthly, Jan, 2019, 97.595, OvernightIndexFuture::Averaging}, - {Monthly, Feb, 2019, 97.590, OvernightIndexFuture::Averaging}, - {Monthly, Mar, 2019, 97.525, OvernightIndexFuture::Averaging}, - // removed due to overlap in bootstrap - // {Quarterly, Sep, 2018, 97.8175, OvernightIndexFuture::Compounding}, - // {Quarterly, Dec, 2018, 97.600, OvernightIndexFuture::Compounding}, - {Quarterly, Mar, 2019, 97.440, OvernightIndexFuture::Compounding}, - {Quarterly, Jun, 2019, 97.295, OvernightIndexFuture::Compounding}, - {Quarterly, Sep, 2019, 97.220, OvernightIndexFuture::Compounding}, - {Quarterly, Dec, 2019, 97.170, OvernightIndexFuture::Compounding}, - {Quarterly, Mar, 2020, 97.160, OvernightIndexFuture::Compounding}, - {Quarterly, Jun, 2020, 97.165, OvernightIndexFuture::Compounding}, - {Quarterly, Sep, 2020, 97.175, OvernightIndexFuture::Compounding}, + {Monthly, Oct, 2018, 97.8175, OvernightAveraging::Simple}, + {Monthly, Nov, 2018, 97.770, OvernightAveraging::Simple}, + {Monthly, Dec, 2018, 97.685, OvernightAveraging::Simple}, + {Monthly, Jan, 2019, 97.595, OvernightAveraging::Simple}, + {Monthly, Feb, 2019, 97.590, OvernightAveraging::Simple}, + {Monthly, Mar, 2019, 97.525, OvernightAveraging::Simple}, + {Quarterly, Mar, 2019, 97.440, OvernightAveraging::Compound}, + {Quarterly, Jun, 2019, 97.295, OvernightAveraging::Compound}, + {Quarterly, Sep, 2019, 97.220, OvernightAveraging::Compound}, + {Quarterly, Dec, 2019, 97.170, OvernightAveraging::Compound}, + {Quarterly, Mar, 2020, 97.160, OvernightAveraging::Compound}, + {Quarterly, Jun, 2020, 97.165, OvernightAveraging::Compound}, + {Quarterly, Sep, 2020, 97.175, OvernightAveraging::Compound}, }; ext::shared_ptr index = ext::make_shared(); @@ -92,7 +89,8 @@ void SofrFuturesTest::testBootstrap() { std::vector > helpers; for (const auto& sofrQuote : sofrQuotes) { helpers.push_back(ext::make_shared( - sofrQuote.price, sofrQuote.month, sofrQuote.year, sofrQuote.freq, index)); + sofrQuote.price, sofrQuote.month, sofrQuote.year, sofrQuote.freq, + index, 0.0, sofrQuote.averagingMethod)); } ext::shared_ptr > curve = diff --git a/test-suite/testsuite.vcxproj b/test-suite/testsuite.vcxproj index cf40a7627f5..414ea6c2c65 100644 --- a/test-suite/testsuite.vcxproj +++ b/test-suite/testsuite.vcxproj @@ -763,6 +763,7 @@ + @@ -923,6 +924,7 @@ + @@ -965,4 +967,4 @@ - \ No newline at end of file + diff --git a/test-suite/testsuite.vcxproj.filters b/test-suite/testsuite.vcxproj.filters index 6849f3bd9c2..20488fc3643 100644 --- a/test-suite/testsuite.vcxproj.filters +++ b/test-suite/testsuite.vcxproj.filters @@ -353,6 +353,9 @@ Source Files + + Source Files + Source Files @@ -827,6 +830,9 @@ Header Files + + Header Files + Header Files @@ -960,4 +966,4 @@ Header Files - \ No newline at end of file + diff --git a/tools/check_header.py b/tools/check_header.py index 9fafce3a7e6..45b0e96fc2f 100755 --- a/tools/check_header.py +++ b/tools/check_header.py @@ -20,11 +20,11 @@ ) fd, fname = tempfile.mkstemp(suffix=".cpp", dir=".", text=True) - os.write(fd, bytes(str(main).encode("utf-8"))) + os.write(fd, bytes(str(main).encode("utf-8"))) os.close(fd) print("Checking %s" % header) - command = "g++ -c -Wno-unknown-pragmas -Wno-deprecated-declarations -I. %s -o /dev/null" % fname + command = "g++ -c -Wno-unknown-pragmas -Wall -Werror -I. %s -o /dev/null" % fname code = os.system(command) if code != 0: errors += 1