diff --git a/OREData/ored/portfolio/cashflowutils.cpp b/OREData/ored/portfolio/cashflowutils.cpp index 963d67a0b1..61a3deac1c 100644 --- a/OREData/ored/portfolio/cashflowutils.cpp +++ b/OREData/ored/portfolio/cashflowutils.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -62,6 +63,7 @@ void populateReportDataFromAdditionalResults(std::vectordiscountCurve(ccy, configuration) : specificDiscountCurve; discountFactor = cf.payDate < asof ? 0.0 : discountCurve->discount(cf.payDate); } - if (ccy != baseCurrency) { - auto baseDiscountCurve = specificDiscountCurve.empty() ? market->discountCurve(baseCurrency, configuration) : specificDiscountCurve; - discountFactorBase = cf.payDate < asof ? 0.0 : baseDiscountCurve->discount(cf.payDate); - } + if (ccy != baseCurrency && cf.payDate != Null()) { + try { + auto baseDiscountCurve = + specificDiscountCurve.empty() ? market->discountCurve(baseCurrency, configuration) : specificDiscountCurve; + discountFactorBase = cf.payDate < asof ? 0.0 : baseDiscountCurve->discount(cf.payDate); + } catch (std::exception& e) { + if (!missingBaseDiscountCurveLogged) { + DLOG("Could not retrieve base discount curve for cashflow report (base currency " + << baseCurrency << ", configuration " << configuration + << "). DiscountFactor(Base) will be left null. Details: " << e.what()); + missingBaseDiscountCurveLogged = true; + } + } + } if (cf.presentValue != Null()) { presentValue = cf.presentValue * multiplier; } else if (effectiveAmount != Null() && discountFactor != Null()) { diff --git a/OREData/ored/portfolio/trade.cpp b/OREData/ored/portfolio/trade.cpp index 6e0a1a39bf..e195aa457f 100644 --- a/OREData/ored/portfolio/trade.cpp +++ b/OREData/ored/portfolio/trade.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -449,6 +450,7 @@ std::vector Trade::cashflows(const std::string& baseCur // add cashflows from trade legs, if no cashflows were added so far or if a leg is marked as mandatory for cashflows bool haveEngineCashflows = !result.empty(); + bool missingBaseDiscountCurveLogged = false; for (size_t i = 0; i < legs().size(); i++) { Trade::LegCashflowInclusion cashflowInclusion = Trade::LegCashflowInclusion::IfNoEngineCashflows; if (auto incl = legCashflowInclusion().find(i); incl != legCashflowInclusion().end()) { @@ -465,10 +467,20 @@ std::vector Trade::cashflows(const std::string& baseCur string ccy = legCurrencies()[i]; Handle discountCurve = specificDiscountCurve; - if (discountCurve.empty()) + if (discountCurve.empty()) discountCurve = market->discountCurve(ccy, configuration); - - Handle baseDiscountCurve = market->discountCurve(baseCurrency, configuration); + + QuantLib::ext::shared_ptr baseDiscountCurve; + try { + baseDiscountCurve = *market->discountCurve(baseCurrency, configuration); + } catch (std::exception& e) { + if (!missingBaseDiscountCurveLogged) { + DLOG("Could not retrieve base discount curve for cashflow report (base currency " + << baseCurrency << ", configuration " << configuration + << "). Base discount factor column will be left null where required. Details: " << e.what()); + missingBaseDiscountCurveLogged = true; + } + } auto fxRateCcyBase = market->fxRate(npvCurrency_ + baseCurrency, configuration)->value(); auto fxRateLocalCcy = market->fxRate(ccy + npvCurrency_, configuration)->value(); @@ -487,7 +499,7 @@ std::vector Trade::cashflows(const std::string& baseCur [&market, &configuration](const std::string qualifier) { return *market->capFloorVol(qualifier, configuration); }, - std::string(), Null(), *baseDiscountCurve)); + std::string(), Null(), baseDiscountCurve)); result.back().cashflowNo = j + 1; result.back().legNo = i + legNoOffset; }