30#include <boost/algorithm/string/replace.hpp>
34using namespace std::placeholders;
40 const Real premiumMultiplier) {
42 DLOG(
"ScriptedTrade::build() called for trade " <<
id());
44 auto builder = QuantLib::ext::dynamic_pointer_cast<ScriptedTradeEngineBuilder>(engineFactory->builder(
"ScriptedTrade"));
46 QL_REQUIRE(builder,
"no builder found for ScriptedTrade");
47 auto engine = builder->engine(
id(), *
this, engineFactory->referenceData(), engineFactory->iborFallbackConfig());
54 auto qleInstr = QuantLib::ext::make_shared<ScriptedInstrument>(builder->lastRelevantDate());
55 qleInstr->setPricingEngine(engine);
65 std::vector<QuantLib::ext::shared_ptr<Instrument>> additionalInstruments;
66 std::vector<Real> additionalMultipliers;
71 instrument_ = QuantLib::ext::make_shared<VanillaInstrument>(qleInstr, 1.0, additionalInstruments, additionalMultipliers);
74 for (
auto const& f : builder->fixings()) {
75 for (
auto const& d : f.second) {
78 QL_DEPRECATED_DISABLE_WARNING
80 info.
inf()->frequency(), info.
inf()->availabilityLag(),
81 CPI::AsIndex, info.
inf()->frequency(), Date::maxDate(),
false,
false);
82 QL_DEPRECATED_ENABLE_WARNING
83 }
else if (info.
isFx()) {
125 <<
" follows the Equity template");
139 auto st = QuantLib::ext::dynamic_pointer_cast<ScriptedInstrument>(
instrument_->qlInstrument(
true));
140 QL_REQUIRE(st,
"internal error: could not cast to ScriptedInstrument");
142 return st->result<Real>(
"currentNotional");
143 }
catch (
const std::exception& e) {
144 if (st->lastCalculationWasValid()) {
146 DLOG(
"notional was not retrieved: " << e.what() <<
", return null");
160 auto st = QuantLib::ext::dynamic_pointer_cast<ScriptedInstrument>(
instrument_->qlInstrument(
true));
161 QL_REQUIRE(st,
"internal error: could not cast to ScriptedInstrument");
163 return instrument_->qlInstrument()->result<std::string>(
"notionalCurrency");
164 }
catch (
const std::exception& e) {
165 if (st->lastCalculationWasValid()) {
167 DLOG(
"notional ccy was not retrieved: " << e.what() <<
", return empty string");
174 return std::string();
191enum class NodeType { Event, Number, Index, Currency, Daycounter };
193std::pair<NodeType, std::string> getNativeTypeAndValue(
const std::string&
value,
const std::string& type) {
195 static std::map<std::string, std::map<std::string, std::string>> mappings = {
196 {
"bool", {{
"true",
"1"}, {
"false",
"-1"}}},
197 {
"optionType", {{
"Call",
"1"}, {
"Put",
"-1"}, {
"Cap",
"1"}, {
"Floor",
"-1"}}},
198 {
"longShort", {{
"Long",
"1"}, {
"Short",
"-1"}}},
199 {
"barrierType", {{
"DownIn",
"1"}, {
"UpIn",
"2"}, {
"DownOut",
"3"}, {
"UpOut",
"4"}}},
204 return std::make_pair(NodeType::Event,
value);
205 else if (type ==
"number")
206 return std::make_pair(NodeType::Number,
value);
207 else if (type ==
"index")
208 return std::make_pair(NodeType::Index,
value);
209 else if (type ==
"currency")
210 return std::make_pair(NodeType::Currency,
value);
211 else if (type ==
"dayCounter")
212 return std::make_pair(NodeType::Daycounter,
value);
215 auto t = mappings.find(type);
216 QL_REQUIRE(t != mappings.end(),
"type '" << type <<
"' not known");
217 auto v = t->second.find(
value);
218 QL_REQUIRE(v != t->second.end(),
"value '" <<
value <<
"' for type '" << type <<
"' not known");
219 return std::make_pair(NodeType::Number, v->second);
225std::map<ore::data::AssetClass, std::set<std::string>>
228 map<ore::data::AssetClass, set<string>> result;
232 if (!p.value().empty())
233 vals.push_back(p.value());
237 for (
auto v : vals) {
242 }
else if (ind.
isEq()) {
261 QL_REQUIRE(dataNode,
"ScriptedTradeData/Data node not found");
263 for (
auto const n : nodes) {
286 for (
auto const& n : sn) {
293 QL_FAIL(
"either Script or ScriptName expected");
302 if (
name.size() > 4 &&
name.substr(
name.size() - 4, 4) ==
"Data") {
303 QL_REQUIRE(!tradeDataNode,
"multiple child nodes xxxData found");
304 tradeDataNode = child;
309 QL_REQUIRE(tradeDataNode,
"expected ScriptedTradeData or xxxData node");
317 QL_REQUIRE(!type.empty(),
"no type given for node '" << varName <<
"'");
320 if (!scalarValue.empty()) {
322 auto native = getNativeTypeAndValue(scalarValue, type);
323 if (native.first == NodeType::Event) {
325 }
else if (native.first == NodeType::Number) {
327 }
else if (native.first == NodeType::Index) {
329 }
else if (native.first == NodeType::Currency) {
331 }
else if (native.first == NodeType::Daycounter) {
334 QL_FAIL(
"unexpected node type");
349 QL_REQUIRE(native.first != NodeType::Event,
"unexpected even array under node '" << varName <<
"'");
350 std::vector<std::string> arrayValues;
354 arrayValues.push_back(v.second);
356 if (native.first == NodeType::Number) {
358 }
else if (native.first == NodeType::Index) {
360 }
else if (native.first == NodeType::Currency) {
362 }
else if (native.first == NodeType::Daycounter) {
365 QL_FAIL(
"unexpected node type");
368 QL_FAIL(
"unexpected content under node '" << varName <<
"'");
383 XMLNode* n = s.second.toXML(doc);
404 const bool fallBackOnEmptyPurpose)
const {
405 auto s1 =
script_.find(purpose);
408 if (fallBackOnEmptyPurpose) {
413 QL_FAIL(
"ScriptedTrade::script(): script with purpose '"
414 << purpose <<
"' not found, fall back on empty purpose was " << std::boolalpha << fallBackOnEmptyPurpose);
433 QL_FAIL(
"Expected Value or ScheduleData node");
452 QL_FAIL(
"ScriptedTradeEventData::toXML(): unexpected ScriptedTradeEventData::Type");
480 QL_FAIL(
"Expected Value or Values node");
528 std::vector<std::string> attributes;
529 std::vector<std::string> values =
531 for (Size i = 0; i < values.size(); ++i) {
533 results_.push_back(std::make_pair(attributes[i].empty() ? values[i] : attributes[i], values[i]));
546 for (
auto const& n : calibrations) {
562 std::vector<std::string> values, attributes;
564 attributes.push_back(r.first);
565 values.push_back(r.second);
588 boost::replace_all(
code_,
"\r",
"");
590 boost::replace_all(
code_,
"\t",
" ");
603 scripts_ = std::move(d.scripts_);
608 const bool fallBackOnEmptyPurpose)
const {
609 auto s = scripts_.find(scriptName);
610 if (s != scripts_.end()) {
611 return s->second.second.find(purpose) != s->second.second.end() ||
612 (fallBackOnEmptyPurpose && has(scriptName,
"",
false));
618 const std::string& purpose,
619 const bool fallBackOnEmptyPurpose)
const {
620 auto s = scripts_.find(scriptName);
621 if (s != scripts_.end()) {
622 auto f = s->second.second.find(purpose);
623 if (f != s->second.second.end()) {
624 return std::make_pair(s->second.first, f->second);
625 }
else if (fallBackOnEmptyPurpose) {
626 auto f = s->second.second.find(
"");
627 if (f != s->second.second.end())
628 return std::make_pair(s->second.first, f->second);
631 QL_FAIL(
"ScriptedTradeScriptData::get(): script '" << scriptName <<
"' with purpose '" << purpose
632 <<
"' not found, fallBackOnEmptyPurpose was " << std::boolalpha
633 << fallBackOnEmptyPurpose);
639 std::set<std::string> loadedNames;
640 for (
auto c : childs) {
642 QL_REQUIRE(std::find(loadedNames.begin(), loadedNames.end(),
name) == loadedNames.end(),
643 "duplicate script with name '" <<
name <<
"'");
644 loadedNames.insert(
name);
646 scripts_[
name].first = productTag;
648 QL_REQUIRE(!sn.empty(),
"no node Script found for '" <<
name <<
"'");
653 scripts_[
name].second[purpose] = d;
654 TLOG(
"loaded script '" <<
name <<
"' (purpose='" << purpose <<
"', productTag='" << productTag <<
"')");
661 for (
auto& s : scripts_) {
665 for (
auto& t : s.second.second) {
666 XMLNode* n = t.second.toXML(doc);
675 boost::shared_lock<boost::shared_mutex> lock(mutex_);
680 boost::unique_lock<boost::shared_mutex> lock(mutex_);
685 boost::unique_lock<boost::shared_mutex> lock(mutex_);
686 data_ = std::move(
data);
690 boost::unique_lock<boost::shared_mutex> lock(mutex_);
std::string infName() const
QuantLib::ext::shared_ptr< ZeroInflationIndex > inf() const
QuantLib::ext::shared_ptr< EquityIndex2 > eq() const
std::string commName() const
Serializable object holding premium data.
void addZeroInflationFixingDate(const QuantLib::Date &fixingDate, const std::string &indexName, const bool indexInterpolated, const Frequency indexFrequency, const Period &indexAvailabilityLag, const CPI::InterpolationType coupopnInterpolation, const Frequency couponFrequency, const QuantLib::Date &payDate=Date::maxDate(), const bool alwaysAddIfPaysOnSettlement=false, const bool mandatoryFixing=true)
void addFixingDate(const QuantLib::Date &fixingDate, const std::string &indexName, const QuantLib::Date &payDate=Date::maxDate(), const bool alwaysAddIfPaysOnSettlement=false, const bool mandatoryFixing=true)
Serializable schedule data.
bool hasData() const
Check if has any dates/rules/derived schedules.
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
ScriptLibraryData & operator=(const ScriptLibraryData &d)
std::pair< std::string, ScriptedTradeScriptData > get(const std::string &scriptName, const std::string &purpose, const bool fallBackOnEmptyPurpose=true) const
std::map< std::string, std::pair< std::string, std::map< std::string, ScriptedTradeScriptData > > > scripts_
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(ore::data::XMLDocument &doc) const override
bool has(const std::string &scriptName, const std::string &purpose, const bool fallBackOnEmptyPurpose=true) const
void set(const ScriptLibraryData &data)
const ScriptLibraryData & get() const
virtual void fromXML(XMLNode *node) override
std::string baseSchedule_
virtual XMLNode * toXML(ore::data::XMLDocument &doc) const override
std::string notionalCurrency() const override
const std::map< std::string, ScriptedTradeScriptData > & script() const
std::vector< ScriptedTradeValueTypeData > daycounters_
std::vector< ScriptedTradeEventData > events_
const std::string & scriptName() const
std::vector< ScriptedTradeValueTypeData > currencies_
std::map< ore::data::AssetClass, std::set< std::string > > underlyingIndices(const QuantLib::ext::shared_ptr< ReferenceDataManager > &referenceDataManager=nullptr) const override
std::string scheduleProductClass_
QuantLib::Real notional() const override
Return the current notional in npvCurrency. See individual sub-classes for the precise definition.
void fromXML(XMLNode *node) override
XMLNode * toXML(ore::data::XMLDocument &doc) const override
std::vector< ScriptedTradeValueTypeData > indices_
virtual void setIsdaTaxonomyFields()
std::string simmProductClass_
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(ore::data::XMLDocument &doc) const override
std::vector< std::string > sourceSchedules_
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(ore::data::XMLDocument &doc) const override
std::vector< std::string > conditionalExpectationModelStates_
std::vector< CalibrationData > calibrationSpec_
std::vector< NewScheduleData > newSchedules_
std::vector< std::string > schedulesEligibleForCoarsening_
virtual void fromXML(XMLNode *node) override
std::vector< std::pair< std::string, std::string > > results_
virtual XMLNode * toXML(ore::data::XMLDocument &doc) const override
const std::vector< NewScheduleData > & newSchedules() const
std::vector< std::string > stickyCloseOutStates_
std::vector< std::string > values_
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(ore::data::XMLDocument &doc) const override
std::vector< bool > legPayers_
std::vector< string > legCurrencies_
std::vector< QuantLib::Leg > legs_
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_
Small XML Document wrapper class.
XMLNode * allocNode(const string &nodeName)
util functions that wrap rapidxml
static void addChildrenWithAttributes(XMLDocument &doc, XMLNode *n, const string &names, const string &name, const vector< T > &values, const string &attrName, const vector< string > &attrs)
static void addAttribute(XMLDocument &doc, XMLNode *node, const string &attrName, const string &attrValue)
static void addChildren(XMLDocument &doc, XMLNode *n, const string &names, const string &name, const vector< T > &values)
static string getAttribute(XMLNode *node, const string &attrName)
static void checkNode(XMLNode *n, const string &expectedName)
static vector< XMLNode * > getChildrenNodes(XMLNode *node, const string &name)
Returns all the children with a given name.
static void addChildAsCdata(XMLDocument &doc, XMLNode *n, const string &name, const string &value)
static string getNodeName(XMLNode *n)
Get and set a node's 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 string getNodeValue(XMLNode *node)
Get a node's value.
static XMLNode * getNextSibling(XMLNode *node, const string &name="")
Get a node's next sibling node.
static vector< string > getChildrenValuesWithAttributes(XMLNode *node, const string &names, const string &name, const string &attrName, vector< string > &attrs, bool mandatory=false)
static vector< string > getChildrenValues(XMLNode *node, const string &names, const string &name, bool mandatory=false)
static XMLNode * addChild(XMLDocument &doc, XMLNode *n, const string &name)
static void appendNode(XMLNode *parent, XMLNode *child)
SafeStack< ValueType > value
script engine context holding variable names and values
Currency parseCurrencyWithMinors(const string &s)
Convert text to QuantLib::Currency.
Map text representations to QuantLib/QuantExt types.
Classes and functions for log message handling.
#define DLOG(text)
Logging Macro (Level = Debug)
#define TLOG(text)
Logging Macro (Level = Data)
std::string inverseFxIndex(const std::string &indexName)
Serializable Credit Default Swap.
trade schedule data model and serialization
scripted instrument pricing engine
scripted trade data model