From d6beb7063d66c8a28be8d3effb387ecdb3dfc48b Mon Sep 17 00:00:00 2001 From: Luigi Ballabio Date: Thu, 11 Apr 2024 16:14:19 +0200 Subject: [PATCH] Make ZeroInflationCashFlow properly lazy --- ql/cashflows/indexedcashflow.hpp | 3 ++- ql/cashflows/zeroinflationcashflow.cpp | 6 ++--- ql/cashflows/zeroinflationcashflow.hpp | 2 +- test-suite/inflation.cpp | 37 ++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/ql/cashflows/indexedcashflow.hpp b/ql/cashflows/indexedcashflow.hpp index a74fce488d4..dc0bb7eeba6 100644 --- a/ql/cashflows/indexedcashflow.hpp +++ b/ql/cashflows/indexedcashflow.hpp @@ -73,12 +73,13 @@ namespace QuantLib { //@{ void performCalculations() const override; //@} + protected: + mutable Real amount_; private: Real notional_; ext::shared_ptr index_; Date baseDate_, fixingDate_, paymentDate_; bool growthOnly_; - mutable Real amount_; }; diff --git a/ql/cashflows/zeroinflationcashflow.cpp b/ql/cashflows/zeroinflationcashflow.cpp index a79600e36c8..90eb676c91e 100644 --- a/ql/cashflows/zeroinflationcashflow.cpp +++ b/ql/cashflows/zeroinflationcashflow.cpp @@ -38,7 +38,7 @@ namespace QuantLib { zeroInflationIndex_(index), observationInterpolation_(observationInterpolation), startDate_(startDate), endDate_(endDate), observationLag_(observationLag) {} - Real ZeroInflationCashFlow::amount() const { + void ZeroInflationCashFlow::performCalculations() const { Real I0, I1; @@ -51,9 +51,9 @@ namespace QuantLib { } if (growthOnly()) - return notional() * (I1 / I0 - 1.0); + amount_ = notional() * (I1 / I0 - 1.0); else - return notional() * (I1 / I0); + amount_ = notional() * (I1 / I0); } void ZeroInflationCashFlow::accept(AcyclicVisitor& v) { diff --git a/ql/cashflows/zeroinflationcashflow.hpp b/ql/cashflows/zeroinflationcashflow.hpp index cfb4f6deb88..316e34c6fc8 100644 --- a/ql/cashflows/zeroinflationcashflow.hpp +++ b/ql/cashflows/zeroinflationcashflow.hpp @@ -61,7 +61,7 @@ namespace QuantLib { //! \name CashFlow interface //@{ - Real amount() const override; + void performCalculations() const override; //@} //! \name Visitability //@{ diff --git a/test-suite/inflation.cpp b/test-suite/inflation.cpp index e6186c4bbbb..357a7e456b0 100644 --- a/test-suite/inflation.cpp +++ b/test-suite/inflation.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -1602,6 +1603,42 @@ BOOST_AUTO_TEST_CASE(testCpiAsIndexInterpolation) { "\n calculated: " << calculated); } +BOOST_AUTO_TEST_CASE(testNotifications) { + BOOST_TEST_MESSAGE("Testing notifications from zero-inflation cash flow..."); + + Date today = Settings::instance().evaluationDate(); + Real nominal = 10000.0; + + std::vector dates = { today - 3*Months, today + 5*Years }; + std::vector rates = { 0.02, 0.02 }; + + RelinkableHandle inflation_handle; + inflation_handle.linkTo( + ext::make_shared(today, dates, rates, Monthly, Actual360())); + + auto index = ext::make_shared(inflation_handle); + index->addFixing(inflationPeriod(today - 3 * Months, index->frequency()).first, 100.0); + auto cashflow = + ext::make_shared(nominal, + index, + CPI::Flat, + today, + today + 1 * Years, + 3 * Months, + today + 1 * Years); + cashflow->amount(); + + Flag flag; + flag.registerWith(cashflow); + flag.lower(); + + inflation_handle.linkTo( + ext::make_shared(today, dates, rates, Monthly, Actual360())); + + if (!flag.isUp()) + BOOST_FAIL("cash flow did not notify observer of curve change"); +} + BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()