Build QuantLib/QuantExt instrument, link pricing engine.
39 {
41
42 QL_REQUIRE(
tradeActions().empty(),
"TradeActions not supported for VanillaOption");
43
44
45
48 bool sameCcy = underlyingCurrency == ccy;
49
52
53
55 QuantLib::ext::shared_ptr<StrikedTypePayoff> payoff(
new PlainVanillaPayoff(type,
strike_.
value()));
59
60
62
63 QuantLib::ext::shared_ptr<Exercise> exercise;
64 switch (exerciseType) {
65 case QuantLib::Exercise::Type::European: {
66 exercise = QuantLib::ext::make_shared<EuropeanExercise>(
expiryDate_);
67 break;
68 }
69 case QuantLib::Exercise::Type::American: {
71 break;
72 }
73 default:
74 QL_FAIL(
"Option Style " <<
option_.
style() <<
" is not supported");
75 }
76
77 QuantLib::ext::shared_ptr<Instrument> vanilla;
80
81
82 if (!sameCcy) {
83 QL_REQUIRE(exerciseType == Exercise::Type::European, "Option exercise must be European for a Quanto payoff.");
84 if (settlementType == Settlement::Type::Physical) {
86 "Physically settled Quanto options are allowed only for an FX underlying.");
87 }
88 }
89
90 if (exerciseType == Exercise::European && settlementType == Settlement::Cash) {
91
92
93
96 if (opd) {
97 if (opd->rulesBased()) {
98 const Calendar& cal = opd->calendar();
99 QL_REQUIRE(cal != Calendar(), "Need a non-empty calendar for rules based payment date.");
101 } else {
102 const vector<Date>& dates = opd->dates();
103 QL_REQUIRE(dates.size() == 1, "Need exactly one payment date for cash settled European option.");
105 }
107 }
108
110 QL_REQUIRE(sameCcy, "Payment date must equal expiry date for a Quanto payoff. Trade: " << id() << ".");
111
112
113
114
116 bool exercised = false;
117 Real exercisePrice = Null<Real>();
118 if (oed) {
119 QL_REQUIRE(oed->date() ==
expiryDate_,
"The supplied exercise date ("
120 << io::iso_date(oed->date())
121 << ") should equal the option's expiry date ("
123 exercised = true;
124 exercisePrice = oed->price();
125 }
126
127
129 QL_REQUIRE(
index_,
"Option trade " <<
id() <<
" has automatic exercise so we need a valid index.");
130
132 if (indexName.empty()) {
133 indexName =
index_->name();
135 indexName = "EQ-" + indexName;
136 }
138 }
139
140
141 LOG(
"Build CashSettledEuropeanOption for trade " <<
id());
142 vanilla = QuantLib::ext::make_shared<CashSettledEuropeanOption>(
144
145
146
148
149
151
152 } else {
154
155 if (sameCcy) {
156 LOG(
"Build VanillaOption for trade " <<
id());
157 vanilla = QuantLib::ext::make_shared<QuantLib::VanillaOption>(payoff, exercise);
158 }
159 else {
160 LOG(
"Build QuantoVanillaOption for trade " <<
id());
161 vanilla = QuantLib::ext::make_shared<QuantLib::QuantoVanillaOption>(payoff, exercise);
163 tradeTypeBuilder = "QuantoEquityOption";
165 tradeTypeBuilder = "QuantoCommodityOption";
166 else
168 }
169 } else {
170 LOG(
"Build VanillaForwardOption for trade " <<
id());
171 QL_REQUIRE(sameCcy, "Quanto payoff is not currently supported for Forward Options: Trade " << id());
172 vanilla = QuantLib::ext::make_shared<QuantExt::VanillaForwardOption>(payoff, exercise,
forwardDate_);
175 }
176 }
177
178 } else {
180
181 if (sameCcy) {
182 LOG(
"Build VanillaOption for trade " <<
id());
183 vanilla = QuantLib::ext::make_shared<QuantLib::VanillaOption>(payoff, exercise);
184 } else {
185 LOG(
"Build QuantoVanillaOption for trade " <<
id());
186 vanilla = QuantLib::ext::make_shared<QuantLib::QuantoVanillaOption>(payoff, exercise);
187 }
188 } else {
189 QL_REQUIRE(exerciseType == QuantLib::Exercise::Type::European, "Only European Forward Options currently supported");
190 LOG(
"Built VanillaForwardOption for trade " <<
id());
194 }
195
196
198 if (sameCcy)
199 tradeTypeBuilder =
tradeType_ + (exerciseType == QuantLib::Exercise::Type::European ?
"" :
"American");
200 else
201 tradeTypeBuilder = "QuantoFxOption";
202 }
203 }
204 LOG(
"tradeTypeBuilder set to " << tradeTypeBuilder <<
" for trade " <<
id());
205
206
207
209 QuantLib::ext::shared_ptr<EngineBuilder> builder = engineFactory->builder(tradeTypeBuilder);
210 QL_REQUIRE(builder, "No builder found for " << tradeTypeBuilder);
211
212 if (sameCcy) {
213 QuantLib::ext::shared_ptr<VanillaOptionEngineBuilder> vanillaOptionBuilder =
214 QuantLib::ext::dynamic_pointer_cast<VanillaOptionEngineBuilder>(builder);
215 QL_REQUIRE(vanillaOptionBuilder != nullptr, "No engine builder found for trade type " << tradeTypeBuilder);
216
219 } else {
221 }
223
225 } else {
226 QuantLib::ext::shared_ptr<QuantoVanillaOptionEngineBuilder> quantoVanillaOptionBuilder =
227 QuantLib::ext::dynamic_pointer_cast<QuantoVanillaOptionEngineBuilder>(builder);
228 QL_REQUIRE(quantoVanillaOptionBuilder != nullptr, "No (Quanto) engine builder found for trade type "
229 << tradeTypeBuilder);
230
231 vanilla->setPricingEngine(quantoVanillaOptionBuilder->engine(
assetName_, underlyingCurrency, ccy,
expiryDate_));
233
235 }
236
238 Real bsInd = (positionType == QuantLib::Position::Long ? 1.0 : -1.0);
240
241 std::vector<QuantLib::ext::shared_ptr<Instrument>> additionalInstruments;
242 std::vector<Real> additionalMultipliers;
245
246 instrument_ = QuantLib::ext::shared_ptr<InstrumentWrapper>(
247 new VanillaInstrument(vanilla, mult, additionalInstruments, additionalMultipliers));
248}
static const string defaultConfiguration
Default configuration label.
const string & callPut() const
const string & longShort() const
const string & style() const
const string & settlement() const
const bool & payoffAtExpiry() const
bool isAutomaticExercise() const
Automatic exercise assumed false if not explicitly provided.
const boost::optional< OptionPaymentData > & paymentData() const
const boost::optional< OptionExerciseData > & exerciseData() const
const PremiumData & premiumData() const
const vector< string > & exerciseDates() const
void addFixingDate(const QuantLib::Date &fixingDate, const std::string &indexName, const QuantLib::Date &payDate=Date::maxDate(), const bool alwaysAddIfPaysOnSettlement=false, const bool mandatoryFixing=true)
TradeActions & tradeActions()
Set the trade actions.
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)
void setSensitivityTemplate(const EngineBuilder &builder)
RequiredFixings requiredFixings_
QuantLib::ext::shared_ptr< InstrumentWrapper > instrument_
void setCurrency(const std::string ¤cy)
QuantLib::Real value() const
void setNotionalAndCurrencies()
QuantLib::Date expiryDate_
Store the option expiry date.
QuantLib::Date paymentDate_
Store the (optional) payment date.
const QuantLib::Date paymentDate() const
Currency underlyingCurrency_
Exercise::Type parseExerciseType(const std::string &s)
Convert text to QuantLib::Exercise::Type.
Currency parseCurrencyWithMinors(const string &s)
Convert text to QuantLib::Currency.
Date parseDate(const string &s)
Convert std::string to QuantLib::Date.
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.
Option::Type parseOptionType(const std::string &s)
Convert text to QuantLib::Option::Type.
#define LOG(text)
Logging Macro (Level = Notice)