@@ -257,8 +257,8 @@ XMLNode* TRS::toXML(XMLDocument& doc) {
257257
258258boost::shared_ptr<QuantExt::FxIndex>
259259TRS::getFxIndex (const boost::shared_ptr<Market> market, const std::string& configuration, const std::string& domestic,
260- const std::string& foreign,
261- std::map <std::string, boost::shared_ptr<QuantExt::FxIndex>>& fxIndices ) const {
260+ const std::string& foreign, std::map<std::string, boost::shared_ptr<QuantExt::FxIndex>>& fxIndices,
261+ std::set <std::string>& missingFxIndexPairs ) const {
262262 if (domestic == foreign)
263263 return nullptr ;
264264 std::set<std::string> requiredCcys = {domestic, foreign};
@@ -275,7 +275,15 @@ TRS::getFxIndex(const boost::shared_ptr<Market> market, const std::string& confi
275275 return fx;
276276 }
277277 }
278- QL_FAIL (" TRS:getFxIndex(): no fx terms for " << domestic << " vs " << foreign);
278+
279+ // build a fx index, so that the processing can continue, but add to the error messages,
280+ // which - if not empty - will fail the trade build eventually
281+
282+ std::string f (" FX-GENERIC-" + domestic + " -" + foreign);
283+ auto fx = buildFxIndex (f, domestic, foreign, market, configuration, false );
284+ fxIndices[f] = fx;
285+ missingFxIndexPairs.insert (domestic + foreign);
286+ return fx;
279287}
280288
281289void TRS::build (const boost::shared_ptr<EngineFactory>& engineFactory) {
@@ -381,13 +389,16 @@ void TRS::build(const boost::shared_ptr<EngineFactory>& engineFactory) {
381389
382390 // get fx indices for conversion return and add cf ccy to funding ccy
383391
392+ std::set<std::string> missingFxIndexPairs;
393+
384394 auto fxIndexReturn = getFxIndex (engineFactory->market (), engineFactory->configuration (MarketContext::pricing),
385- returnData_.currency (), fundingCurrency, initialFxIndices);
395+ returnData_.currency (), fundingCurrency, initialFxIndices, missingFxIndexPairs );
386396 auto fxIndexAdditionalCashflows =
387397 additionalCashflowData_.legData ().currency ().empty ()
388398 ? fxIndexReturn
389399 : getFxIndex (engineFactory->market (), engineFactory->configuration (MarketContext::pricing),
390- additionalCashflowData_.legData ().currency (), fundingCurrency, fxIndicesDummy);
400+ additionalCashflowData_.legData ().currency (), fundingCurrency, fxIndicesDummy,
401+ missingFxIndexPairs);
391402
392403 Real initialPrice = returnData_.initialPrice ();
393404
@@ -411,13 +422,13 @@ void TRS::build(const boost::shared_ptr<EngineFactory>& engineFactory) {
411422 std::vector<Leg> returnLegs;
412423 auto builder = TrsUnderlyingBuilderFactory::instance ().getBuilder (
413424 underlyingDerivativeId_[i].empty () ? underlying_[i]->tradeType () : " Derivative" );
414- builder->build (id (), underlying_[i], valuationDates, paymentDates, fundingCurrency,
415- engineFactory, underlyingIndex[i], underlyingMultiplier[i],
416- localIndexNamesAndQuantities, localFxIndices,
417- underlying_.size () == 1 ? initialPrice : dummyInitialPrice,
418- assetCurrency[i], localCreditRiskCurrency, creditQualifierMapping_, localMaturity,
425+ builder->build (id (), underlying_[i], valuationDates, paymentDates, fundingCurrency, engineFactory,
426+ underlyingIndex[i], underlyingMultiplier[i], localIndexNamesAndQuantities, localFxIndices,
427+ underlying_.size () == 1 ? initialPrice : dummyInitialPrice, assetCurrency[i],
428+ localCreditRiskCurrency, creditQualifierMapping_, localMaturity,
419429 std::bind (&TRS::getFxIndex, this , std::placeholders::_1, std::placeholders::_2,
420- std::placeholders::_3, std::placeholders::_4, std::placeholders::_5),
430+ std::placeholders::_3, std::placeholders::_4, std::placeholders::_5,
431+ std::ref (missingFxIndexPairs)),
421432 underlyingDerivativeId_[i], requiredFixings_, returnLegs);
422433
423434 addTRSRequiredFixings (requiredFixings_, returnLegs, fxIndexReturn);
@@ -442,7 +453,7 @@ void TRS::build(const boost::shared_ptr<EngineFactory>& engineFactory) {
442453 << fundingCurrency << " , return ccy is " << returnData_.currency ());
443454
444455 fxIndexAsset[i] = getFxIndex (engineFactory->market (), engineFactory->configuration (MarketContext::pricing),
445- assetCurrency[i], fundingCurrency, localFxIndices);
456+ assetCurrency[i], fundingCurrency, localFxIndices, missingFxIndexPairs );
446457 DLOG (" underlying #" << (i + 1 ) << " index (" << underlyingIndex[i]->name () << " ) built." );
447458 DLOG (" underlying #" << (i + 1 ) << " multiplier is " << underlyingMultiplier[i]);
448459
@@ -455,18 +466,24 @@ void TRS::build(const boost::shared_ptr<EngineFactory>& engineFactory) {
455466 fxIndices.insert (localFxIndices.begin (), localFxIndices.end ());
456467 }
457468
469+ // check that we have all fx terms that we needed to build the fx indices
470+
471+ QL_REQUIRE (missingFxIndexPairs.empty (), " TRS::build(): missing FXTerms for the following pairs: "
472+ << boost::algorithm::join (missingFxIndexPairs, " , " ));
473+
458474 // set initial price currency
459475
460- std::string initialPriceCurrency;
461- if (returnData_.initialPrice () != Null<Real>() && !returnData_.initialPriceCurrency ().empty ())
462- initialPriceCurrency = returnData_.initialPriceCurrency ();
463- else {
464- initialPriceCurrency = assetCurrency.front ();
465- for (Size i = 1 ; i < assetCurrency.size (); ++i) {
466- QL_REQUIRE (assetCurrency[i] == initialPriceCurrency,
467- " TRS::build(): can not determine unique initial price currency, since it is not given in the "
468- " trade data and the underlyings have different asset currencies (e.g. '"
469- << assetCurrency[i] << " , " << initialPriceCurrency << " )" );
476+ QL_REQUIRE (!assetCurrency.empty (), " TRS::build(): no underlying given." );
477+
478+ std::string initialPriceCurrency =
479+ returnData_.initialPriceCurrency ().empty () ? assetCurrency.front () : returnData_.initialPriceCurrency ();
480+
481+ if (initialPrice != Null<Real>() && returnData_.initialPriceCurrency ().empty ()) {
482+ for (auto const & ccy : assetCurrency) {
483+ QL_REQUIRE (ccy == initialPriceCurrency, " TRS::build(): can not determine unique initial price currency "
484+ " from asset currencies for initial price ("
485+ << returnData_.initialPrice ()
486+ << " ), please add the initial price currency to the trade xml" );
470487 }
471488 }
472489
0 commit comments