Build QuantLib/QuantExt instrument, link pricing engine. If build() is called multiple times, reset() should be called between these calls.
37 {
38
39 DLOG(
"Building MultiLegOption " <<
id());
40
41 QL_REQUIRE(!
underlyingData_.empty(),
"MultiLegOption: no underlying given");
42
43 Position::Type positionType = Position::Long;
44 Settlement::Type settleType = Settlement::Cash;
47 QL_REQUIRE(exerciseType == Exercise::Bermudan || exerciseType == Exercise::European,
48 "MultiLegOption: exercise type must be bermudan or european");
51 }
52
53 Date today = Settings::instance().evaluationDate();
54 Real multiplier = positionType == Position::Long ? 1.0 : -1.0;
55
56 auto builder =
57 QuantLib::ext::dynamic_pointer_cast<MultiLegOptionEngineBuilderBase>(engineFactory->builder("MultiLegOption"));
58 QL_REQUIRE(builder != nullptr, "wrong builder, expected multi leg option engine builder");
59
60
61
62
63 vector<Leg> underlyingLegs;
64 vector<bool> underlyingPayers;
65 vector<Currency> underlyingCurrencies;
67
69 auto legBuilder = engineFactory->legBuilder(underlyingData_[i].legType());
70 underlyingLegs.push_back(legBuilder->buildLeg(underlyingData_[i], engineFactory, requiredFixings_,
71 builder->configuration(MarketContext::pricing)));
72 underlyingCurrencies.push_back(
parseCurrency(underlyingData_[i].currency()));
74 underlyingPayers.push_back(underlyingData_[i].isPayer());
75 DLOG(
"Added leg of type " << underlyingData_[i].legType() <<
" in currency " << underlyingData_[i].currency()
76 << " is payer " << underlyingData_[i].isPayer());
77 }
78
79
80
81 QuantLib::ext::shared_ptr<Exercise> exercise;
82 vector<Date> exDates;
86 if (exDate > Settings::instance().evaluationDate())
87 exDates.push_back(exDate);
88 }
89 }
90 if (!exDates.empty()) {
91 std::sort(exDates.begin(), exDates.end());
92 exercise = QuantLib::ext::make_shared<BermudanExercise>(exDates);
93 DLOG(
"Added exercise with " << exDates.size() <<
" alive exercise dates.");
94 } else {
95 DLOG(
"No exercise added, instrument is equal to the underlying");
96 }
97
98
99
100 auto multiLegOption = QuantLib::ext::make_shared<QuantExt::MultiLegOption>(underlyingLegs, underlyingPayers,
101 underlyingCurrencies, exercise, settleType);
102
103 DLOG(
"QLE Instrument built.")
104
105
106
107 vector<Date> underlyingFixingDates;
109 vector<Currency> allCurrencies;
110 for (auto const& c : underlyingCurrencies) {
111 if (std::find(allCurrencies.begin(), allCurrencies.end(), c) == allCurrencies.end()) {
112 allCurrencies.push_back(c);
113 }
114 }
115 for (auto const& l : underlyingLegs) {
116 for (auto const& c : l) {
117 auto flr = QuantLib::ext::dynamic_pointer_cast<QuantLib::FloatingRateCoupon>(c);
118 auto cfc = QuantLib::ext::dynamic_pointer_cast<QuantLib::CappedFlooredCoupon>(c);
119 if (cfc != nullptr)
120 flr = cfc->underlying();
121 if (flr != nullptr) {
122 if (flr->fixingDate() > today) {
123 underlyingFixingDates.push_back(flr->fixingDate());
124 underlyingIndices.push_back(flr->index());
125 if (std::find(allCurrencies.begin(), allCurrencies.end(), flr->index()->currency()) ==
126 allCurrencies.end())
127 allCurrencies.push_back(flr->index()->currency());
128 }
129 }
130 }
131 }
132
133 DLOG(
"Extracted underlying currencies, indices and fixing dates.")
134
136 std::vector<Real> additionalMultipliers;
137 Date lastPremiumDate = addPremiums(additionalInstruments, additionalMultipliers, multiplier,
138 optionData_.premiumData(), -multiplier, parseCurrency(legCurrencies_.front()),
139 engineFactory, builder->configuration(MarketContext::pricing));
140
141
142
143 std::sort(allCurrencies.begin(), allCurrencies.end(),
144 [](const Currency& a, const Currency& b) { return a.code() < b.code(); });
145 auto engine = builder->engine(id(), exDates, multiLegOption->maturityDate(), allCurrencies, underlyingFixingDates,
146 underlyingIndices);
147 multiLegOption->setPricingEngine(engine);
149
150 DLOG(
"Pricing engine set.")
151
152
153
154 instrument_ =
155 QuantLib::ext::make_shared<VanillaInstrument>(multiLegOption, multiplier, additionalInstruments, additionalMultipliers);
156
157
158
159 legs_ = underlyingLegs;
160 legPayers_ = underlyingPayers;
161 notional_ = currentNotional(
legs_.front());
163
164 auto moe =
QuantLib::ext::dynamic_pointer_cast<McMultiLegOptionEngine>(engine);
165 QL_REQUIRE(moe != nullptr, "MultiLegOption::build(): expected McMultiLegOptionEngine from engine builder");
166 npvCurrency_ = moe->model()->irlgm1f(0)->currency().code();
167
168 DLOG("Building MultiLegOption done");
169}
const Date & maturityDate() const
const std::vector< Leg > legs_
const string & longShort() const
const string & style() const
const string & settlement() const
const vector< string > & exerciseDates() const
std::vector< string > legCurrencies_
void setSensitivityTemplate(const EngineBuilder &builder)
Exercise::Type parseExerciseType(const std::string &s)
Convert text to QuantLib::Exercise::Type.
Date parseDate(const string &s)
Convert std::string to QuantLib::Date.
Currency parseCurrency(const string &s)
Convert text to QuantLib::Currency.
Position::Type parsePositionType(const std::string &s)
Convert text to QuantLib::Position::Type.
Settlement::Type parseSettlementType(const std::string &s)
Convert text to QuantLib::Settlement::Type.
#define DLOG(text)
Logging Macro (Level = Debug)
Size size(const ValueType &v)