19#include <boost/make_shared.hpp>
28#include <ql/errors.hpp>
29#include <ql/exercise.hpp>
30#include <ql/instruments/barriertype.hpp>
31#include <ql/instruments/compositeinstrument.hpp>
32#include <ql/instruments/vanillaoption.hpp>
49 const QuantLib::ext::shared_ptr<Market> market = engineFactory->market();
54 QL_REQUIRE(
barrier_.
levels().size() == 1,
"Invalid number of barrier levels");
56 QL_REQUIRE(
tradeActions().empty(),
"TradeActions not supported for FxEuropeanBarrierOption");
62 QL_REQUIRE(rebate >= 0,
"Rebate must be non-negative");
135 Date paymentDate = expiryDate;
137 QuantLib::ext::shared_ptr<Exercise> exercise = QuantLib::ext::make_shared<EuropeanExercise>(expiryDate);
141 if (opd->rulesBased()) {
142 const Calendar& cal = opd->calendar();
143 QL_REQUIRE(cal != Calendar(),
"Need a non-empty calendar for rules based payment date.");
144 paymentDate = cal.advance(expiryDate, opd->lag(), Days, opd->convention());
146 const vector<Date>& dates = opd->dates();
147 QL_REQUIRE(dates.size() == 1,
"Need exactly one payment date for cash settled European option.");
148 paymentDate = dates[0];
150 QL_REQUIRE(paymentDate >= expiryDate,
"Payment date must be greater than or equal to expiry date.");
156 QuantLib::ext::shared_ptr<Instrument> digital;
157 QuantLib::ext::shared_ptr<Instrument> vanillaK;
158 QuantLib::ext::shared_ptr<Instrument> vanillaB;
159 QuantLib::ext::shared_ptr<Instrument> rebateInstrument;
161 bool exercised =
false;
162 Real exercisePrice = Null<Real>();
165 Option::Type rebateType;
166 if (barrierType == Barrier::Type::UpIn || barrierType == Barrier::Type::DownOut) {
168 rebateType = Option::Put;
171 rebateType = Option::Call;
174 if (paymentDate > expiryDate) {
179 QL_REQUIRE(oed->date() == expiryDate,
"The supplied exercise date ("
180 << io::iso_date(oed->date())
181 <<
") should equal the option's expiry date ("
182 << io::iso_date(expiryDate) <<
").");
184 exercisePrice = oed->price();
187 QuantLib::ext::shared_ptr<FxIndex>
fxIndex;
189 QL_REQUIRE(!
fxIndex_.empty(),
"FX european barrier option trade with delay payment "
190 <<
id() <<
": the FXIndex node needs to be populated.");
196 vanillaK = QuantLib::ext::make_shared<CashSettledEuropeanOption>(
198 vanillaB = QuantLib::ext::make_shared<CashSettledEuropeanOption>(
200 digital = QuantLib::ext::make_shared<CashSettledEuropeanOption>(type, level, fabs(level -
strike), expiryDate,
202 exercised, exercisePrice);
203 rebateInstrument = QuantLib::ext::make_shared<CashSettledEuropeanOption>(rebateType, level, rebate, expiryDate,
205 exercised, exercisePrice);
208 QuantLib::ext::shared_ptr<StrikedTypePayoff> payoffVanillaK(
new PlainVanillaPayoff(type,
strike));
210 QuantLib::ext::shared_ptr<StrikedTypePayoff> payoffVanillaB(
new PlainVanillaPayoff(type, level));
212 QuantLib::ext::shared_ptr<StrikedTypePayoff> payoffDigital(
new CashOrNothingPayoff(type, level, fabs(level -
strike)));
213 QuantLib::ext::shared_ptr<StrikedTypePayoff> rebatePayoff(
new CashOrNothingPayoff(rebateType, level, rebate));
215 vanillaK = QuantLib::ext::make_shared<VanillaOption>(payoffVanillaK, exercise);
216 vanillaB = QuantLib::ext::make_shared<VanillaOption>(payoffVanillaB, exercise);
217 digital = QuantLib::ext::make_shared<VanillaOption>(payoffDigital, exercise);
218 rebateInstrument = QuantLib::ext::make_shared<VanillaOption>(rebatePayoff, exercise);
223 const bool flipResults =
false;
226 QuantLib::ext::shared_ptr<EngineBuilder> builder;
227 QuantLib::ext::shared_ptr<EngineBuilder> digitalBuilder;
228 QuantLib::ext::shared_ptr<VanillaOptionEngineBuilder> fxOptBuilder;
230 if (paymentDate > expiryDate) {
231 builder = engineFactory->builder(
"FxOptionEuropeanCS");
232 QL_REQUIRE(builder,
"No builder found for FxOptionEuropeanCS");
233 fxOptBuilder = QuantLib::ext::dynamic_pointer_cast<FxEuropeanCSOptionEngineBuilder>(builder);
235 digitalBuilder = engineFactory->builder(
"FxDigitalOptionEuropeanCS");
236 QL_REQUIRE(digitalBuilder,
"No builder found for FxDigitalOptionEuropeanCS");
237 auto fxDigitalOptBuilder = QuantLib::ext::dynamic_pointer_cast<FxDigitalCSOptionEngineBuilder>(digitalBuilder);
238 digital->setPricingEngine(fxDigitalOptBuilder->engine(boughtCcy, soldCcy));
239 rebateInstrument->setPricingEngine(fxDigitalOptBuilder->engine(boughtCcy, soldCcy));
242 builder = engineFactory->builder(
"FxOption");
243 QL_REQUIRE(builder,
"No builder found for FxOption");
244 fxOptBuilder = QuantLib::ext::dynamic_pointer_cast<FxEuropeanOptionEngineBuilder>(builder);
246 digitalBuilder = engineFactory->builder(
"FxDigitalOption");
247 QL_REQUIRE(digitalBuilder,
"No builder found for FxDigitalOption");
248 auto fxDigitalOptBuilder = QuantLib::ext::dynamic_pointer_cast<FxDigitalOptionEngineBuilder>(digitalBuilder);
249 digital->setPricingEngine(fxDigitalOptBuilder->engine(boughtCcy, soldCcy, flipResults));
250 rebateInstrument->setPricingEngine(fxDigitalOptBuilder->engine(boughtCcy, soldCcy, flipResults));
254 vanillaK->setPricingEngine(fxOptBuilder->engine(boughtCcy, soldCcy, paymentDate));
255 vanillaB->setPricingEngine(fxOptBuilder->engine(boughtCcy, soldCcy, paymentDate));
258 QuantLib::ext::shared_ptr<CompositeInstrument> qlInstrument = QuantLib::ext::make_shared<CompositeInstrument>();
259 qlInstrument->add(rebateInstrument);
260 if (type == Option::Call) {
261 if (barrierType == Barrier::Type::UpIn || barrierType == Barrier::Type::DownOut) {
263 qlInstrument->add(vanillaB);
264 qlInstrument->add(digital);
266 qlInstrument->add(vanillaK);
268 }
else if (barrierType == Barrier::Type::UpOut || barrierType == Barrier::Type::DownIn) {
270 qlInstrument->add(vanillaK);
271 qlInstrument->add(vanillaB, -1);
272 qlInstrument->add(digital, -1);
277 QL_FAIL(
"Unknown Barrier Type: " << barrierType);
279 }
else if (type == Option::Put) {
280 if (barrierType == Barrier::Type::UpIn || barrierType == Barrier::Type::DownOut) {
284 qlInstrument->add(vanillaK);
285 qlInstrument->add(vanillaB, -1);
286 qlInstrument->add(digital, -1);
288 }
else if (barrierType == Barrier::Type::UpOut || barrierType == Barrier::Type::DownIn) {
290 qlInstrument->add(vanillaK);
292 qlInstrument->add(vanillaB);
293 qlInstrument->add(digital);
296 QL_FAIL(
"Unknown Barrier Type: " << barrierType);
302 Real bsInd = (positionType == QuantLib::Position::Long ? 1.0 : -1.0);
305 std::vector<QuantLib::ext::shared_ptr<Instrument>> additionalInstruments;
306 std::vector<Real> additionalMultipliers;
310 instrument_ = QuantLib::ext::shared_ptr<InstrumentWrapper>(
311 new VanillaInstrument(qlInstrument, mult, additionalInstruments, additionalMultipliers));
328 QL_REQUIRE(fxNode,
"No FxEuropeanBarrierOptionData Node");
Engine builder for FX Options.
const std::string & type() const
virtual void fromXML(ore::data::XMLNode *node) override
virtual ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
std::vector< ore::data::TradeBarrier > levels() const
const std::string & style() const
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
std::string fxIndex_
If the option has automatic exercise (i.e. cash settled after maturity), need an FX index for settlem...
const std::string & fxIndex() const
void build(const QuantLib::ext::shared_ptr< EngineFactory > &) override
Build QuantLib/QuantExt instrument, link pricing engine.
std::string soldCurrency_
std::string boughtCurrency_
const string & callPut() const
const string & longShort() const
const string & style() const
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
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.
virtual void fromXML(XMLNode *node) override
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)
virtual XMLNode * toXML(XMLDocument &doc) const override
RequiredFixings requiredFixings_
QuantLib::ext::shared_ptr< InstrumentWrapper > instrument_
std::map< std::string, boost::any > additionalData_
Vanilla Instrument Wrapper.
Small XML Document wrapper class.
XMLNode * allocNode(const string &nodeName)
util functions that wrap rapidxml
static Real getChildValueAsDouble(XMLNode *node, const string &name, bool mandatory=false, double defaultValue=0.0)
static string getChildValue(XMLNode *node, const string &name, bool mandatory=false, const string &defaultValue=string())
static XMLNode * getChildNode(XMLNode *n, const string &name="")
static XMLNode * addChild(XMLDocument &doc, XMLNode *n, const string &name)
static void appendNode(XMLNode *parent, XMLNode *child)
FX European Barrier Option data model and serialization.
FX Option data model and serialization.
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.
Barrier::Type parseBarrierType(const std::string &s)
Convert std::string to QuantLib::BarrierType.
Option::Type parseOptionType(const std::string &s)
Convert text to QuantLib::Option::Type.
Classes and functions for log message handling.
market data related utilties
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)
Serializable Credit Default Swap.
Map text representations to QuantLib/QuantExt types.