@@ -460,24 +460,32 @@ void runCoreEngine(const boost::shared_ptr<ore::data::Portfolio>& portfolio,
460460 resFee[0 ][0 ],
461461 tradeId[j], 0 );
462462 int dateIndex = -1 ;
463+ std::map<QuantLib::Date, size_t > dateIndexCache;
464+ std::map<QuantLib::Date, double > dateTimeCache;
463465 for (Size k = 0 ; k < sgd->getGrid ()->dates ().size (); ++k) {
464466 Real t = sgd->getGrid ()->timeGrid ()[k + 1 ];
465- Real tm = sgd-> getGrid ()-> timeGrid ()[k];
467+
466468 if (sgd->getGrid ()->isCloseOutDate ()[k]) {
467- QL_REQUIRE (dateIndex >= 0 , " first date in grid must be a valuation date" );
469+ Date closeOutDate = sgd->getGrid ()->dates ()[k];
470+ Date valuationDate = sgd->getGrid ()->valuationDateFromCloseOutDate (closeOutDate);
471+ auto dateIndexIt = dateIndexCache.find (valuationDate);
472+ QL_REQUIRE (dateIndexIt != dateIndexCache.end (), " first date in grid must be a valuation date" );
473+ Real tm = dateTimeCache[valuationDate];
468474 for (Size i = 0 ; i < outputCube->samples (); ++i) {
469475 Real v = outputCube->get (tradeId[j], dateIndex, i, 1 );
470476 outputCube->set (v + resLag[dateIndex + 1 ][i] * fx (fxBuffer, currencyIndex[j], k + 1 , i) *
471477 num (model, irStateBuffer, currencyIndex[j], k + 1 , tm, i) *
472478 effectiveMultiplier[j] +
473479 resFee[dateIndex + 1 ][i],
474- tradeId[j], dateIndex , i, 1 );
480+ tradeId[j], dateIndexIt-> second , i, 1 );
475481 }
476482 }
477483 if (sgd->getGrid ()->isValuationDate ()[k]) {
478- ++dateIndex;
484+ Date valuationDate = sgd->getGrid ()->dates ()[k];
485+ dateIndexCache[valuationDate] = ++dateIndex;
486+ dateTimeCache[valuationDate] = t;
479487 for (Size i = 0 ; i < outputCube->samples (); ++i) {
480- Real v = outputCube->get (tradeId[j], dateIndex, i, 1 );
488+ Real v = outputCube->get (tradeId[j], dateIndex, i, 0 );
481489 outputCube->set (v + res[dateIndex + 1 ][i] * fx (fxBuffer, currencyIndex[j], k + 1 , i) *
482490 numRatio (model, irStateBuffer, currencyIndex[j], k + 1 , t, i) *
483491 effectiveMultiplier[j] +
@@ -495,22 +503,27 @@ void runCoreEngine(const boost::shared_ptr<ore::data::Portfolio>& portfolio,
495503 numRatio (model, irStateBuffer, currencyIndex[j], 0 , 0.0 , 0 ) *
496504 effectiveMultiplier[j],
497505 tradeId[j], 0 );
506+ std::map<QuantLib::Date, size_t > dateIndexCache;
498507 int dateIndex = -1 ;
499508 for (Size k = 1 ; k < res.size (); ++k) {
500509 Real t = sgd->getGrid ()->timeGrid ()[k];
501510 if (sgd->getGrid ()->isCloseOutDate ()[k - 1 ]) {
502- QL_REQUIRE (dateIndex >= 0 , " first date in grid must be a valuation date" );
511+ Date closeOutDate = sgd->getGrid ()->dates ()[k-1 ];
512+ Date valuationDate = sgd->getGrid ()->valuationDateFromCloseOutDate (closeOutDate);
513+ auto dateIndexIt = dateIndexCache.find (valuationDate);
514+ QL_REQUIRE (dateIndexIt != dateIndexCache.end (), " first date in grid must be a valuation date" );
503515 for (Size i = 0 ; i < outputCube->samples (); ++i) {
504516 Real v = outputCube->get (tradeId[j], dateIndex, i, 1 );
505517 outputCube->set (v + res[k][i] * fx (fxBuffer, currencyIndex[j], k, i) *
506518 num (model, irStateBuffer, currencyIndex[j], k, t, i) *
507519 effectiveMultiplier[j] +
508520 resFee[k][i],
509- tradeId[j], dateIndex , i, 1 );
521+ tradeId[j], dateIndexIt-> second , i, 1 );
510522 }
511523 }
512524 if (sgd->getGrid ()->isValuationDate ()[k - 1 ]) {
513- ++dateIndex;
525+ Date valuationDate = sgd->getGrid ()->dates ()[k-1 ];
526+ dateIndexCache[valuationDate] = ++dateIndex;
514527 for (Size i = 0 ; i < outputCube->samples (); ++i) {
515528 Real v = outputCube->get (tradeId[j], dateIndex, i, 0 );
516529 outputCube->set (v + res[k][i] * fx (fxBuffer, currencyIndex[j], k, i) *
0 commit comments