Skip to content

Commit 42bf48b

Browse files
author
jenkins
committed
git subrepo pull (merge) ore
subrepo: subdir: "ore" merged: "200f02188a" upstream: origin: "git@gitlab.acadiasoft.net:qs/ore.git" branch: "master" commit: "a12a2e80aa" git-subrepo: version: "0.4.6" origin: "https://github.com/ingydotnet/git-subrepo" commit: "110b9eb"
2 parents 001b0b7 + a12a2e8 commit 42bf48b

3 files changed

Lines changed: 87 additions & 43 deletions

File tree

OREData/ored/portfolio/genericbarrieroption.cpp

Lines changed: 79 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ namespace data {
3030

3131
static const std::string mcscript =
3232
" REQUIRE PayoffType == 0 OR PayoffType == 1;\n"
33-
" REQUIRE TransatlanticBarrierType >= 0 AND TransatlanticBarrierType <= 4;\n"
33+
" REQUIRE SIZE(Underlyings) == SIZE(TransatlanticBarrierType);\n"
3434
" REQUIRE SIZE(BarrierTypes) == SIZE(BarrierLevels) / SIZE(Underlyings);\n"
3535
" REQUIRE SIZE(BarrierTypes) == SIZE(BarrierRebates);\n"
3636
" REQUIRE SIZE(BarrierTypes) == SIZE(BarrierRebateCurrencies);\n"
@@ -90,10 +90,11 @@ namespace data {
9090
"\n"
9191
" TransatlanticActive = 1;\n"
9292
" FOR k IN (1, SIZE(Underlyings), 1) DO\n"
93-
" IF { TransatlanticBarrierType == 1 AND Underlyings[k](ExpiryDate) >= TransatlanticBarrierLevel[k] } OR\n"
94-
" { TransatlanticBarrierType == 2 AND Underlyings[k](ExpiryDate) <= TransatlanticBarrierLevel[k] } OR\n"
95-
" { TransatlanticBarrierType == 3 AND Underlyings[k](ExpiryDate) < TransatlanticBarrierLevel[k] } OR\n"
96-
" { TransatlanticBarrierType == 4 AND Underlyings[k](ExpiryDate) > TransatlanticBarrierLevel[k] } THEN\n"
93+
" REQUIRE TransatlanticBarrierType[k] >= 0 AND TransatlanticBarrierType[k] <= 4;\n"
94+
" IF { TransatlanticBarrierType[k] == 1 AND Underlyings[k](ExpiryDate) >= TransatlanticBarrierLevel[k] } OR\n"
95+
" { TransatlanticBarrierType[k] == 2 AND Underlyings[k](ExpiryDate) <= TransatlanticBarrierLevel[k] } OR\n"
96+
" { TransatlanticBarrierType[k] == 3 AND Underlyings[k](ExpiryDate) < TransatlanticBarrierLevel[k] } OR\n"
97+
" { TransatlanticBarrierType[k] == 4 AND Underlyings[k](ExpiryDate) > TransatlanticBarrierLevel[k] } THEN\n"
9798
" TransatlanticActive = 0;\n"
9899
" END;\n"
99100
" END;\n"
@@ -116,7 +117,7 @@ namespace data {
116117

117118
static const std::string fdscript =
118119
" REQUIRE PayoffType == 0 OR PayoffType == 1;\n"
119-
" REQUIRE TransatlanticBarrierType >= 0 AND TransatlanticBarrierType <= 4;\n"
120+
" REQUIRE SIZE(Underlyings) == SIZE(TransatlanticBarrierType);\n"
120121
" REQUIRE SIZE(BarrierTypes) == SIZE(BarrierLevels) / SIZE(Underlyings);\n"
121122
" REQUIRE SIZE(BarrierTypes) == SIZE(BarrierRebates);\n"
122123
" REQUIRE SIZE(BarrierTypes) == SIZE(BarrierRebateCurrencies);\n"
@@ -135,10 +136,11 @@ namespace data {
135136
"\n"
136137
" TransatlanticActive = 1;\n"
137138
" FOR k IN (1, SIZE(Underlyings), 1) DO\n"
138-
" IF { TransatlanticBarrierType == 1 AND Underlyings[k](ExpiryDate) >= TransatlanticBarrierLevel[k] } OR\n"
139-
" { TransatlanticBarrierType == 2 AND Underlyings[k](ExpiryDate) <= TransatlanticBarrierLevel[k] } OR\n"
140-
" { TransatlanticBarrierType == 3 AND Underlyings[k](ExpiryDate) < TransatlanticBarrierLevel[k] } OR\n"
141-
" { TransatlanticBarrierType == 4 AND Underlyings[k](ExpiryDate) > TransatlanticBarrierLevel[k] } THEN\n"
139+
" REQUIRE TransatlanticBarrierType[k] >= 0 AND TransatlanticBarrierType[k] <= 4;\n"
140+
" IF { TransatlanticBarrierType[k] == 1 AND Underlyings[k](ExpiryDate) >= TransatlanticBarrierLevel[k] } OR\n"
141+
" { TransatlanticBarrierType[k] == 2 AND Underlyings[k](ExpiryDate) <= TransatlanticBarrierLevel[k] } OR\n"
142+
" { TransatlanticBarrierType[k] == 3 AND Underlyings[k](ExpiryDate) < TransatlanticBarrierLevel[k] } OR\n"
143+
" { TransatlanticBarrierType[k] == 4 AND Underlyings[k](ExpiryDate) > TransatlanticBarrierLevel[k] } THEN\n"
142144
" TransatlanticActive = 0;\n"
143145
" END;\n"
144146
" END;\n"
@@ -297,31 +299,61 @@ void GenericBarrierOption::build(const boost::shared_ptr<EngineFactory>& factory
297299
(quantity_.empty() && strike_.empty() && !amount_.empty()),
298300
"Need no Quantity, no Strike, Amount for PayoffType = CashOrNothing");
299301

300-
std::string transatlanticBarrierType = "0";
302+
std::vector<std::string> transatlanticBarrierType(underlyings_.size(), "0");
301303
std::vector<std::string> transatlanticBarrierLevel(underlyings_.size(), "0");
302304
std::string transatlanticBarrierRebate = "0.0";
303305
std::string transatlanticBarrierRebateCurrency = payCurrency_;
304-
if (!transatlanticBarrier_.type().empty()) {
305-
if (transatlanticBarrier_.type() == "DownAndIn")
306-
transatlanticBarrierType = "1";
307-
else if (transatlanticBarrier_.type() == "UpAndIn")
308-
transatlanticBarrierType = "2";
309-
else if (transatlanticBarrier_.type() == "DownAndOut")
310-
transatlanticBarrierType = "3";
311-
else if (transatlanticBarrier_.type() == "UpAndOut")
312-
transatlanticBarrierType = "4";
313-
else {
314-
QL_FAIL("Transatlantic BarrierType (" << transatlanticBarrier_.type()
315-
<< ") must be DownAndIn, UpAndIn, DownAndOut, UpAndOut");
306+
if (!transatlanticBarrier_[0].type().empty()) {
307+
transatlanticBarrierType.clear();
308+
for (auto const& n : transatlanticBarrier_) {
309+
if (n.type() == "DownAndIn")
310+
transatlanticBarrierType.push_back("1");
311+
else if (n.type() == "UpAndIn")
312+
transatlanticBarrierType.push_back("2");
313+
else if (n.type() == "DownAndOut")
314+
transatlanticBarrierType.push_back("3");
315+
else if (n.type() == "UpAndOut")
316+
transatlanticBarrierType.push_back("4");
317+
else {
318+
QL_FAIL("Transatlantic BarrierType (" << n.type()
319+
<< ") must be DownAndIn, UpAndIn, DownAndOut, UpAndOut");
320+
}
321+
}
322+
QL_REQUIRE(transatlanticBarrierType.size() == 1 || transatlanticBarrierType.size() == underlyings_.size(),
323+
"Transatlantic Barrier must have only 1 Barrier block or 1 block for each underlyings, got "
324+
<< transatlanticBarrierType.size());
325+
if (transatlanticBarrierType.size() == 1 && underlyings_.size() > 1) {
326+
transatlanticBarrierType.assign(underlyings_.size(), transatlanticBarrierType[0]);
316327
}
317-
QL_REQUIRE(transatlanticBarrier_.levels().size() == underlyings_.size(),
318-
"Transatlantic Barrier must have exactly 1 level for each underlying, got " << transatlanticBarrier_.levels().size());
319328
transatlanticBarrierLevel.clear();
320-
for (const auto& l : transatlanticBarrier_.levels())
321-
transatlanticBarrierLevel.push_back(boost::lexical_cast<std::string>(l.value()));
322-
transatlanticBarrierRebate = boost::lexical_cast<std::string>(transatlanticBarrier_.rebate());
323-
if (!transatlanticBarrier_.rebateCurrency().empty())
324-
transatlanticBarrierRebateCurrency = transatlanticBarrier_.rebateCurrency();
329+
if (transatlanticBarrier_.size() == 1) {
330+
QL_REQUIRE(transatlanticBarrier_[0].levels().size() == underlyings_.size(),
331+
"Transatlantic Barrier must have exactly 1 level for each underlying, got "
332+
<< transatlanticBarrier_[0].levels().size());
333+
for (const auto& l : transatlanticBarrier_[0].levels())
334+
transatlanticBarrierLevel.push_back(boost::lexical_cast<std::string>(l.value()));
335+
} else {
336+
QL_REQUIRE(transatlanticBarrierType.size() == underlyings_.size(),
337+
"Transatlantic Barrier must have exactly 1 level for each underlying, got "
338+
<< transatlanticBarrier_.size());
339+
for (auto const& n : transatlanticBarrier_) {
340+
QL_REQUIRE(n.levels().size() == 1, "Number of level in each barrier block in transatlantic barriers "
341+
"must be exactly 1 if more than 1 barrier blocks are provided, got "
342+
<< transatlanticBarrier_.size());
343+
transatlanticBarrierLevel.push_back(boost::lexical_cast<std::string>(n.levels()[0].value()));
344+
}
345+
}
346+
if (transatlanticBarrier_.size() > 1) {
347+
for (Size i = 1; i < transatlanticBarrier_.size(); i++) {
348+
QL_REQUIRE(transatlanticBarrier_[i].rebateCurrency().empty() ||
349+
transatlanticBarrier_[i].rebateCurrency() == transatlanticBarrier_[0].rebateCurrency(),
350+
"Rebate currency for transatlantic barriers must be identical or only given in the first "
351+
"transatlantic barrier.");
352+
}
353+
}
354+
transatlanticBarrierRebate = boost::lexical_cast<std::string>(transatlanticBarrier_[0].rebate());
355+
if (!transatlanticBarrier_[0].rebateCurrency().empty())
356+
transatlanticBarrierRebateCurrency = transatlanticBarrier_[0].rebateCurrency();
325357
}
326358
numbers_.emplace_back("Number", "TransatlanticBarrierType", transatlanticBarrierType);
327359
numbers_.emplace_back("Number", "TransatlanticBarrierLevel", transatlanticBarrierLevel);
@@ -331,7 +363,14 @@ void GenericBarrierOption::build(const boost::shared_ptr<EngineFactory>& factory
331363
auto positionType = parsePositionType(optionData_.longShort());
332364
numbers_.emplace_back("Number", "LongShort", positionType == Position::Long ? "1" : "-1");
333365

334-
numbers_.emplace_back("Number", "PutCall", parseOptionType(optionData_.callPut()) == Option::Call ? "1.0" : "-1.0");
366+
if (optionData_.callPut().empty()) {
367+
QL_REQUIRE(optionData_.payoffType() == "CashOrNothing" || optionData_.payoffType() == "AssetOrNothing",
368+
"Payoff type must be vanilla if option type is not givien.");
369+
numbers_.emplace_back("Number", "PutCall", "1.0");
370+
} else {
371+
numbers_.emplace_back("Number", "PutCall",
372+
parseOptionType(optionData_.callPut()) == Option::Call ? "1.0" : "-1.0");
373+
}
335374
numbers_.emplace_back("Number", "Quantity", quantity_.empty() ? "0.0" : quantity_);
336375
if (!strike_.empty())
337376
numbers_.emplace_back("Number", "Strike", strike_);
@@ -553,9 +592,11 @@ void GenericBarrierOption::fromXML(XMLNode* node) {
553592

554593
auto transatlanticBarrierNode = XMLUtils::getChildNode(dataNode, "TransatlanticBarrier");
555594
if (transatlanticBarrierNode) {
556-
auto b = XMLUtils::getChildNode(transatlanticBarrierNode, "BarrierData");
557-
if (b)
558-
transatlanticBarrier_.fromXML(b);
595+
auto b = XMLUtils::getChildrenNodes(transatlanticBarrierNode, "BarrierData");
596+
for (auto const& n : b) {
597+
transatlanticBarrier_.push_back(BarrierData());
598+
transatlanticBarrier_.back().fromXML(n);
599+
}
559600
}
560601

561602
payCurrency_ = XMLUtils::getChildValue(dataNode, "PayCurrency", true);
@@ -597,9 +638,11 @@ XMLNode* GenericBarrierOption::toXML(XMLDocument& doc) {
597638
XMLUtils::addChild(doc, barriers, "KikoType", kikoType_);
598639
XMLUtils::appendNode(dataNode, barriers);
599640

600-
if (!transatlanticBarrier_.type().empty()) {
641+
if (!transatlanticBarrier_[0].type().empty()) {
601642
XMLNode* transatlanticBarrierNode = doc.allocNode("TransatlanticBarrier");
602-
XMLUtils::appendNode(transatlanticBarrierNode, transatlanticBarrier_.toXML(doc));
643+
for (auto& n : transatlanticBarrier_) {
644+
XMLUtils::appendNode(transatlanticBarrierNode, n.toXML(doc));
645+
}
603646
XMLUtils::appendNode(dataNode, transatlanticBarrierNode);
604647
}
605648

OREData/ored/portfolio/genericbarrieroption.hpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class GenericBarrierOption : public ScriptedTrade {
3838
explicit GenericBarrierOption(const std::string& tradeType = "GenericBarrierOption") : ScriptedTrade(tradeType) {}
3939
GenericBarrierOption(std::vector<boost::shared_ptr<Underlying>> underlyings, const OptionData& optionData,
4040
const std::vector<BarrierData>& barriers, const ScheduleData& barrierMonitoringDates,
41-
const BarrierData& transatlanticBarrier, const std::string& payCurrency,
41+
const std::vector<BarrierData>& transatlanticBarrier, const std::string& payCurrency,
4242
const std::string& settlementDate, const std::string& quantity, const std::string& strike,
4343
const std::string& amount, const std::string& kikoType)
4444
: underlyings_(underlyings), optionData_(optionData), barriers_(barriers),
@@ -54,10 +54,11 @@ class GenericBarrierOption : public ScriptedTrade {
5454
const std::string& settlementDate, const std::string& quantity, const std::string& strike,
5555
const std::string& amount, const std::string& kikoType)
5656
: optionData_(optionData), barriers_(barriers),
57-
barrierMonitoringDates_(barrierMonitoringDates), transatlanticBarrier_(transatlanticBarrier),
57+
barrierMonitoringDates_(barrierMonitoringDates),
5858
payCurrency_(payCurrency), settlementDate_(settlementDate), quantity_(quantity), strike_(strike),
5959
amount_(amount), kikoType_(kikoType) {
60-
underlyings_.push_back(underlying);
60+
underlyings_.push_back(underlying);
61+
transatlanticBarrier_.push_back(transatlanticBarrier);
6162
initIndices();
6263
}
6364
void build(const boost::shared_ptr<EngineFactory>&) override;
@@ -81,8 +82,8 @@ class GenericBarrierOption : public ScriptedTrade {
8182
OptionData optionData_;
8283
std::vector<BarrierData> barriers_;
8384
ScheduleData barrierMonitoringDates_;
85+
std::vector<BarrierData> transatlanticBarrier_;
8486
std::string barrierMonitoringStartDate_, barrierMonitoringEndDate_;
85-
BarrierData transatlanticBarrier_;
8687
std::string payCurrency_, settlementDate_, quantity_, strike_, amount_, kikoType_;
8788
std::string settlementLag_, settlementCalendar_, settlementConvention_;
8889
};

xsd/instruments.xsd

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4467,9 +4467,9 @@
44674467
</xs:element>
44684468
<xs:element name="TransatlanticBarrier" minOccurs="0">
44694469
<xs:complexType>
4470-
<xs:all>
4471-
<xs:element type="barrierData" name="BarrierData"/>
4472-
</xs:all>
4470+
<xs:sequence>
4471+
<xs:element type="barrierData" name="BarrierData" minOccurs="0" maxOccurs="unbounded"/>
4472+
</xs:sequence>
44734473
</xs:complexType>
44744474
</xs:element>
44754475
</xs:all>

0 commit comments

Comments
 (0)