Build QuantLib/QuantExt instrument, link pricing engine.
65 {
66
67
72
75
79
80 const QuantLib::ext::shared_ptr<Market> market = engineFactory->market();
81
82 QL_REQUIRE(
tradeActions().empty(),
"TradeActions not supported for FxOption");
84 QL_REQUIRE(
barrier_.
levels().size() == 1,
"Double barriers not supported for FxTouchOptions");
86
87
92
93 Natural payLag = 0;
94 BusinessDayConvention payConvention = Unadjusted;
95 Calendar payCalendar = NullCalendar();
96 Date payDate = expiryDate;
98 if (opd) {
99 if (opd->rulesBased()) {
100 payLag = opd->lag();
101 payConvention = opd->convention();
102 payCalendar = opd->calendar();
103 payDate = payCalendar.advance(expiryDate, opd->lag(), Days, opd->convention());
104 } else {
105 if (opd->dates().size() > 1)
107 "Found more than 1 payment date. The first one will be used.")
109 payDate = opd->dates().front();
110 }
111 }
112 QL_REQUIRE(payDate >= expiryDate, "Settlement date cannot be earlier than expiry date");
113
116 if (barrierType == Barrier::DownIn || barrierType == Barrier::DownOut)
117 type = Option::Type::Put;
118 else
119 type = Option::Type::Call;
125
126 QL_REQUIRE(rebate == 0, "Rebates not supported for FxTouchOptions");
127 QL_REQUIRE(payoffAtExpiry == true || barrierType == Barrier::Type::DownIn || barrierType == Barrier::Type::UpIn,
128 "Payoff at hit not supported for FxNoTouchOptions");
129 if ((barrierType == Barrier::Type::DownIn || barrierType == Barrier::Type::UpIn) && payoffAtExpiry == false)
130 QL_REQUIRE(
132 "Option payment data must be rules-based and relative to Exercise for FxOneTouchOption with payoff at hit");
133
134
135 bool flipResults = false;
137
138 level = 1.0 / level;
139 std::swap(fgnCcy, domCcy);
140 type =
type == Option::Call ? Option::Put : Option::Call;
141 switch (barrierType) {
142 case Barrier::DownIn:
143 barrierType = Barrier::UpIn;
144 break;
145 case Barrier::UpIn:
146 barrierType = Barrier::DownIn;
147 break;
148 case Barrier::DownOut:
149 barrierType = Barrier::UpOut;
150 break;
151 case Barrier::UpOut:
152 barrierType = Barrier::DownOut;
153 break;
154 }
155 flipResults = true;
159 }
160 DLOG(
"Setting up FxTouchOption with level " << level <<
" foreign/bought " << fgnCcy <<
" domestic/sold "
161 << domCcy);
162
163
164
165 QuantLib::ext::shared_ptr<QuantExt::FxIndex>
fxIndex;
170
171 auto buildBarrierOptionWrapperInstr = [
this,
type, level, engineFactory, domCcy, fgnCcy, flipResults, positionType,
172 market, barrierType, rebate,
fxIndex, cal,
173 start](const Date& expiryDate, const Date& payDate) {
174 QuantLib::ext::shared_ptr<StrikedTypePayoff> payoff(
new CashOrNothingPayoff(
type, level, 1.0));
175 Leg leg;
176
177 leg.push_back(QuantLib::ext::shared_ptr<CashFlow>(new SimpleCashFlow(1.0, payDate)));
178
179 bool payoffFlag = true;
180
181 QuantLib::ext::shared_ptr<Exercise> exercise = QuantLib::ext::make_shared<AmericanExercise>(expiryDate, payoffFlag);
182
183 QuantLib::ext::shared_ptr<Instrument>
barrier = QuantLib::ext::make_shared<VanillaOption>(payoff, exercise);
184 QuantLib::ext::shared_ptr<Instrument> underlying = QuantLib::ext::make_shared<Swap>(Leg(), leg);
185
186
187 QuantLib::ext::shared_ptr<EngineBuilder> builder = engineFactory->builder(
tradeType_);
188 QL_REQUIRE(builder,
"No builder found for " <<
tradeType_);
189 QuantLib::ext::shared_ptr<FxTouchOptionEngineBuilder> fxTouchOptBuilder =
190 QuantLib::ext::dynamic_pointer_cast<FxTouchOptionEngineBuilder>(builder);
191 barrier->setPricingEngine(fxTouchOptBuilder->engine(fgnCcy, domCcy,
type_, payDate, flipResults));
193 if (
type_ ==
"One-Touch") {
194
195
196 builder = engineFactory->builder("Swap");
197 QL_REQUIRE(builder, "No builder found for Swap");
198 QuantLib::ext::shared_ptr<SwapEngineBuilderBase> swapBuilder =
199 QuantLib::ext::dynamic_pointer_cast<SwapEngineBuilderBase>(builder);
200 underlying->setPricingEngine(swapBuilder->engine(domCcy, std::string(), std::string()));
201 }
202
203 bool isLong = (positionType == Position::Long) ? true : false;
204
205 std::vector<QuantLib::ext::shared_ptr<Instrument>> additionalInstruments;
206 std::vector<Real> additionalMultipliers;
207 Date lastPremiumDate =
211
212 Handle<Quote> spot = market->fxRate(fgnCcy.code() + domCcy.code());
213
214 auto barrierOptionWrapper = QuantLib::ext::make_shared<SingleBarrierOptionWrapper>(
215 barrier, isLong, expiryDate,
false, underlying, barrierType, spot, level, rebate, domCcy, start,
fxIndex,
217
218 maturity_ = std::max(lastPremiumDate, payDate);
219
220 return barrierOptionWrapper;
221 };
222
223 auto barrierOptionWrapper = buildBarrierOptionWrapperInstr(expiryDate, payDate);
224
225
226
228 if (start != Date()) {
229 for (Date d = start; d <= expiryDate; d = fixingCal.advance(d, 1 * Days))
231 }
232
233
234
235 if (auto rt = engineFactory->engineData()->globalParameters().find("RunType");
236 rt != engineFactory->engineData()->globalParameters().end() && rt->second != "PortfolioAnalyser" &&
237 barrierOptionWrapper->exercise()) {
238 QL_REQUIRE(barrierOptionWrapper->exerciseDate() != Date(), "Option is exercised but exercise date was not defined");
239 expiryDate = barrierOptionWrapper->exerciseDate();
241
242 if (!payoffAtExpiry &&
type_ ==
"One-Touch") {
243 payDate = payCalendar.advance(expiryDate, payLag, Days, payConvention);
244 barrierOptionWrapper = buildBarrierOptionWrapperInstr(expiryDate, payDate);
246 }
247 }
248
250
251
252}
std::vector< ore::data::TradeBarrier > levels() const
const std::string & style() const
std::string & domesticCurrency_
std::string & foreignCurrency_
const string & type() const
void log() const
generate Boost log record to pass to corresponding sinks
void setCallPut(const string &callPut)
const string & longShort() const
const bool & payoffAtExpiry() const
const boost::optional< OptionPaymentData > & paymentData() 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)
Utility classes for Structured warnings, contains the Trade ID and Type.
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_
const string & tradeType() const
std::map< std::string, boost::any > additionalData_
Calendar parseCalendar(const string &s)
Convert text to QuantLib::Calendar.
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.
#define DLOG(text)
Logging Macro (Level = Debug)
std::string to_string(const LocationInfo &l)
QuantLib::ext::shared_ptr< QuantExt::FxIndex > buildFxIndex(const string &fxIndex, const string &domestic, const string &foreign, const QuantLib::ext::shared_ptr< Market > &market, const string &configuration, bool useXbsCurves)