25#include <boost/lexical_cast.hpp>
32 static const std::string vanilla_basket_option_script =
33 " REQUIRE SIZE(Underlyings) == SIZE(Weights);\n"
35 " NUMBER u, basketPrice, ExerciseProbability, Payoff, currentNotional;\n"
37 " FOR u IN (1, SIZE(Underlyings), 1) DO\n"
38 " basketPrice = basketPrice + Underlyings[u](Expiry) * Weights[u];\n"
41 " Payoff = max(PutCall * (basketPrice - Strike), 0);\n"
43 " Option = LongShort * Notional * PAY(Payoff, Expiry, Settlement, PayCcy);\n"
45 " IF Payoff > 0 THEN\n"
46 " ExerciseProbability = 1;\n"
48 " currentNotional = Notional * Strike;\n";
50 static const std::string asian_basket_option_script =
51 " REQUIRE SIZE(Underlyings) == SIZE(Weights);\n"
53 " NUMBER d, u, basketPrice, ExerciseProbability, Payoff;\n"
54 " NUMBER currentNotional;\n"
56 " FOR d IN (1, SIZE(ObservationDates), 1) DO\n"
57 " FOR u IN (1, SIZE(Underlyings), 1) DO\n"
58 " basketPrice = basketPrice + Underlyings[u](ObservationDates[d]) * Weights[u];\n"
62 " basketPrice = basketPrice / SIZE(ObservationDates);\n"
64 " Payoff = max(PutCall * (basketPrice - Strike), 0);\n"
66 " Option = LongShort * Notional * PAY(Payoff, Expiry, Settlement, PayCcy);\n"
68 " IF Payoff > 0 THEN\n"
69 " ExerciseProbability = 1;\n"
72 " currentNotional = Notional * Strike; \n";
74 static const std::string average_strike_basket_option_script =
75 " REQUIRE SIZE(Underlyings) == SIZE(Weights);\n"
77 " NUMBER d, u, timeAverageBasketPrice, currentNotional;\n"
78 " FOR d IN (1, SIZE(ObservationDates), 1) DO\n"
79 " FOR u IN (1, SIZE(Underlyings), 1) DO\n"
80 " timeAverageBasketPrice = timeAverageBasketPrice\n"
81 " + Underlyings[u](ObservationDates[d]) * Weights[u];\n"
84 " timeAverageBasketPrice = timeAverageBasketPrice / SIZE(ObservationDates);\n"
86 " NUMBER expiryBasketPrice;\n"
87 " FOR u IN (1, SIZE(Underlyings), 1) DO\n"
88 " expiryBasketPrice = expiryBasketPrice + Underlyings[u](Expiry) * Weights[u];\n"
92 " Payoff = max(PutCall * (expiryBasketPrice - timeAverageBasketPrice), 0);\n"
94 " Option = LongShort * Notional * PAY(Payoff, Expiry, Settlement, PayCcy);\n"
96 " NUMBER ExerciseProbability;\n"
97 " IF Payoff > 0 THEN\n"
98 " ExerciseProbability = 1;\n"
100 " FOR u IN (1, SIZE(Underlyings), 1) DO\n"
101 " currentNotional = currentNotional + Notional * Underlyings[u](ObservationDates[1]) * Weights[u];\n"
104 static const std::string lookback_call_basket_option_script =
105 " REQUIRE SIZE(Underlyings) == SIZE(Weights);\n"
107 " NUMBER d, u, basketPrice, minBasketPrice, currentNotional;\n"
108 " FOR d IN (1, SIZE(ObservationDates), 1) DO\n"
109 " basketPrice = 0;\n"
110 " FOR u IN (1, SIZE(Underlyings), 1) DO\n"
111 " basketPrice = basketPrice + Underlyings[u](ObservationDates[d]) * Weights[u];\n"
114 " minBasketPrice = basketPrice;\n"
116 " IF basketPrice < minBasketPrice THEN\n"
117 " minBasketPrice = basketPrice;\n"
121 " NUMBER expiryBasketPrice;\n"
122 " FOR u IN (1, SIZE(Underlyings), 1) DO\n"
123 " expiryBasketPrice = expiryBasketPrice + Underlyings[u](Expiry) * Weights[u];\n"
127 " Payoff = max(expiryBasketPrice - minBasketPrice, 0);\n"
129 " Option = LongShort * Notional * PAY(Payoff, Expiry, Settlement, PayCcy);\n"
131 " NUMBER ExerciseProbability;\n"
132 " IF Payoff > 0 THEN\n"
133 " ExerciseProbability = 1;\n"
135 " FOR u IN (1, SIZE(Underlyings), 1) DO\n"
136 " currentNotional = currentNotional + Notional * Underlyings[u](ObservationDates[1]) * Weights[u];\n"
139 static const std::string lookback_put_basket_option_script =
140 " REQUIRE SIZE(Underlyings) == SIZE(Weights);\n"
142 " NUMBER d, u, basketPrice, maxBasketPrice, currentNotional;\n"
143 " FOR d IN (1, SIZE(ObservationDates), 1) DO\n"
144 " basketPrice = 0;\n"
145 " FOR u IN (1, SIZE(Underlyings), 1) DO\n"
146 " basketPrice = basketPrice + Underlyings[u](ObservationDates[d]) * Weights[u];\n"
149 " maxBasketPrice = basketPrice;\n"
151 " IF basketPrice > maxBasketPrice THEN\n"
152 " maxBasketPrice = basketPrice;\n"
156 " NUMBER expiryBasketPrice;\n"
157 " FOR u IN (1, SIZE(Underlyings), 1) DO\n"
158 " expiryBasketPrice = expiryBasketPrice + Underlyings[u](Expiry) * Weights[u];\n"
162 " Payoff = max(maxBasketPrice - expiryBasketPrice, 0);\n"
164 " Option = LongShort * Notional * PAY(Payoff, Expiry, Settlement, PayCcy);\n"
166 " NUMBER ExerciseProbability;\n"
167 " IF Payoff > 0 THEN\n"
168 " ExerciseProbability = 1;\n"
170 " FOR u IN (1, SIZE(Underlyings), 1) DO\n"
171 " currentNotional = currentNotional + Notional * Underlyings[u](ObservationDates[1]) * Weights[u];\n"
189 numbers_.emplace_back(
"Number",
"LongShort", positionType == Position::Long ?
"1" :
"-1");
199 currencies_.emplace_back(
"Currency",
"PayCcy", ccy);
203 <<
"', expected 'Arithmetic'");
205 std::string scriptToUse;
207 scriptToUse = vanilla_basket_option_script;
209 numbers_.emplace_back(
"Number",
"Strike", strike);
211 scriptToUse = asian_basket_option_script;
214 numbers_.emplace_back(
"Number",
"Strike", strike);
216 scriptToUse = average_strike_basket_option_script;
220 scriptToUse = lookback_call_basket_option_script;
223 scriptToUse = lookback_put_basket_option_script;
237 {{
"currentNotional",
"currentNotional"}, {
"notionalCurrency",
"PayCcy"}}, {})}};
249 std::string assetClass = boost::any_cast<std::string>(
additionalData_[
"isdaAssetClass"]);
250 if (assetClass ==
"Equity") {
252 additionalData_[
"isdaSubProduct"] = string(
"Price Return Basic Performance");
253 }
else if (assetClass ==
"Foreign Exchange") {
256 }
else if (assetClass ==
"Commodity") {
259 additionalData_[
"isdaSubProduct"] = string(
"Price Return Basic Performance");
261 WLOG(
"ISDA taxonomy incomplete for trade " <<
id());
267 std::vector<std::string> underlyings, weights;
270 QL_REQUIRE(u->weight() != Null<Real>(),
"underlying '" << u->name() <<
"' has no weight");
271 weights.push_back(boost::lexical_cast<std::string>(u->weight()));
274 indices_.emplace_back(
"Index",
"Underlyings", underlyings);
275 numbers_.emplace_back(
"Number",
"Weights", weights);
281 QL_REQUIRE(dataNode,
tradeType() +
"Data node not found");
287 QL_REQUIRE(underlyingsNode,
"No Underlyings node");
289 for (
auto const& n : underlyings) {
basket option wrapper for scripted trade
void setIsdaTaxonomyFields() override
std::vector< QuantLib::ext::shared_ptr< ore::data::Underlying > > underlyings_
void fromXML(XMLNode *node) override
XMLNode * toXML(XMLDocument &doc) const override
ScheduleData observationDates_
void build(const QuantLib::ext::shared_ptr< EngineFactory > &) override
const string & callPut() const
const string & payoffType2() const
const string & payoffType() const
const string & longShort() const
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
const PremiumData & premiumData() const
const vector< string > & exerciseDates() const
bool hasData() const
Check if has any dates/rules/derived schedules.
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
std::vector< ScriptedTradeEventData > events_
std::vector< ScriptedTradeValueTypeData > currencies_
std::vector< ScriptedTradeValueTypeData > indices_
virtual void setIsdaTaxonomyFields()
std::vector< ScriptedTradeValueTypeData > numbers_
std::map< std::string, ScriptedTradeScriptData > script_
void build(const QuantLib::ext::shared_ptr< EngineFactory > &) override
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
const string & tradeType() const
std::map< std::string, boost::any > additionalData_
XMLNode * toXML(XMLDocument &doc) const
void setCurrency(const std::string ¤cy)
void fromXML(XMLNode *node, const bool isRequired=true, const bool allowYieldStrike=false)
QuantLib::Real value() const
const QuantLib::ext::shared_ptr< Underlying > & underlying()
void fromXML(XMLNode *node) override
Small XML Document wrapper class.
XMLNode * allocNode(const string &nodeName)
util functions that wrap rapidxml
static vector< XMLNode * > getChildrenNodes(XMLNode *node, const string &name)
Returns all the children with a given name.
static string getChildValue(XMLNode *node, const string &name, bool mandatory=false, const string &defaultValue=string())
static XMLNode * getChildNode(XMLNode *n, const string &name="")
static void setNodeName(XMLDocument &doc, XMLNode *node, const string &name)
static XMLNode * addChild(XMLDocument &doc, XMLNode *n, const string &name)
static void appendNode(XMLNode *parent, XMLNode *child)
Currency parseCurrencyWithMinors(const string &s)
Convert text to QuantLib::Currency.
Position::Type parsePositionType(const std::string &s)
Convert text to QuantLib::Position::Type.
Option::Type parseOptionType(const std::string &s)
Convert text to QuantLib::Option::Type.
#define WLOG(text)
Logging Macro (Level = Warning)
QL_DEPRECATED_ENABLE_WARNING std::string scriptedIndexName(const QuantLib::ext::shared_ptr< Underlying > &underlying)
Serializable Credit Default Swap.
Map text representations to QuantLib/QuantExt types.
string conversion utilities