43 {
44
46
47 LOG(
"CommoditySwap::build() called for trade " <<
id());
48
49
52 additionalData_[
"isdaSubProduct"] = string(
"Price Return Basic Performance");
53
55
57
58
60
61
64
65 const QuantLib::ext::shared_ptr<Market> market = engineFactory->market();
66 QuantLib::ext::shared_ptr<EngineBuilder> builder = engineFactory->builder("CommoditySwap");
67 QuantLib::ext::shared_ptr<CommoditySwapEngineBuilder> engineBuilder =
68 QuantLib::ext::dynamic_pointer_cast<CommoditySwapEngineBuilder>(builder);
70
71
72
73
74
75
76
77
78 map<string, Leg> floatingLegs;
79 vector<Size> legsIdx;
80 for (Size t = 0; t <
legData_.size(); t++) {
81 const auto& legDatum =
legData_.at(t);
82
83 const string& type = legDatum.legType();
84 if (type == "CommodityFixed")
85 continue;
86
87
88 buildLeg(engineFactory, legDatum, configuration);
89 legsIdx.push_back(t);
90
91
92 if (auto cfld = QuantLib::ext::dynamic_pointer_cast<CommodityFloatingLegData>(legDatum.concreteLegData())) {
93 floatingLegs[cfld->tag()] =
legs_.back();
94 }
95 }
96
97
98 for (Size t = 0; t <
legData_.size(); t++) {
99 const auto& legDatum =
legData_.at(t);
100
101
102 auto effLegDatum = legDatum;
103
104 const string& type = effLegDatum.legType();
105 if (type != "CommodityFixed")
106 continue;
107
108
109 auto cfld = QuantLib::ext::dynamic_pointer_cast<CommodityFixedLegData>(effLegDatum.concreteLegData());
110 QL_REQUIRE(cfld, "CommodityFixed leg should have valid CommodityFixedLegData");
111 if (cfld->quantities().empty()) {
112
113 auto it = floatingLegs.find(cfld->tag());
114 QL_REQUIRE(it != floatingLegs.end(), "Did not find a commodity floating leg corresponding to the" <<
115 " fixed leg with tag '" << cfld->tag() << "' from which to take the quantities.");
116
117 const Leg& leg = it->second;
118 vector<Real> quantities;
119 quantities.reserve(leg.size());
120 for (const auto& cf : leg) {
121
123 if (auto cicf = QuantLib::ext::dynamic_pointer_cast<CommodityIndexedCashFlow>(ucf)) {
124 quantities.push_back(cicf->periodQuantity());
125 } else if (auto ciacf = QuantLib::ext::dynamic_pointer_cast<CommodityIndexedAverageCashFlow>(ucf)) {
126 quantities.push_back(ciacf->periodQuantity());
127 } else {
128 QL_FAIL("Expected a commodity indexed cashflow while building commodity fixed" <<
129 " leg quantities for trade " << id() << ".");
130 }
131 }
132
133 cfld->setQuantities(quantities);
134 }
135
136 if (effLegDatum.paymentDates().empty() &&
138 auto it = floatingLegs.find(cfld->tag());
139 QL_REQUIRE(it != floatingLegs.end(),
140 "Did not find a commodity floating leg correpsonding to the fixed leg with tag '"
141 << cfld->tag() << "' from which to take the payment dates.");
142 vector<string> tmp;
143 for(auto const& cf: it->second) {
145 }
146 effLegDatum.paymentDates() = tmp;
147 }
148
149
150 buildLeg(engineFactory, effLegDatum, configuration);
151 legsIdx.push_back(t);
152 }
153
154
155 vector<Leg> legsTmp;
156 vector<bool> legPayersTmp;
157 vector<string> legCurrenciesTmp;
158 for (const Size idx : legsIdx) {
159 legsTmp.push_back(
legs_.at(idx));
162 }
166
167
168 auto swap = QuantLib::ext::make_shared<QuantLib::Swap>(
legs_,
legPayers_);
170 swap->setPricingEngine(engine);
172 instrument_ = QuantLib::ext::make_shared<VanillaInstrument>(swap);
173}
void buildLeg(const QuantLib::ext::shared_ptr< ore::data::EngineFactory > &ef, const ore::data::LegData &legDatum, const std::string &configuration)
std::vector< bool > legPayers_
std::vector< string > legCurrencies_
std::vector< QuantLib::Leg > legs_
void setSensitivityTemplate(const EngineBuilder &builder)
QuantLib::ext::shared_ptr< InstrumentWrapper > instrument_
void reset()
Reset trade, clear all base class data. This does not reset accumulated timings for this trade.
std::map< std::string, boost::any > additionalData_
Currency parseCurrency(const string &s)
Convert text to QuantLib::Currency.
#define LOG(text)
Logging Macro (Level = Notice)
boost::shared_ptr< CashFlow > unpackIndexWrappedCashFlow(const boost::shared_ptr< CashFlow > &c)
std::string to_string(const LocationInfo &l)