@@ -31,15 +31,15 @@ namespace analytics {
3131
3232// Additional quotes for fx fixings, add fixing quotes with USD and EUR to the list of fixings
3333// requested in order to triangulate missing fixings
34- void additional_fx_fixings (const string& fixingId, const set<Date>& fixingDates, FixingMap& relevantFixings) {
34+ void additional_fx_fixings (const string& fixingId, const RequiredFixings::FixingDates& fixingDates,
35+ FixingMap& relevantFixings) {
3536 std::vector<std::string> tokens;
3637 boost::split (tokens, fixingId, boost::is_any_of (" -" ));
3738 QL_REQUIRE (tokens.size () == 4 , " MarketDataLoader::additional_fx_fixings: Invalid fixing id, "
3839 << " must be of form FX-TYPE-CCY1-CCY, e.g FX-ECB-EUR-GBP" );
3940
4041 // add fixings on inverted ccy pair
41- relevantFixings[tokens[0 ] + " -" + tokens[1 ] + " -" + tokens[3 ] + " -" + tokens[2 ]].insert (fixingDates.begin (),
42- fixingDates.end ());
42+ relevantFixings[tokens[0 ] + " -" + tokens[1 ] + " -" + tokens[3 ] + " -" + tokens[2 ]].addDates (fixingDates, false );
4343
4444 vector<string> baseCcys = {" USD" , " EUR" };
4545
@@ -48,28 +48,28 @@ void additional_fx_fixings(const string& fixingId, const set<Date>& fixingDates,
4848 string fixingType = tokens[0 ] + " -" + tokens[1 ] + " -" ;
4949 if (tokens[2 ] != ccy) {
5050 string fix = fixingType + ccy + " -" + tokens[2 ];
51- relevantFixings[fix].insert (fixingDates. begin (), fixingDates. end () );
51+ relevantFixings[fix].addDates (fixingDates, false );
5252
5353 if (tokens[3 ] != ccy) {
5454 fix = fixingType + tokens[2 ] + " -" + ccy;
55- relevantFixings[fix].insert (fixingDates. begin (), fixingDates. end () );
55+ relevantFixings[fix].addDates (fixingDates, false );
5656 }
5757 }
5858
5959 if (tokens[3 ] != ccy) {
6060 string fix = fixingType + ccy + " -" + tokens[3 ];
61- relevantFixings[fix].insert (fixingDates. begin (), fixingDates. end () );
61+ relevantFixings[fix].addDates (fixingDates, false );
6262
6363 if (tokens[2 ] != ccy) {
6464 fix = fixingType + tokens[3 ] + " -" + ccy;
65- relevantFixings[fix].insert (fixingDates. begin (), fixingDates. end () );
65+ relevantFixings[fix].addDates (fixingDates, false );
6666 }
6767 }
6868 }
6969}
7070
7171// Additional quotes for commodity fixings
72- void additional_commodity_fixings (const string& fixingId, const set<Date> & fixingDates, FixingMap& fixings,
72+ void additional_commodity_fixings (const string& fixingId, const RequiredFixings::FixingDates & fixingDates, FixingMap& fixings,
7373 map<pair<string, Date>, set<Date>>& commodityMap) {
7474
7575 boost::shared_ptr<Conventions> conventions = InstrumentConventions::instance ().conventions ();
@@ -86,7 +86,7 @@ void additional_commodity_fixings(const string& fixingId, const set<Date>& fixin
8686 // Add historical fixings for daily and monthly expiring contracts
8787 // TODO: potentially need to add for OffPeakPowerIndex commodities too.
8888 if (cfc->contractFrequency () == Daily) {
89- for (const auto & fd : fixingDates) {
89+ for (const auto & [fd, _] : fixingDates) {
9090 // Add 1 week lookback for each date for daily expiry
9191 set<Date> dates;
9292 Date wLookback = fd - Period (1 , Weeks);
@@ -97,12 +97,12 @@ void additional_commodity_fixings(const string& fixingId, const set<Date>& fixin
9797 TLOG (" Adding (date, id) = (" << io::iso_date (fd) << " ," << fixingId << " )" );
9898 // Add to the fixings so a fixing is requested for all dates, and also to the commodityMap
9999 // so we can map a fixing to the correct date required
100- fixings[fixingId].insert (dates. begin (), dates. end () );
100+ fixings[fixingId].addDates (dates, false );
101101 commodityMap[pair (fixingId, fd)].insert (dates.begin (), dates.end ());
102102 }
103103 } else {
104104 // for monthly expiries add fixings for the last 45 days
105- for (const auto & fd : fixingDates) {
105+ for (const auto & [fd,_] : fixingDates) {
106106 set<Date> dates;
107107 Date wLookback = fd - Period (45 , Days);
108108 do {
@@ -112,15 +112,15 @@ void additional_commodity_fixings(const string& fixingId, const set<Date>& fixin
112112 TLOG (" Adding (date, id) = (" << io::iso_date (fd) << " ," << fixingId << " )" );
113113 // Add to the fixings so a fixing is requested for all dates, and also to the commodityMap
114114 // so we can map a fixing to the correct date required
115- fixings[fixingId].insert (dates. begin (), dates. end () );
115+ fixings[fixingId].addDates (dates, false );
116116 commodityMap[pair (fixingId, fd)].insert (dates.begin (), dates.end ());
117117 }
118118 }
119119 }
120120}
121121
122122// Additional fixings for equity index decomposition
123- void additional_equity_fixings (map<string, set<Date> >& fixings, const TodaysMarketParameters& mktParams,
123+ void additional_equity_fixings (map<string, RequiredFixings::FixingDates >& fixings, const TodaysMarketParameters& mktParams,
124124 const boost::shared_ptr<ReferenceDataManager> refData,
125125 const boost::shared_ptr<CurveConfigurations>& curveConfigs) {
126126 std::string configuration = Market::defaultConfiguration;
@@ -146,7 +146,7 @@ const boost::shared_ptr<MarketDataLoaderImpl>& MarketDataLoader::impl() const {
146146}
147147
148148void MarketDataLoader::addRelevantFixings (
149- const std::pair<std::string, std::set<QuantLib::Date> >& fixing,
149+ const std::pair<std::string, RequiredFixings::FixingDates >& fixing,
150150 std::map<std::pair<std::string, QuantLib::Date>, std::set<QuantLib::Date>>& lastAvailableFixingLookupMap) {
151151 if (isFxIndex (fixing.first )) {
152152 // for FX fixings we want to add additional fixings to allow triangulation in case of missing
@@ -156,9 +156,7 @@ void MarketDataLoader::addRelevantFixings(
156156 if (isCommodityIndex (fixing.first )) {
157157 additional_commodity_fixings (fixing.first , fixing.second , fixings_, lastAvailableFixingLookupMap);
158158 }
159- fixings_[fixing.first ].insert (fixing.second .begin (), fixing.second .end ());
160- // also add to portfolioFixings_, used for alerting missing required fixings
161- portfolioFixings_[fixing.first ].insert (fixing.second .begin (), fixing.second .end ());
159+ fixings_[fixing.first ].addDates (fixing.second );
162160}
163161
164162void MarketDataLoader::populateFixings (
@@ -191,7 +189,6 @@ void MarketDataLoader::populateFixings(
191189 if (inputs_->eomInflationFixings ()) {
192190 LOG (" Adjust inflation fixing dates to the end of the month before the request" );
193191 amendInflationFixingDates (fixings_);
194- amendInflationFixingDates (portfolioFixings_);
195192 }
196193
197194 if (fixings_.size () > 0 )
@@ -200,13 +197,13 @@ void MarketDataLoader::populateFixings(
200197 // apply all fixings now
201198 applyFixings (loader_->loadFixings ());
202199
203- // check and warn any missing fixings - only warn for portfolio fixings
204- for (const auto & f : portfolioFixings_ ) {
205- for (const auto & d : f. second ) {
206- if (!loader_->hasFixing (f. first , d)) {
200+ // check and warn any missing fixings - only warn for mandatory fixings
201+ for (const auto & [indexName, fixingDates] : fixings_ ) {
202+ for (const auto & [d, mandatory] :fixingDates ) {
203+ if (mandatory && !loader_->hasFixing (indexName , d)) {
207204 string fixingErr = " " ;
208- if (isFxIndex (f. first )) {
209- auto fxInd = parseFxIndex (f. first );
205+ if (isFxIndex (indexName )) {
206+ auto fxInd = parseFxIndex (indexName );
210207 try {
211208 if (fxInd->fixingCalendar ().isBusinessDay (d))
212209 fxInd->fixing (d);
@@ -215,7 +212,7 @@ void MarketDataLoader::populateFixings(
215212 fixingErr = " , error: " + ore::data::to_string (e.what ());
216213 }
217214 }
218- StructuredFixingWarningMessage (f. first , d, " Missing fixing" , " Could not find required fixing ID." )
215+ StructuredFixingWarningMessage (indexName , d, " Missing fixing" , " Could not find required fixing ID." )
219216 .log ();
220217 }
221218 }
0 commit comments