@@ -210,7 +210,7 @@ parRateCurve(const Date& asof, const vector<QuantLib::ext::shared_ptr<QuantExt::
210210TestMarket::TestMarket (Date asof, bool swapVolCube) : MarketImpl(false ) {
211211
212212 TestConfigurationObjects::setConventions ();
213-
213+
214214 asof_ = asof;
215215
216216 // build discount
@@ -356,7 +356,7 @@ TestMarket::TestMarket(Date asof, bool swapVolCube) : MarketImpl(false) {
356356 recoveryRates_[make_pair (Market::defaultConfiguration, " dc2" )] =
357357 Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(0.4 ));
358358 recoveryRates_[make_pair (Market::defaultConfiguration, " BondIssuer0" )] =
359- Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(0.0 ));
359+ Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(0.0 ));
360360 recoveryRates_[make_pair (Market::defaultConfiguration, " BondIssuer1" )] =
361361 Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(0.4 ));
362362
@@ -384,15 +384,15 @@ TestMarket::TestMarket(Date asof, bool swapVolCube) : MarketImpl(false) {
384384
385385 cdsVols_[make_pair (Market::defaultConfiguration, " dc" )] =
386386 Handle<QuantExt::CreditVolCurve>(QuantLib::ext::make_shared<QuantExt::CreditVolCurveWrapper>(flatRateFxv (0.12 )));
387-
387+
388388 Handle<IborIndex> hGBP (ore::data::parseIborIndex (
389389 " GBP-LIBOR-6M" , yieldCurves_[make_tuple (Market::defaultConfiguration, YieldCurveType::Discount, " GBP" )]));
390390 // FIXME: We have defined that above already
391391 iborIndices_[make_pair (Market::defaultConfiguration, " GBP-LIBOR-6M" )] = hGBP;
392392
393393 // Some test cases need a different definition of UKRPI index, curve and vol structure
394394 // We there fore added the new UKROi as UKRP1 and keep the "original" below.
395-
395+
396396 // build inflation indices
397397 auto zeroIndex = Handle<ZeroInflationIndex>(QuantLib::ext::make_shared<UKRPI>(flatZeroInflationCurve (0.02 , 0.01 )));
398398 zeroInflationIndices_[make_pair (Market::defaultConfiguration, " UKRP1" )] = zeroIndex;
@@ -436,23 +436,12 @@ TestMarket::TestMarket(Date asof, bool swapVolCube) : MarketImpl(false) {
436436 euii->addFixing (fixingDatesEUHICPXT[i], fixingRatesEUHICPXT[i], true );
437437 };
438438
439- vector<Date> datesZCII = {asof_,
440- asof_ + 1 * Years,
441- asof_ + 2 * Years,
442- asof_ + 3 * Years,
443- asof_ + 4 * Years,
444- asof_ + 5 * Years,
445- asof_ + 6 * Years,
446- asof_ + 7 * Years,
447- asof_ + 8 * Years,
448- asof_ + 9 * Years,
449- asof_ + 10 * Years,
450- asof_ + 12 * Years,
451- asof_ + 15 * Years,
439+ vector<Date> datesZCII = {asof_ + 1 * Years, asof_ + 2 * Years, asof_ + 3 * Years, asof_ + 4 * Years,
440+ asof_ + 5 * Years, asof_ + 6 * Years, asof_ + 7 * Years, asof_ + 8 * Years,
441+ asof_ + 9 * Years, asof_ + 10 * Years, asof_ + 12 * Years, asof_ + 15 * Years,
452442 asof_ + 20 * Years};
453443
454- vector<Rate> ratesZCII = {2.825 , 2.9425 , 2.975 , 2.983 , 3.0 , 3.01 , 3.008 ,
455- 3.009 , 3.013 , 3.0445 , 3.044 , 3.09 , 3.109 , 3.108 };
444+ vector<Rate> ratesZCII = {2.9425 , 2.975 , 2.983 , 3.0 , 3.01 , 3.008 , 3.009 , 3.013 , 3.0445 , 3.044 , 3.09 , 3.109 , 3.108 };
456445
457446 zeroInflationIndices_[make_pair (Market::defaultConfiguration, " EUHICPXT" )] =
458447 makeZeroInflationIndex (" EUHICPXT" , datesZCII, ratesZCII, euii,
@@ -555,7 +544,7 @@ Handle<CPICapFloorTermPriceSurface> TestMarket::flatRateCps(Handle<ZeroInflation
555544 cPrice, fPrice ));
556545 return Handle<CPICapFloorTermPriceSurface>(ts);
557546}
558-
547+
559548Handle<QuantLib::CPIVolatilitySurface> TestMarket::flatCpiVolSurface (Volatility v) {
560549 Natural settleDays = 0 ;
561550 Calendar cal = TARGET ();
@@ -578,9 +567,19 @@ Handle<ZeroInflationIndex> TestMarket::makeZeroInflationIndex(string index, vect
578567 vector<QuantLib::ext::shared_ptr<BootstrapHelper<ZeroInflationTermStructure>>> instruments;
579568 for (Size i = 0 ; i < dates.size (); i++) {
580569 Handle<Quote> quote (QuantLib::ext::shared_ptr<Quote>(new SimpleQuote (rates[i] / 100.0 )));
581- QuantLib::ext::shared_ptr<BootstrapHelper<ZeroInflationTermStructure>> anInstrument (new ZeroCouponInflationSwapHelper (
582- quote, Period (2 , Months), dates[i], TARGET (), ModifiedFollowing, ActualActual (ActualActual::ISDA), ii, CPI::AsIndex, yts));
583- anInstrument->unregisterWith (Settings::instance ().evaluationDate ());
570+ QuantLib::ext::shared_ptr<BootstrapHelper<ZeroInflationTermStructure>> anInstrument (
571+ new ZeroCouponInflationSwapHelper (quote, Period (2 , Months), dates[i], TARGET (), ModifiedFollowing,
572+ ActualActual (ActualActual::ISDA), ii, CPI::AsIndex, yts, asof_));
573+
574+ // Remove the helper's observation of the inflation index. This has the effect that the
575+ // PiecewiseZeroInflationCurve created below will also not observe the index. It will only get recalculated
576+ // if the initial market quotes change or if the initial nominal yield curve changes. Observation of the index
577+ // was interfering with scenario generation. The PiecewiseZeroInflationCurve was getting recalculated on the
578+ // first time grid date t_1 i.e. was not using the t_0 calculated curve.
579+ anInstrument->unregisterWithAll ();
580+ anInstrument->registerWith (yts);
581+ anInstrument->registerWith (quote);
582+
584583 instruments.push_back (anInstrument);
585584 };
586585 // we can use historical or first ZCIIS for this
@@ -607,9 +606,25 @@ Handle<YoYInflationIndex> TestMarket::makeYoYInflationIndex(string index, vector
607606 for (Size i = 0 ; i < dates.size (); i++) {
608607 Handle<Quote> quote (QuantLib::ext::shared_ptr<Quote>(new SimpleQuote (rates[i] / 100.0 )));
609608 QL_DEPRECATED_DISABLE_WARNING
610- QuantLib::ext::shared_ptr<BootstrapHelper<YoYInflationTermStructure>> anInstrument (new YearOnYearInflationSwapHelper (
611- quote, Period (2 , Months), dates[i], TARGET (), ModifiedFollowing, ActualActual (ActualActual::ISDA), ii, yts));
609+ QuantLib::ext::shared_ptr<BootstrapHelper<YoYInflationTermStructure>> anInstrument (
610+ new YearOnYearInflationSwapHelper (quote, Period (2 , Months), dates[i], TARGET (), ModifiedFollowing,
611+ ActualActual (ActualActual::ISDA), ii, yts, asof_));
612612 QL_DEPRECATED_ENABLE_WARNING
613+
614+ // Remove the helper's observation of the inflation index. This has the effect that the
615+ // PiecewiseYoYInflationCurve created below will also not observe the index. It will only get recalculated
616+ // if the initial market quotes change or if the initial nominal yield curve changes.
617+ // Note: QuantLib needs a change so that if swap start is provided in the helper above then updateDates_ on
618+ // the RelativeDateBootstrapHelper should be false and hence the helper does not observe Settings
619+ // evaluationDate. Without this fix, the unregister here does this also.
620+ // These changes are needed to allow ObservationModeTest/testDefer to pass. Without them
621+ // YearOnYearInflationSwapHelper::initializeDates() gets called due to evaluation date changes, the yyiis_
622+ // member gets reassigned but the original value is still in the deferredObervers_. The testDefer test then
623+ // crashes when deferredObserver->update(); is called in ObservableSettings::enableUpdates() with
624+ // deferredObserver null.
625+ anInstrument->unregisterWithAll ();
626+ anInstrument->registerWith (yts);
627+ anInstrument->registerWith (quote);
613628 instruments.push_back (anInstrument);
614629 };
615630 // we can use historical or first ZCIIS for this
@@ -702,7 +717,7 @@ TestMarketParCurves::TestMarketParCurves(const Date& asof) : MarketImpl(false) {
702717 vector<Real> parRates (parInst.size (), parRate);
703718 createDiscountCurve (ccy, parInst, parTenor, parRates);
704719 }
705-
720+
706721 // add fx rates
707722 // add fx rates
708723 std::map<std::string, QuantLib::Handle<QuantLib::Quote>> quotes;
@@ -1127,7 +1142,7 @@ void TestMarketParCurves::createZeroInflationIndex(const string& idxName, const
11271142 yieldCurve (YieldCurveType::Discount, ccy, Market::defaultConfiguration)));
11281143 }
11291144 QuantLib::ext::shared_ptr<ZeroInflationTermStructure> zeroCurve;
1130-
1145+
11311146 Date baseDate = QuantExt::ZeroInflation::curveBaseDate (false , asof_, conv->observationLag (), zii->frequency (), zii);
11321147 zeroCurve = QuantLib::ext::shared_ptr<PiecewiseZeroInflationCurve<Linear>>(
11331148 new PiecewiseZeroInflationCurve<Linear>(asof_, baseDate, conv->observationLag (), zii->frequency (), conv->dayCounter (), instruments));
@@ -1784,7 +1799,7 @@ TestConfigurationObjects::setupSensitivityScenarioData(bool hasSwapVolCube, bool
17841799 return sensiData;
17851800};
17861801
1787-
1802+
17881803QuantLib::ext::shared_ptr<ore::analytics::ScenarioSimMarketParameters> TestConfigurationObjects::setupSimMarketData2 () {
17891804 QuantLib::ext::shared_ptr<ore::analytics::ScenarioSimMarketParameters> simMarketData (
17901805 new ore::analytics::ScenarioSimMarketParameters ());
0 commit comments