Skip to content

Commit e284b7a

Browse files
committed
QPR-12206 support IndexedCoupons in AMC simulation
1 parent 63e73dd commit e284b7a

2 files changed

Lines changed: 125 additions & 51 deletions

File tree

OREData/ored/portfolio/swap.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ using std::make_pair;
4242
namespace ore {
4343
namespace data {
4444

45+
46+
47+
4548
void Swap::build(const boost::shared_ptr<EngineFactory>& engineFactory) {
4649
DLOG("Swap::build() called for trade " << id());
4750

@@ -55,6 +58,7 @@ void Swap::build(const boost::shared_ptr<EngineFactory>& engineFactory) {
5558
Size numLegs = legData_.size();
5659
legPayers_ = vector<bool>(numLegs);
5760
std::vector<QuantLib::Currency> currencies(numLegs);
61+
std::vector<QuantLib::Currency> currenciesForMcSimulation;
5862
legs_.resize(numLegs);
5963

6064
isXCCY_ = false;
@@ -67,11 +71,36 @@ void Swap::build(const boost::shared_ptr<EngineFactory>& engineFactory) {
6771
currencies[i] = parseCurrencyWithMinors(legData_[i].currency());
6872
else
6973
currencies[i] = parseCurrency(legData_[i].currency());
74+
7075
if (currencies[i] != currency)
7176
isXCCY_ = true;
7277
isResetting_ = isResetting_ || (!legData_[i].isNotResetXCCY());
7378
}
7479

80+
81+
// Check if there is indexing is used, need to collect all underlying currrencies
82+
// for AMC simulations, such a trade needs to be treated a x-ccy swap with both leg paying
83+
// one currency.
84+
auto addUnique = [](vector<Currency>& currencies, Currency ccy) {
85+
if (std::find(currencies.begin(), currencies.end(), ccy) ==
86+
currencies.end()) {
87+
currencies.push_back(ccy);
88+
}
89+
};
90+
91+
for (Size i = 0; i < numLegs; ++i) {
92+
addUnique(currenciesForMcSimulation, currencies[i]);
93+
vector<Indexing> indexings = legData_[i].indexing();
94+
if (!indexings.empty() && indexings.front().hasData()) {
95+
Indexing indexing = indexings.front();
96+
if (boost::starts_with(indexing.index(), "FX-")) {
97+
auto index = parseFxIndex(indexing.index());
98+
addUnique(currenciesForMcSimulation, index->targetCurrency());
99+
addUnique(currenciesForMcSimulation, index->sourceCurrency());
100+
}
101+
}
102+
}
103+
isXCCY_ = isXCCY_ || currenciesForMcSimulation.size() > 1;
75104
static std::set<std::string> eligibleForXbs = {"Fixed", "Floating"};
76105
bool useXbsCurves = true;
77106
for(Size i=0;i<numLegs;++i) {
@@ -151,7 +180,7 @@ void Swap::build(const boost::shared_ptr<EngineFactory>& engineFactory) {
151180
boost::shared_ptr<CrossCurrencySwapEngineBuilderBase> swapBuilder =
152181
boost::dynamic_pointer_cast<CrossCurrencySwapEngineBuilderBase>(builder);
153182
QL_REQUIRE(swapBuilder, "No Builder found for CrossCurrencySwap " << id());
154-
swap->setPricingEngine(swapBuilder->engine(currencies, npvCcy));
183+
swap->setPricingEngine(swapBuilder->engine(currenciesForMcSimulation, npvCcy));
155184
// take the first legs currency as the npv currency (arbitrary choice)
156185
instrument_.reset(new VanillaInstrument(swap));
157186
} else {

0 commit comments

Comments
 (0)