Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
commodityoptionstrip.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2019 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
19#include <algorithm>
34
35using namespace ore::data;
36using namespace QuantExt;
37using namespace QuantLib;
38using std::max;
39using std::string;
40using std::transform;
41using std::vector;
42
43namespace {
44
45vector<string> strPositions(const vector<Position::Type>& positions) {
46 vector<string> res(positions.size());
47 transform(positions.begin(), positions.end(), res.begin(), [](const Position::Type& pt) { return to_string(pt); });
48 return res;
49}
50
51struct TempOptionData {
52 string type;
53 Position::Type position;
54 Real strike;
55 string id;
56};
57
58} // namespace
59
60namespace ore {
61namespace data {
62
63CommodityOptionStrip::CommodityOptionStrip(const Envelope& envelope, const LegData& legData,
64 const vector<Position::Type>& callPositions, const vector<Real>& callStrikes,
65 const vector<Position::Type>& putPositions, const vector<Real>& putStrikes,
66 Real premium, const string& premiumCurrency, const Date& premiumPayDate,
67 const string& style, const string& settlement,
68 const BarrierData& callBarrierData, const BarrierData& putBarrierData,
69 const string& fxIndex, const bool isDigital, Real payoffPerUnit)
70 : Trade("CommodityOptionStrip", envelope), legData_(legData), callPositions_(callPositions),
71 callStrikes_(callStrikes), putPositions_(putPositions), putStrikes_(putStrikes),
72 style_(style),
73 settlement_(settlement),
74 callBarrierData_(callBarrierData), putBarrierData_(putBarrierData), fxIndex_(fxIndex), isDigital_(isDigital),
75 unaryPayoff_(payoffPerUnit) {
76 if (!QuantLib::close_enough(premium, 0.0)) {
77 QL_REQUIRE(premiumPayDate != Date(), "The premium is non-zero so its payment date needs to be provided");
78 QL_REQUIRE(!premiumCurrency.empty(), "The premium is non-zero so its currency needs to be provided");
79 premiumData_ = PremiumData(premium, premiumCurrency, premiumPayDate);
80 }
81}
82
83
84void CommodityOptionStrip::build(const QuantLib::ext::shared_ptr<EngineFactory>& engineFactory) {
85
86 reset();
87
88 DLOG("CommodityOptionStrip::build() called for trade " << id());
89
90 // ISDA taxonomy, assuming Commodity follows the Equity template
91 additionalData_["isdaAssetClass"] = std::string("Commodity");
92 additionalData_["isdaBaseProduct"] = std::string("Option");
93 additionalData_["isdaSubProduct"] = std::string("Price Return Basic Performance");
94 // skip the transaction level mapping for now
95 additionalData_["isdaTransaction"] = std::string();
96
98
99 // Check that the leg data is of type CommodityFloating
100 auto conLegData = legData_.concreteLegData();
101 commLegData_ = QuantLib::ext::dynamic_pointer_cast<CommodityFloatingLegData>(conLegData);
102 QL_REQUIRE(commLegData_, "CommodityOptionStrip leg data should be of type CommodityFloating");
103 if(!commLegData_->fxIndex().empty())
104 fxIndex_= commLegData_->fxIndex();
105 // Build the commodity floating leg data
106 auto legBuilder = engineFactory->legBuilder(legData_.legType());
107 auto cflb = QuantLib::ext::dynamic_pointer_cast<CommodityFloatingLegBuilder>(legBuilder);
108 QL_REQUIRE(cflb, "Expected a CommodityFloatingLegBuilder for leg type " << legData_.legType());
109 Leg leg =
110 cflb->buildLeg(legData_, engineFactory, requiredFixings_, engineFactory->configuration(MarketContext::pricing));
111
112 // Perform checks
113 check(leg.size());
114
115 // We update the notional_ in either buildAPOs or buildStandardOptions below.
116 notional_ = Null<Real>();
117
118 // Build the strip of option trades
120
121 if (commLegData_->isAveraged() && !cflb->allAveraging()) {
122 buildAPOs(leg, engineFactory);
123 } else {
124 buildStandardOptions(leg, engineFactory);
125 }
126
127 // Add leg to legs_ so that fixings method can work.
128 legs_.push_back(leg);
129 legPayers_.push_back(false);
130 legCurrencies_.push_back(npvCurrency_);
131}
132
133std::map<ore::data::AssetClass, std::set<std::string>>
134CommodityOptionStrip::underlyingIndices(const QuantLib::ext::shared_ptr<ReferenceDataManager>& referenceDataManager) const {
135 std::map<ore::data::AssetClass, std::set<std::string>> result;
136
137 set<string> indices = legData_.indices();
138 for (auto ind : indices) {
139 QuantLib::ext::shared_ptr<Index> index = parseIndex(ind);
140 // only handle commodity
141 if (auto ci = QuantLib::ext::dynamic_pointer_cast<QuantExt::CommodityIndex>(index)) {
142 result[ore::data::AssetClass::COM].insert(ci->name());
143 }
144 }
145 return result;
146}
147
149
150 Trade::fromXML(node);
151
152 XMLNode* stripNode = XMLUtils::getChildNode(node, "CommodityOptionStripData");
153 QL_REQUIRE(stripNode, "No CommodityOptionStripData Node");
154
155 legData_.fromXML(XMLUtils::getChildNode(stripNode, "LegData"));
156
157 if (XMLNode* n = XMLUtils::getChildNode(stripNode, "Calls")) {
158 vector<string> ls = XMLUtils::getChildrenValues(n, "LongShorts", "LongShort", false);
159 callPositions_ = parseVectorOfValues<Position::Type>(ls, &parsePositionType);
160 callStrikes_ = XMLUtils::getChildrenValuesAsDoubles(n, "Strikes", "Strike", false);
161 if (XMLNode* n2 = XMLUtils::getChildNode(n, "BarrierData")) {
163 }
164 }
165
166 if (XMLNode* n = XMLUtils::getChildNode(stripNode, "Puts")) {
167 vector<string> ls = XMLUtils::getChildrenValues(n, "LongShorts", "LongShort", false);
168 putPositions_ = parseVectorOfValues<Position::Type>(ls, &parsePositionType);
169 putStrikes_ = XMLUtils::getChildrenValuesAsDoubles(n, "Strikes", "Strike", false);
170 if (XMLNode* n2 = XMLUtils::getChildNode(n, "BarrierData")) {
172 }
173 }
174 premiumData_.fromXML(stripNode);
175 style_ = "";
176 if (XMLNode* n = XMLUtils::getChildNode(stripNode, "Style"))
178
179 settlement_ = "";
180 if (XMLNode* n = XMLUtils::getChildNode(stripNode, "Settlement"))
182
183 isDigital_ = false;
184 if (XMLNode* n = XMLUtils::getChildNode(stripNode, "IsDigital") )
186 if (isDigital_) {
187 XMLNode* n = XMLUtils::getChildNode(stripNode, "PayoffPerUnit");
188 QL_REQUIRE(n, "A strip of commodity digital options requires PayoffPerUnit node");
190 }
191}
192
194
195 XMLNode* node = Trade::toXML(doc);
196
197 XMLNode* stripNode = doc.allocNode("CommodityOptionStripData");
198 XMLUtils::appendNode(node, stripNode);
199
200 XMLUtils::appendNode(stripNode, legData_.toXML(doc));
201
202 if (!callStrikes_.empty()) {
203 XMLNode* callsNode = doc.allocNode("Calls");
204 XMLUtils::addChildren(doc, callsNode, "LongShorts", "LongShort", strPositions(callPositions_));
205 XMLUtils::addChildren(doc, callsNode, "Strikes", "Strike", callStrikes_);
208 }
209 XMLUtils::appendNode(stripNode, callsNode);
210 }
211
212 if (!putStrikes_.empty()) {
213 XMLNode* putsNode = doc.allocNode("Puts");
214 XMLUtils::addChildren(doc, putsNode, "LongShorts", "LongShort", strPositions(putPositions_));
215 XMLUtils::addChildren(doc, putsNode, "Strikes", "Strike", putStrikes_);
218 }
219 XMLUtils::appendNode(stripNode, putsNode);
220 }
221
222 // These are all optional, really they should be grouped here
223 if (!premiumData_.premiumData().empty())
224 XMLUtils::appendNode(stripNode, premiumData_.toXML(doc));
225
226 if (!style_.empty())
227 XMLUtils::addChild(doc, stripNode, "Style", style_);
228
229 if (!settlement_.empty())
230 XMLUtils::addChild(doc, stripNode, "Settlement", settlement_);
231
232 if (isDigital_){
233 XMLUtils::addChild(doc, stripNode, "IsDigital", isDigital_);
234 XMLUtils::addChild(doc, stripNode, "PayoffPerUnit", unaryPayoff_);
235 }
236 return node;
237}
238
239void CommodityOptionStrip::buildAPOs(const Leg& leg, const QuantLib::ext::shared_ptr<EngineFactory>& engineFactory) {
240
241 // If style is set and not European, log a warning.
242 if (!style_.empty() && style_ != "European") {
243 WLOG("Style should be European when the commodity option strip is a strip of APOs. Ignoring style "
244 << style_ << " and proceeding as if European.");
245 }
246
247 // If settlement is set and not Cash, log a warning. Physical settlement for APOs does not make sense.
248 if (!settlement_.empty() && settlement_ != "Cash") {
249 WLOG("Settlement should be Cash when the commodity option strip is a strip of APOs. Ignoring settlement "
250 << settlement_ << " and proceeding as if Cash.");
251 }
252
253
254 // Populate these with the call/put options requested in each period
255 vector<QuantLib::ext::shared_ptr<Instrument>> additionalInstruments;
256 vector<Real> additionalMultipliers;
257
258 for (Size i = 0; i < leg.size(); i++) {
259 auto cf = QuantLib::ext::dynamic_pointer_cast<CommodityIndexedAverageCashFlow>(leg[i]);
260 QL_REQUIRE(cf, "Expected a CommodityIndexedAverageCashFlow while building APO");
261
262 // Populate call and/or put data at this leg period
263 vector<TempOptionData> tempData;
264 Date exerciseDate = cf->indices().rbegin()->first;
265 vector<string> strExerciseDate = {to_string(exerciseDate)};
266 maturity_ = maturity_ == Date() ? cf->date() : max(maturity_, cf->date());
267 string stemId = id() + "_" + strExerciseDate[0] + "_";
268 if (!callStrikes_.empty()) {
269 Position::Type position = callPositions_.size() == 1 ? callPositions_[0] : callPositions_[i];
270 Real strike = callStrikes_.size() == 1 ? callStrikes_[0] : callStrikes_[i];
271 string id = stemId + "call";
272 tempData.push_back({"Call", position, strike, id});
273 }
274 if (!putStrikes_.empty()) {
275 Position::Type position = putPositions_.size() == 1 ? putPositions_[0] : putPositions_[i];
276 Real strike = putStrikes_.size() == 1 ? putStrikes_[0] : putStrikes_[i];
277 string id = stemId + "put";
278 tempData.push_back({"Put", position, strike, id});
279 }
280
281 // Each CommodityAveragePriceOption is set up to go through the commodity floating leg builder which for
282 // averaging cashflows includes the start date on the first coupon in the leg and includes the end date on
283 // the last coupon in the leg. Only one coupon in each of the cases here so need to do this manually here.
284 Date start = cf->indices().begin()->first;
285
286 // Build a commodity APO for the call and/or put in this period
287
288 for (const auto& tempDatum : tempData) {
289 QuantLib::ext::shared_ptr<Trade> commOption;
290 OptionData optionData(to_string(tempDatum.position), tempDatum.type, "European", true, strExerciseDate);
291 if (!isDigital()) {
292 commOption = QuantLib::ext::make_shared<CommodityAveragePriceOption>(
293 envelope(), optionData, cf->quantity(), tempDatum.strike, legData_.currency(), commLegData_->name(),
294 commLegData_->priceType(), to_string(start), to_string(cf->endDate()), legData_.paymentCalendar(),
296 to_string(cf->date()), cf->gearing(), cf->spread(), cf->quantityFrequency(),
298 commLegData_->deliveryRollDays(), true,
299 tempDatum.type == "Call" ? callBarrierData_ : putBarrierData_, fxIndex_);
300 } else {
301 auto undCcy = cf->index()->priceCurve()->currency();
302 QL_REQUIRE(undCcy.code() == legData_.currency(),
303 "Strips of commodity digital options do not support intra-currency trades yet.");
304 commOption = QuantLib::ext::make_shared<CommodityDigitalAveragePriceOption>(
305 envelope(), optionData, tempDatum.strike, cf->quantity() * payoffPerUnit(),
306 legData_.currency(), commLegData_->name(), commLegData_->priceType(), to_string(start),
308 legData_.paymentConvention(), commLegData_->pricingCalendar(), to_string(cf->date()),
309 cf->gearing(), cf->spread(), cf->quantityFrequency(),
311 commLegData_->deliveryRollDays(), true,
312 tempDatum.type == "Call" ? callBarrierData_ : putBarrierData_, fxIndex_);
313 }
314 commOption->id() = tempDatum.id;
315 commOption->build(engineFactory);
316 QuantLib::ext::shared_ptr<InstrumentWrapper> instWrapper = commOption->instrument();
317 setSensitivityTemplate(commOption->sensitivityTemplate());
318 additionalInstruments.push_back(instWrapper->qlInstrument());
319 additionalMultipliers.push_back(instWrapper->multiplier());
320
321 // Update the notional_ each time. It will hold the notional of the last instrument which is arbitrary
322 // but reasonable as this is the instrument that we use as the main instrument below.
323 notional_ = commOption->notional();
324
325 if (!fxIndex_.empty()) { // if fx is applied, the notional is still quoted in the domestic ccy
326 auto underlyingCcy = QuantLib::ext::dynamic_pointer_cast<CommodityIndexedAverageCashFlow>(leg[0])->index()->priceCurve()->currency();
327 notionalCurrency_ = underlyingCcy.code();
328 }
329 }
330 }
331
332 QL_REQUIRE(additionalInstruments.size() > 0, "Expected commodity APO strip to have at least one instrument");
333
334 // Take the last option and multiplier as the main instrument
335 auto qlInst = additionalInstruments.back();
336 auto qlInstMult = additionalMultipliers.back();
337 additionalInstruments.pop_back();
338 additionalMultipliers.pop_back();
339
340 // Possibly add a premium to the additional instruments and multipliers
341 // We expect here that the fee already has the correct sign
342
343 maturity_ = std::max(maturity_, addPremiums(additionalInstruments, additionalMultipliers, qlInstMult, premiumData_,
344 1.0, parseCurrency(legData_.currency()), engineFactory, ""));
345
346 // Create the Trade's instrument wrapper
348 QuantLib::ext::make_shared<VanillaInstrument>(qlInst, qlInstMult, additionalInstruments, additionalMultipliers);
349}
350
351void CommodityOptionStrip::buildStandardOptions(const Leg& leg, const QuantLib::ext::shared_ptr<EngineFactory>& engineFactory) {
352
353 QL_REQUIRE(!callBarrierData_.initialized(), "Commodity APO: standard option does not support barriers");
354 QL_REQUIRE(!putBarrierData_.initialized(), "Commodity APO: standard option does not support barriers");
355
356 // Set style and settlement
357 string style = style_.empty() ? "European" : style_;
358 string settlement = settlement_.empty() ? "Cash" : settlement_;
359
360 // Set automatic exercise to true for cash settlement.
361 bool automaticExercise = settlement == "Cash";
362
363 // Populate these with the call/put options requested in each period
364 vector<QuantLib::ext::shared_ptr<Instrument>> additionalInstruments;
365 vector<Real> additionalMultipliers;
366
367 for (Size i = 0; i < leg.size(); i++) {
368
369 auto cf = QuantLib::ext::dynamic_pointer_cast<CommodityIndexedCashFlow>(leg[i]);
370 QL_REQUIRE(cf, "Expected a CommodityIndexedCashFlow while building standard option");
371
372 // Exercise date is the pricing date.
373 Date exerciseDate = cf->pricingDate();
374 vector<string> strExerciseDate = {to_string(exerciseDate)};
375
376 // If cash settlement and European, create the OptionPaymentData for the OptionData block below.
377 boost::optional<OptionPaymentData> paymentData = boost::none;
378 if (settlement == "Cash" && style == "European") {
379
380 Date paymentDate = cf->date();
381 vector<string> strPaymentDate = {to_string(paymentDate)};
382 paymentData = OptionPaymentData(strPaymentDate);
383
384 // Update the maturity - cash-settled strip, it is the maximum payment date.
385 maturity_ = maturity_ == Date() ? paymentDate : max(maturity_, paymentDate);
386
387 } else {
388 // Update the maturity - physically-settled strip or American, it is the maximum
389 // exercise date (no deferred delivery for Physical implemented yet).
390 maturity_ = maturity_ == Date() ? exerciseDate : max(maturity_, exerciseDate);
391 }
392
393 // Populate call and/or put data at this leg period
394 vector<TempOptionData> tempData;
395 string stemId = id() + "_" + strExerciseDate[0] + "_";
396 if (!callStrikes_.empty()) {
397 Position::Type position = callPositions_.size() == 1 ? callPositions_[0] : callPositions_[i];
398 Real strike = callStrikes_.size() == 1 ? callStrikes_[0] : callStrikes_[i];
399 string id = stemId + "call";
400 tempData.push_back({"Call", position, strike, id});
401 }
402 if (!putStrikes_.empty()) {
403 Position::Type position = putPositions_.size() == 1 ? putPositions_[0] : putPositions_[i];
404 Real strike = putStrikes_.size() == 1 ? putStrikes_[0] : putStrikes_[i];
405 string id = stemId + "put";
406 tempData.push_back({"Put", position, strike, id});
407 }
408
409 // Build a commodity option for the call and/or put in this period
410 for (const auto& tempDatum : tempData) {
411
412 // Check that gearing, strike and spread make sense
413 QL_REQUIRE(cf->gearing() > 0.0, "Gearing (" << cf->gearing() << ") should be positive.");
414 QL_REQUIRE(cf->spread() < tempDatum.strike || QuantLib::close_enough(cf->spread(), tempDatum.strike),
415 "Spread (" << cf->spread() << ") should be less than strike (" << tempDatum.strike << ").");
416
417 TradeStrike effectiveStrike(TradeStrike::Type::Price, (tempDatum.strike - cf->spread()) / cf->gearing());
418 Real effectiveQuantity = cf->gearing() * cf->periodQuantity();
419
420 OptionData optionData(to_string(tempDatum.position), tempDatum.type, style, false, strExerciseDate,
421 settlement, "", PremiumData(), {}, {}, "", "", "", {}, {}, "", "", "", "", "",
422 automaticExercise, boost::none, paymentData);
423
424
425 QuantLib::ext::shared_ptr<Trade> commOption;
426 if(!isDigital()) {
427 commOption = QuantLib::ext::make_shared<CommodityOption>(
428 envelope(), optionData, commLegData_->name(), legData_.currency(), effectiveQuantity,
429 effectiveStrike, cf->useFuturePrice(), cf->index()->expiryDate());
430 } else {
431 auto undCcy = cf->index()->priceCurve()->currency();
432 QL_REQUIRE(undCcy.code() == legData_.currency(), "Strips of commodity digital options do not support intra-currency trades yet.");
433 commOption = QuantLib::ext::make_shared<CommodityDigitalOption>(
434 envelope(), optionData, commLegData_->name(), legData_.currency(), effectiveStrike.value(), effectiveQuantity*payoffPerUnit(),
435 cf->useFuturePrice(), cf->index()->expiryDate());
436 }
437 commOption->id() = tempDatum.id;
438 commOption->build(engineFactory);
439 QuantLib::ext::shared_ptr<InstrumentWrapper> instWrapper = commOption->instrument();
440 setSensitivityTemplate(commOption->sensitivityTemplate());
441 additionalInstruments.push_back(instWrapper->qlInstrument());
442 additionalMultipliers.push_back(instWrapper->multiplier());
443
444 // Update the notional_ each time. It will hold the notional of the last instrument which is arbitrary
445 // but reasonable as this is the instrument that we use as the main instrument below.
446 notional_ = commOption->notional();
447 }
448 }
449
450 QL_REQUIRE(additionalInstruments.size() > 0, "Expected commodity option strip to have at least one instrument");
451
452 // Take the last option and multiplier as the main instrument
453 auto qlInst = additionalInstruments.back();
454 auto qlInstMult = additionalMultipliers.back();
455 additionalInstruments.pop_back();
456 additionalMultipliers.pop_back();
457
458 // Possibly add a premium to the additional instruments and multipliers
459 // We expect here that the fee already has the correct sign
460 maturity_ = std::max(maturity_, addPremiums(additionalInstruments, additionalMultipliers, qlInstMult, premiumData_,
461 1.0, parseCurrency(legData_.currency()), engineFactory, ""));
462 DLOG("Option premium added for commodity option strip " << id());
463
464 // Create the Trade's instrument wrapper
466 QuantLib::ext::make_shared<VanillaInstrument>(qlInst, qlInstMult, additionalInstruments, additionalMultipliers);
467}
468
469void CommodityOptionStrip::check(Size numberPeriods) const {
470
471 QL_REQUIRE(numberPeriods > 0, "Expected at least one period in the commodity option strip");
472 QL_REQUIRE(!callStrikes_.empty() || !putStrikes_.empty(), "Need at least one call or put to build a strip");
473
474 if (!callStrikes_.empty()) {
475 QL_REQUIRE(callStrikes_.size() == 1 || callStrikes_.size() == numberPeriods,
476 "The number of "
477 << "call strikes (" << callStrikes_.size() << ") should be 1 or equal to "
478 << "the number of periods in the strip (" << numberPeriods << ")");
479 QL_REQUIRE(callPositions_.size() == 1 || callPositions_.size() == numberPeriods,
480 "The number of position "
481 << "flags provided with the call strikes (" << callPositions_.size()
482 << ") should be 1 or equal to "
483 << "the number of periods in the strip (" << numberPeriods << ")");
484 }
485
486 if (!putStrikes_.empty()) {
487 QL_REQUIRE(putStrikes_.size() == 1 || putStrikes_.size() == numberPeriods,
488 "The number of "
489 << "put strikes (" << putStrikes_.size() << ") should be 1 or equal to "
490 << "the number of periods in the strip (" << numberPeriods << ")");
491 QL_REQUIRE(putPositions_.size() == 1 || putPositions_.size() == numberPeriods,
492 "The number of position "
493 << "flags provided with the put strikes (" << putPositions_.size()
494 << ") should be 1 or equal to "
495 << "the number of periods in the strip (" << numberPeriods << ")");
496 }
497}
498
499} // namespace data
500} // namespace ore
Engine builder for commodity average price options.
Serializable obejct holding barrier data.
Definition: barrierdata.hpp:34
virtual void fromXML(ore::data::XMLNode *node) override
Definition: barrierdata.cpp:25
virtual ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
Definition: barrierdata.cpp:49
bool initialized() const
Definition: barrierdata.hpp:52
const std::string & settlement() const
std::vector< QuantLib::Real > putStrikes_
virtual void fromXML(ore::data::XMLNode *node) override
void buildAPOs(const QuantLib::Leg &leg, const QuantLib::ext::shared_ptr< ore::data::EngineFactory > &engineFactory)
Build an average price option strip.
std::map< ore::data::AssetClass, std::set< std::string > > underlyingIndices(const QuantLib::ext::shared_ptr< ReferenceDataManager > &referenceDataManager=nullptr) const override
Add underlying Commodity names.
void build(const QuantLib::ext::shared_ptr< ore::data::EngineFactory > &engineFactory) override
Implement the build method.
QuantLib::ext::shared_ptr< CommodityFloatingLegData > commLegData_
std::vector< QuantLib::Position::Type > callPositions_
virtual ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
std::vector< QuantLib::Position::Type > putPositions_
std::vector< QuantLib::Real > callStrikes_
const std::string & style() const
void buildStandardOptions(const QuantLib::Leg &leg, const QuantLib::ext::shared_ptr< ore::data::EngineFactory > &engineFactory)
Build a standard option strip.
void check(QuantLib::Size numberPeriods) const
Perform checks before building.
Serializable object holding generic trade data, reporting dimensions.
Definition: envelope.hpp:51
Serializable object holding leg data.
Definition: legdata.hpp:844
const string & paymentConvention() const
Definition: legdata.hpp:878
const string & currency() const
Definition: legdata.hpp:873
virtual void fromXML(XMLNode *node) override
Definition: legdata.cpp:759
virtual XMLNode * toXML(XMLDocument &doc) const override
Definition: legdata.cpp:856
const string & legType() const
Definition: legdata.hpp:890
const std::string & paymentCalendar() const
Definition: legdata.hpp:889
const std::set< std::string > & indices() const
Definition: legdata.hpp:892
const string & paymentLag() const
Definition: legdata.hpp:886
QuantLib::ext::shared_ptr< LegAdditionalData > concreteLegData() const
Definition: legdata.hpp:891
Serializable object holding option data.
Definition: optiondata.hpp:42
Serializable object holding premium data.
Definition: premiumdata.hpp:37
const std::vector< PremiumDatum > & premiumData() const
Definition: premiumdata.hpp:57
virtual void fromXML(XMLNode *node) override
Definition: premiumdata.cpp:37
virtual XMLNode * toXML(XMLDocument &doc) const override
Definition: premiumdata.cpp:76
Trade base class.
Definition: trade.hpp:55
string npvCurrency_
Definition: trade.hpp:201
std::vector< bool > legPayers_
Definition: trade.hpp:200
std::vector< string > legCurrencies_
Definition: trade.hpp:199
std::vector< QuantLib::Leg > legs_
Definition: trade.hpp:198
QuantLib::Real notional_
Definition: trade.hpp:202
virtual void fromXML(XMLNode *node) override
Definition: trade.cpp:34
Date addPremiums(std::vector< QuantLib::ext::shared_ptr< Instrument > > &instruments, std::vector< Real > &multipliers, const Real tradeMultiplier, const PremiumData &premiumData, const Real premiumMultiplier, const Currency &tradeCurrency, const QuantLib::ext::shared_ptr< EngineFactory > &factory, const string &configuration)
Definition: trade.cpp:58
void setSensitivityTemplate(const EngineBuilder &builder)
Definition: trade.cpp:295
virtual XMLNode * toXML(XMLDocument &doc) const override
Definition: trade.cpp:46
string & id()
Set the trade id.
Definition: trade.hpp:118
RequiredFixings requiredFixings_
Definition: trade.hpp:223
const Envelope & envelope() const
Definition: trade.hpp:135
QuantLib::ext::shared_ptr< InstrumentWrapper > instrument_
Definition: trade.hpp:197
void reset()
Reset trade, clear all base class data. This does not reset accumulated timings for this trade.
Definition: trade.cpp:130
string notionalCurrency_
Definition: trade.hpp:203
std::map< std::string, boost::any > additionalData_
Definition: trade.hpp:224
QuantLib::Real value() const
Small XML Document wrapper class.
Definition: xmlutils.hpp:65
XMLNode * allocNode(const string &nodeName)
util functions that wrap rapidxml
Definition: xmlutils.cpp:132
static vector< Real > getChildrenValuesAsDoubles(XMLNode *node, const string &names, const string &name, bool mandatory=false)
Definition: xmlutils.cpp:319
static void addChildren(XMLDocument &doc, XMLNode *n, const string &names, const string &name, const vector< T > &values)
Definition: xmlutils.cpp:502
static XMLNode * getChildNode(XMLNode *n, const string &name="")
Definition: xmlutils.cpp:387
static string getNodeValue(XMLNode *node)
Get a node's value.
Definition: xmlutils.cpp:489
static vector< string > getChildrenValues(XMLNode *node, const string &names, const string &name, bool mandatory=false)
Definition: xmlutils.cpp:306
static XMLNode * addChild(XMLDocument &doc, XMLNode *n, const string &name)
Definition: xmlutils.cpp:181
static void appendNode(XMLNode *parent, XMLNode *child)
Definition: xmlutils.cpp:406
Commodity Average Price Option data model and serialization.
Commodity digital option representation as call spread.
Commodity fixed and floating leg builders.
Commodity option representation.
Commodity option strip data model and serialization.
Pricing Engine Factory.
Logic for calculating required fixing dates on legs.
Currency parseCurrency(const string &s)
Convert text to QuantLib::Currency.
Definition: parsers.cpp:290
Position::Type parsePositionType(const std::string &s)
Convert text to QuantLib::Position::Type.
Definition: parsers.cpp:404
bool parseBool(const string &s)
Convert text to bool.
Definition: parsers.cpp:144
QuantLib::ext::shared_ptr< Index > parseIndex(const string &s)
Convert std::string to QuantLib::Index.
Real parseReal(const string &s)
Convert text to Real.
Definition: parsers.cpp:112
Classes and functions for log message handling.
@ data
Definition: log.hpp:77
#define DLOG(text)
Logging Macro (Level = Debug)
Definition: log.hpp:554
#define WLOG(text)
Logging Macro (Level = Warning)
Definition: log.hpp:550
RandomVariable max(RandomVariable x, const RandomVariable &y)
std::string to_string(const LocationInfo &l)
Definition: ast.cpp:28
Serializable Credit Default Swap.
Definition: namespaces.docs:23
Map text representations to QuantLib/QuantExt types.
string conversion utilities