Populate the factors that we need to value the floating leg of a swap referencing a future contract given a Monte Carlo sample. This is to avoid recalculation of these quantities on each iteration.
613 {
614
615 Size numCfs =
arguments_.legs[idxFloat].size();
616
617 QL_REQUIRE(numCfs == floatLegFactors.rows(),
618 "Expected number of rows in floatLegFactors to equal number of cashflows");
619 QL_REQUIRE(numCfs == discounts.size(), "Expected size of discounts to equal number of cashflows");
620 QL_REQUIRE(numCfs == amounts.size(), "Expected size of amounts to equal number of cashflows");
621 QL_REQUIRE(expiries.size() == floatLegFactors.columns(),
622 "Expected number of columns in floatLegFactors to equal number of expiries");
623
624
626 for (Size i = 0; i < numCfs; i++) {
627 auto ccf = QuantLib::ext::dynamic_pointer_cast<CommodityIndexedAverageCashFlow>(
arguments_.legs[idxFloat][i]);
628 QL_REQUIRE(ccf, "futureFloatLegFactors: expected a CommodityIndexedAverageCashFlow");
629 Size numObs = ccf->indices().size();
630 for (const auto& p : ccf->indices()) {
631 Date expiry = p.second->expiryDate();
632 auto it = find(expiries.begin(), expiries.end(), expiry);
633 QL_REQUIRE(it != expiries.end(), "futureFloatLegFactors: expected to find expiry in expiries vector");
634 auto idx = distance(expiries.begin(), it);
635 Real fxRate{1.};
636 if (ccf->fxIndex())
637 fxRate = ccf->fxIndex()->fixing(expiry);
638 floatLegFactors[i][idx] += fxRate * p.second->fixing(expiry) / numObs;
639 }
641 amounts[i] = ccf->periodQuantity();
642 }
643 } else {
644 for (Size i = 0; i < numCfs; i++) {
645 auto ccf = QuantLib::ext::dynamic_pointer_cast<CommodityIndexedCashFlow>(
arguments_.legs[idxFloat][i]);
646 QL_REQUIRE(ccf, "futureFloatLegFactors: expected a CommodityIndexedCashFlow");
647
648 auto it = find(expiries.begin(), expiries.end(), ccf->index()->expiryDate());
649 QL_REQUIRE(it != expiries.end(), "futureFloatLegFactors: expected to find expiry in expiries vector");
650 auto idx = distance(expiries.begin(), it);
651 floatLegFactors[i][idx] = 1.0;
653 amounts[i] = ccf->amount();
654 }
655 }
656
657
658 for (Size i = 0; i < discounts.size(); i++) {
659 discounts[i] /= discountExercise;
660 }
661}