@@ -208,6 +208,30 @@ void RequiredFixings::unsetPayDates() {
208208 yoyInflationFixingDates_ = newYoYInflationFixingDates;
209209}
210210
211+ RequiredFixings RequiredFixings::makeCopyWithMandatoryOverride (bool mandatory) {
212+ RequiredFixings result (*this );
213+ // we can't modify the elements of a set directly, need to make a copy and reassign
214+ std::set<FixingEntry> newFixingDates;
215+ std::set<ZeroInflationFixingEntry> newZeroInflationFixingDates;
216+ std::set<InflationFixingEntry> newYoYInflationFixingDates;
217+ for (auto f : result.fixingDates_ ) {
218+ f.mandatory = mandatory;
219+ newFixingDates.insert (f);
220+ }
221+ for (auto f : result.zeroInflationFixingDates_ ) {
222+ f.mandatory = mandatory;
223+ newZeroInflationFixingDates.insert (f);
224+ }
225+ for (auto f : yoyInflationFixingDates_) {
226+ f.mandatory = mandatory;
227+ newYoYInflationFixingDates.insert (f);
228+ }
229+ result.fixingDates_ = newFixingDates;
230+ result.zeroInflationFixingDates_ = newZeroInflationFixingDates;
231+ result.yoyInflationFixingDates_ = newYoYInflationFixingDates;
232+ return result;
233+ }
234+
211235RequiredFixings RequiredFixings::filteredFixingDates (const Date& settlementDate) {
212236 RequiredFixings rf;
213237 // If settlement date is an empty date, update to evaluation date.
@@ -656,17 +680,35 @@ void FixingDateGetter::visit(EquityMarginCoupon& c) {
656680
657681void FixingDateGetter::visit (CommodityCashFlow& c) {
658682 auto indices = c.indices ();
659- for (const auto & kv : indices) {
683+ for (const auto & [pricingDate, index] : indices) {
660684 // todays fixing is not mandatory, we will fallback to estimate it if its not there.
661- bool isTodaysFixing = Settings::instance ().evaluationDate () == kv.first ;
662- // see above, the ql and ORE index names are identical
663- requiredFixings_.addFixingDate (kv.first , kv.second ->name (), c.date (), false , !isTodaysFixing);
664- // if the pricing date is > future expiry, add the future expiry itself as well
665- if (auto d = kv.second ->expiryDate (); d != Date () && d < kv.first ) {
666- requiredFixings_.addFixingDate (d, kv.second ->name (), d);
667- }
668- if (auto baseFutureIndex = boost::dynamic_pointer_cast<CommodityBasisFutureIndex>(kv.second )) {
669- baseFutureIndex->baseCashflow (c.date ())->accept (*this );
685+ bool isTodaysFixing = Settings::instance ().evaluationDate () == pricingDate;
686+ if (auto powerIndex = boost::dynamic_pointer_cast<OffPeakPowerIndex>(index)) {
687+ // see above, the ql and ORE index names are identical
688+ requiredFixings_.addFixingDate (pricingDate, powerIndex->offPeakIndex ()->name (), c.date (), false ,
689+ !isTodaysFixing);
690+ bool isOffPeakDay = powerIndex->peakCalendar ().isHoliday (pricingDate);
691+ requiredFixings_.addFixingDate (pricingDate, powerIndex->peakIndex ()->name (), c.date (), false ,
692+ isOffPeakDay && !isTodaysFixing);
693+ // if the pricing date is > future expiry, add the future expiry itself as well
694+ if (auto d = index->expiryDate (); d != Date () && d < pricingDate) {
695+ requiredFixings_.addFixingDate (d, powerIndex->offPeakIndex ()->name (), c.date (), false , !isTodaysFixing);
696+ requiredFixings_.addFixingDate (d, powerIndex->peakIndex ()->name (), c.date (), false ,
697+ isOffPeakDay && !isTodaysFixing);
698+ }
699+ } else {
700+ requiredFixings_.addFixingDate (pricingDate, index->name (), c.date (), false , !isTodaysFixing);
701+ // if the pricing date is > future expiry, add the future expiry itself as well
702+ if (auto d = index->expiryDate (); d != Date () && d < pricingDate) {
703+ requiredFixings_.addFixingDate (d, index->name (), c.date (), false , !isTodaysFixing);
704+ }
705+ }
706+ if (auto baseFutureIndex = boost::dynamic_pointer_cast<CommodityBasisFutureIndex>(index)) {
707+ RequiredFixings tmpFixings;
708+ FixingDateGetter baseCashflowGetter (tmpFixings);
709+ baseFutureIndex->baseCashflow (c.date ())->accept (baseCashflowGetter);
710+ auto optionalFixings = tmpFixings.makeCopyWithMandatoryOverride (false );
711+ requiredFixings_.addData (optionalFixings);
670712 }
671713 }
672714}
0 commit comments