Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Public Member Functions | Private Attributes | List of all members
KnockOutSwap Class Reference

#include <ored/portfolio/knockoutswap.hpp>

+ Inheritance diagram for KnockOutSwap:
+ Collaboration diagram for KnockOutSwap:

Public Member Functions

 KnockOutSwap (const std::string &tradeType="KnockOutSwap")
 
 KnockOutSwap (const std::vector< LegData > &legData, const BarrierData &barrierData, const std::string &barrierStartDate)
 
void build (const QuantLib::ext::shared_ptr< EngineFactory > &) override
 
void fromXML (XMLNode *node) override
 
XMLNodetoXML (XMLDocument &doc) const override
 
- Public Member Functions inherited from ScriptedTrade
 ScriptedTrade (const std::string &tradeType="ScriptedTrade", const Envelope &env=Envelope())
 
 ScriptedTrade (const Envelope &env, const std::vector< ScriptedTradeEventData > &events, const std::vector< ScriptedTradeValueTypeData > &numbers, const std::vector< ScriptedTradeValueTypeData > &indices, const std::vector< ScriptedTradeValueTypeData > &currencies, const std::vector< ScriptedTradeValueTypeData > &daycounters, const std::map< std::string, ScriptedTradeScriptData > &script, const std::string &productTag, const std::string &tradeType="ScriptedTrade")
 
 ScriptedTrade (const Envelope &env, const std::vector< ScriptedTradeEventData > &events, const std::vector< ScriptedTradeValueTypeData > &numbers, const std::vector< ScriptedTradeValueTypeData > &indices, const std::vector< ScriptedTradeValueTypeData > &currencies, const std::vector< ScriptedTradeValueTypeData > &daycounters, const std::string &scriptName, const std::string &tradeType="ScriptedTrade")
 
void clear ()
 
void build (const QuantLib::ext::shared_ptr< EngineFactory > &) override
 
QuantLib::Real notional () const override
 Return the current notional in npvCurrency. See individual sub-classes for the precise definition. More...
 
std::string notionalCurrency () const override
 
void fromXML (XMLNode *node) override
 
XMLNodetoXML (ore::data::XMLDocument &doc) const override
 
void build (const QuantLib::ext::shared_ptr< EngineFactory > &engineFactory, const PremiumData &premiumData, const Real premiumMultiplier)
 
std::map< ore::data::AssetClass, std::set< std::string > > underlyingIndices (const QuantLib::ext::shared_ptr< ReferenceDataManager > &referenceDataManager=nullptr) const override
 
virtual void setIsdaTaxonomyFields ()
 
const std::vector< ScriptedTradeEventData > & events () const
 
const std::vector< ScriptedTradeValueTypeData > & numbers () const
 
const std::vector< ScriptedTradeValueTypeData > & indices () const
 
const std::vector< ScriptedTradeValueTypeData > & currencies () const
 
const std::vector< ScriptedTradeValueTypeData > & daycounters () const
 
const std::map< std::string, ScriptedTradeScriptData > & script () const
 
const std::string & productTag () const
 
const std::string & scriptName () const
 
const std::string & simmProductClass () const
 
const std::string & scheduleProductClass () const
 
const ScriptedTradeScriptDatascript (const std::string &purpose, const bool fallBackOnEmptyPurpose=true) const
 
- Public Member Functions inherited from Trade
 Trade ()
 Default constructor. More...
 
 Trade (const string &tradeType, const Envelope &env=Envelope(), const TradeActions &ta=TradeActions())
 Base class constructor. More...
 
virtual ~Trade ()
 Default destructor. More...
 
virtual void build (const QuantLib::ext::shared_ptr< EngineFactory > &)=0
 
virtual std::map< std::string, RequiredFixings::FixingDatesfixings (const QuantLib::Date &settlementDate=QuantLib::Date()) const
 
const RequiredFixingsrequiredFixings () const
 
virtual std::map< AssetClass, std::set< std::string > > underlyingIndices (const QuantLib::ext::shared_ptr< ReferenceDataManager > &referenceDataManager=nullptr) const
 
void reset ()
 Reset trade, clear all base class data. This does not reset accumulated timings for this trade. More...
 
void resetPricingStats (const std::size_t numberOfPricings=0, const boost::timer::nanosecond_type cumulativePricingTime=0)
 Reset accumulated timings to given values. More...
 
string & id ()
 Set the trade id. More...
 
void setEnvelope (const Envelope &envelope)
 Set the envelope with counterparty and portfolio info. More...
 
void setAdditionalData (const std::map< std::string, boost::any > &additionalData)
 
TradeActionstradeActions ()
 Set the trade actions. More...
 
const string & id () const
 
const string & tradeType () const
 
const Envelopeenvelope () const
 
const set< string > & portfolioIds () const
 
const TradeActionstradeActions () const
 
const QuantLib::ext::shared_ptr< InstrumentWrapper > & instrument () const
 
const std::vector< QuantLib::Leg > & legs () const
 
const std::vector< string > & legCurrencies () const
 
const std::vector< bool > & legPayers () const
 
const string & npvCurrency () const
 
const Date & maturity () const
 
virtual bool isExpired (const Date &d)
 
const string & issuer () const
 
template<typename T >
additionalDatum (const std::string &tag) const
 returns any additional datum. More...
 
virtual const std::map< std::string, boost::any > & additionalData () const
 returns all additional data returned by the trade once built More...
 
const std::string & sensitivityTemplate () const
 
void validate () const
 Utility to validate that everything that needs to be set in this base class is actually set. More...
 
virtual bool hasCashflows () const
 
boost::timer::nanosecond_type getCumulativePricingTime () const
 Get cumulative timing spent on pricing. More...
 
std::size_t getNumberOfPricings () const
 Get number of pricings. More...
 
- Public Member Functions inherited from XMLSerializable
virtual ~XMLSerializable ()
 
virtual void fromXML (XMLNode *node)=0
 
virtual XMLNodetoXML (XMLDocument &doc) const =0
 
void fromFile (const std::string &filename)
 
void toFile (const std::string &filename) const
 
void fromXMLString (const std::string &xml)
 Parse from XML string. More...
 
std::string toXMLString () const
 Parse from XML string. More...
 

Private Attributes

std::vector< LegDatalegData_
 
BarrierData barrierData_
 
std::string barrierStartDate_
 

Additional Inherited Members

- Protected Member Functions inherited from Trade
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 setLegBasedAdditionalData (const Size legNo, Size resultLegId=Null< Size >()) const
 
void setSensitivityTemplate (const EngineBuilder &builder)
 
void setSensitivityTemplate (const std::string &id)
 
- Protected Attributes inherited from ScriptedTrade
std::vector< ScriptedTradeEventDataevents_
 
std::vector< ScriptedTradeValueTypeDatanumbers_
 
std::vector< ScriptedTradeValueTypeDataindices_
 
std::vector< ScriptedTradeValueTypeDatacurrencies_
 
std::vector< ScriptedTradeValueTypeDatadaycounters_
 
std::map< std::string, ScriptedTradeScriptDatascript_
 
std::string productTag_
 
std::string scriptName_
 
std::string simmProductClass_
 
std::string scheduleProductClass_
 
- Protected Attributes inherited from Trade
string tradeType_
 
QuantLib::ext::shared_ptr< InstrumentWrapperinstrument_
 
std::vector< QuantLib::Leg > legs_
 
std::vector< string > legCurrencies_
 
std::vector< boollegPayers_
 
string npvCurrency_
 
QuantLib::Real notional_
 
string notionalCurrency_
 
Date maturity_
 
string issuer_
 
string sensitivityTemplate_
 
bool sensitivityTemplateSet_ = false
 
std::size_t savedNumberOfPricings_ = 0
 
boost::timer::nanosecond_type savedCumulativePricingTime_ = 0
 
RequiredFixings requiredFixings_
 
std::map< std::string, boost::any > additionalData_
 

Detailed Description

Definition at line 36 of file knockoutswap.hpp.

Constructor & Destructor Documentation

◆ KnockOutSwap() [1/2]

KnockOutSwap ( const std::string &  tradeType = "KnockOutSwap")
explicit

Definition at line 38 of file knockoutswap.hpp.

ScriptedTrade(const std::string &tradeType="ScriptedTrade", const Envelope &env=Envelope())
const string & tradeType() const
Definition: trade.hpp:133

◆ KnockOutSwap() [2/2]

KnockOutSwap ( const std::vector< LegData > &  legData,
const BarrierData barrierData,
const std::string &  barrierStartDate 
)

Definition at line 39 of file knockoutswap.hpp.

41 : legData_(legData), barrierData_(barrierData), barrierStartDate_(barrierStartDate) {}
std::vector< LegData > legData_
std::string barrierStartDate_

Member Function Documentation

◆ build()

void build ( const QuantLib::ext::shared_ptr< EngineFactory > &  )
overridevirtual

Build QuantLib/QuantExt instrument, link pricing engine. If build() is called multiple times, reset() should be called between these calls.

Implements Trade.

Definition at line 32 of file knockoutswap.cpp.

32 {
33
34 clear();
35
36 QL_REQUIRE(legData_.size() == 2, "Expected exactly two legs, got " << legData_.size());
37
38 std::set<std::string> legTypes;
39 for (auto const& ld : legData_) {
40 legTypes.insert(ld.legType());
41 }
42
43 QL_REQUIRE(legTypes.size() == 2 && *legTypes.begin() == "Fixed" && *std::next(legTypes.begin(), 1) == "Floating",
44 "Expected one 'Floating' and one 'Fixed' type");
45
46 const LegData& fixedLegData = legData_[0].legType() == "Fixed" ? legData_[0] : legData_[1];
47 const LegData& floatLegData = legData_[0].legType() == "Fixed" ? legData_[1] : legData_[0];
48
49 auto floatAddData = QuantLib::ext::dynamic_pointer_cast<FloatingLegData>(floatLegData.concreteLegData());
50 auto fixedAddData = QuantLib::ext::dynamic_pointer_cast<FixedLegData>(fixedLegData.concreteLegData());
51
52 QL_REQUIRE(floatAddData, "Internal error: could not cast to float additional data");
53 QL_REQUIRE(fixedAddData, "Internal error: could not cast to fixed additional data");
54
55 QL_REQUIRE(fixedLegData.isPayer() != floatLegData.isPayer(), "Expected one payer and one receiver leg");
56
57 if (fixedLegData.isPayer())
58 numbers_.emplace_back("Number", "Payer", "-1");
59 else
60 numbers_.emplace_back("Number", "Payer", "1");
61
62 QL_REQUIRE(fixedLegData.notionals().size() == 1,
63 "Expected one notional on fixed leg, got " << fixedLegData.notionals().size());
64 QL_REQUIRE(floatLegData.notionals().size() == 1,
65 "Expected one notional on floating leg, got " << floatLegData.notionals().size());
66 QL_REQUIRE(QuantLib::close_enough(fixedLegData.notionals().front(), floatLegData.notionals().front()),
67 "Expected same notional on fixed and floating leg, got " << fixedLegData.notionals().front() << " and "
68 << floatLegData.notionals().front());
69
70 QL_REQUIRE(fixedAddData->rates().size() == 1,
71 "Expected one rate on fixed leg, got " << fixedAddData->rates().size());
72 QL_REQUIRE(floatAddData->spreads().size() <= 1,
73 "Expected at most one spread on floating leg, got " << floatAddData->spreads().size());
74 QL_REQUIRE(floatAddData->gearings().size() <= 1,
75 "Expected at most one gearing on floating leg, got " << floatAddData->gearings().size());
76
77 numbers_.emplace_back("Number", "Notional", std::to_string(fixedLegData.notionals().front()));
78 numbers_.emplace_back("Number", "FixedRate", std::to_string(fixedAddData->rates().front()));
79 numbers_.emplace_back("Number", "FloatMargin",
80 floatAddData->spreads().empty() ? "0.0" : std::to_string(floatAddData->spreads().front()));
81 numbers_.emplace_back("Number", "FloatGearing",
82 floatAddData->gearings().empty() ? "1.0" : std::to_string(floatAddData->gearings().front()));
83
84 auto index = parseIborIndex(floatAddData->index());
85 Size fixingShift = floatAddData->fixingDays() == Null<Size>() ? index->fixingDays() : floatAddData->fixingDays();
86 std::string fixingCalendar = index->fixingCalendar().name();
87 events_.emplace_back("FloatFixingSchedule", "FloatSchedule", "-" + std::to_string(fixingShift) + "D", fixingCalendar, "P");
88
89 indices_.emplace_back("Index", "FloatIndex", floatAddData->index());
90
91 std::string floatDayCounter =
92 floatLegData.dayCounter().empty() ? index->dayCounter().name() : floatLegData.dayCounter();
93 std::string fixedDayCounter = fixedLegData.dayCounter().empty() ? floatDayCounter : fixedLegData.dayCounter();
94
95 daycounters_.emplace_back("Daycounter", "FixedDayCounter", fixedDayCounter);
96 daycounters_.emplace_back("Daycounter", "FloatDayCounter", floatDayCounter);
97
98 events_.emplace_back("FixedSchedule", fixedLegData.schedule());
99 events_.emplace_back("FloatSchedule", floatLegData.schedule());
100
101 QL_REQUIRE(!fixedLegData.currency().empty() && fixedLegData.currency() == floatLegData.currency(),
102 "Both legs must have the same currency, got '" << fixedLegData.currency() << "' on the fixed leg and '"
103 << floatLegData.currency() << "' on the floating leg.");
104 QL_REQUIRE(fixedLegData.currency() == index->currency().code(),
105 "Leg currency '" << fixedLegData.currency() << "' must match float index currency '"
106 << index->currency().code() << "' of index '" << index->name() << "'");
107
108 currencies_.emplace_back("Currency", "PayCurrency", fixedLegData.currency());
109
110 QL_REQUIRE(barrierData_.style().empty() || barrierData_.style() == "European",
111 "Expected European barrier style, got '" << barrierData_.style() << "'");
112
113 auto barrierType = parseBarrierType(barrierData_.type());
114 if (barrierType == QuantLib::Barrier::DownOut)
115 numbers_.emplace_back("Number", "KnockOutType", "3");
116 else if (barrierType == QuantLib::Barrier::UpOut)
117 numbers_.emplace_back("Number", "KnockOutType", "4");
118 else {
119 QL_FAIL("Expected BarrierType 'DownAndOut' or 'UpAndOut', got '" << barrierData_.type());
120 }
121
122 QL_REQUIRE(barrierData_.levels().size() == 1, "Expected exactly one barrier level");
123 QL_REQUIRE(barrierData_.levels().front().value() != Null<Real>(), "No barrier level specified.");
124
125 numbers_.emplace_back("Number", "KnockOutLevel", std::to_string(barrierData_.levels().front().value()));
126
127 events_.emplace_back("BarrierStartDate", barrierStartDate_);
128
129 // set product tag
130
131 productTag_ = "SingleUnderlyingIrOption";
132
133 // set script
134
135 bool isIborBased = QuantLib::ext::dynamic_pointer_cast<QuantLib::OvernightIndex>(index) == nullptr;
136
137 // clang-format off
138
139 // FloatFixingSchedule has one date more than needed at the back because it is derived from FloatSchedule
140 // there are two variants of the float payoff scripting depending on isIborBased
141
142 std::string mc_script = std::string(
143 "REQUIRE KnockOutType == 3 OR KnockOutType == 4;\n"
144 "NUMBER Alive[SIZE(FloatFixingSchedule)], aliveInd, lastFixedIndex, lastFloatIndex, d, j, fix;\n"
145
146 "aliveInd = 1;\n"
147
148 "FOR d IN (1, SIZE(FloatFixingSchedule), 1) DO\n"
149
150 " FOR j IN (lastFixedIndex + 1, SIZE(FixedSchedule) - 1, 1) DO\n"
151 " IF FixedSchedule[j] < FloatFixingSchedule[d] OR d == SIZE(FloatFixingSchedule) THEN\n"
152 " value = value + LOGPAY( Payer * aliveInd * Notional * FixedRate * dcf( FixedDayCounter, FixedSchedule[j], FixedSchedule[j+1]),\n"
153 " FixedSchedule[j], FixedSchedule[j+1], PayCurrency, 1, FixedLegCoupon );\n"
154 " lastFixedIndex = j;\n"
155 " END;\n"
156 " END;\n"
157
158 " FOR j IN (lastFloatIndex + 1, SIZE(FloatSchedule) - 1, 1) DO\n"
159 " IF FloatSchedule[j] < FloatFixingSchedule[d] OR d == SIZE(FloatFixingSchedule) THEN\n"
160 " value = value + LOGPAY( (-Payer) * aliveInd * Notional *\n") + std::string(
161 isIborBased ?
162 " ( FloatGearing * FloatIndex(FloatFixingSchedule[j]) + FloatMargin)\n"
163 :
164 " FWDCOMP(FloatIndex, FloatFixingSchedule[j], FloatSchedule[j], FloatSchedule[j+1], FloatMargin, FloatGearing)\n") + std::string(
165
166 " * dcf( FloatDayCounter, FloatSchedule[j], FloatSchedule[j+1]),\n"
167 " FloatFixingSchedule[j], FloatSchedule[j+1], PayCurrency, 2, FloatingLegCoupon );\n"
168 " lastFloatIndex = j;\n"
169 " END;\n"
170 " END;\n"
171
172 " IF d < SIZE(FloatFixingSchedule) THEN\n"
173 " fix = FloatIndex(FloatFixingSchedule[d]);\n"
174 " IF FloatFixingSchedule[d] >= BarrierStartDate AND\n"
175 " {{KnockOutType == 3 AND fix <= KnockOutLevel} OR\n"
176 " {KnockOutType == 4 AND fix >= KnockOutLevel}} THEN\n"
177 " aliveInd = 0;\n"
178 " END;\n"
179 " Alive[d] = aliveInd;\n"
180 " END;\n"
181
182 "END;\n");
183
184 // clang-format on
185
186 script_[""] = ScriptedTradeScriptData(
187 mc_script, "value", {{"currentNotional", "Notional"}, {"notionalCurrency", "PayCurrency"}, {"Alive", "Alive"}},
188 {}, {}, {}, {});
189
190 // build trade
191
192 ScriptedTrade::build(factory);
193}
const std::string & type() const
Definition: barrierdata.hpp:46
std::vector< ore::data::TradeBarrier > levels() const
Definition: barrierdata.hpp:50
const std::string & style() const
Definition: barrierdata.hpp:51
std::vector< ScriptedTradeValueTypeData > daycounters_
std::vector< ScriptedTradeEventData > events_
std::vector< ScriptedTradeValueTypeData > currencies_
std::vector< ScriptedTradeValueTypeData > indices_
std::vector< ScriptedTradeValueTypeData > numbers_
std::map< std::string, ScriptedTradeScriptData > script_
void build(const QuantLib::ext::shared_ptr< EngineFactory > &) override
QuantLib::ext::shared_ptr< IborIndex > parseIborIndex(const string &s, const Handle< YieldTermStructure > &h)
Convert std::string to QuantLib::IborIndex.
Barrier::Type parseBarrierType(const std::string &s)
Convert std::string to QuantLib::BarrierType.
Definition: parsers.cpp:1042
+ Here is the call graph for this function:

◆ fromXML()

void fromXML ( XMLNode node)
overridevirtual

Reimplemented from Trade.

Definition at line 195 of file knockoutswap.cpp.

195 {
196 Trade::fromXML(node);
197 XMLNode* dataNode = XMLUtils::getChildNode(node, tradeType() + "Data");
198 QL_REQUIRE(dataNode, tradeType() + "Data node not found");
199
200 barrierData_.fromXML(XMLUtils::getChildNode(dataNode, "BarrierData"));
201 barrierStartDate_ = XMLUtils::getChildValue(dataNode, "BarrierStartDate", true);
202
203 legData_.clear();
204 for (auto const n : XMLUtils::getChildrenNodes(dataNode, "LegData")) {
205 legData_.push_back(ore::data::LegData());
206 legData_.back().fromXML(n);
207 }
208}
virtual void fromXML(ore::data::XMLNode *node) override
Definition: barrierdata.cpp:25
Serializable object holding leg data.
Definition: legdata.hpp:844
virtual void fromXML(XMLNode *node) override
Definition: trade.cpp:34
static vector< XMLNode * > getChildrenNodes(XMLNode *node, const string &name)
Returns all the children with a given name.
Definition: xmlutils.cpp:428
static string getChildValue(XMLNode *node, const string &name, bool mandatory=false, const string &defaultValue=string())
Definition: xmlutils.cpp:277
static XMLNode * getChildNode(XMLNode *n, const string &name="")
Definition: xmlutils.cpp:387
rapidxml::xml_node< char > XMLNode
Definition: xmlutils.hpp:60
+ Here is the call graph for this function:

◆ toXML()

XMLNode * toXML ( XMLDocument doc) const
overridevirtual

Reimplemented from Trade.

Definition at line 210 of file knockoutswap.cpp.

210 {
211 XMLNode* node = Trade::toXML(doc);
212 XMLNode* dataNode = doc.allocNode(tradeType() + "Data");
214 XMLUtils::addChild(doc, dataNode, "BarrierStartDate", barrierStartDate_);
215 for (auto& ld : legData_) {
216 XMLUtils::appendNode(dataNode, ld.toXML(doc));
217 }
218 XMLUtils::appendNode(node, dataNode);
219 return node;
220}
virtual ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
Definition: barrierdata.cpp:49
virtual XMLNode * toXML(XMLDocument &doc) const override
Definition: trade.cpp:46
static XMLNode * addChild(XMLDocument &doc, XMLNode *n, const string &name)
Definition: xmlutils.cpp:181
static void appendNode(XMLNode *parent, XMLNode *child)
Definition: xmlutils.cpp:406
+ Here is the call graph for this function:

Member Data Documentation

◆ legData_

std::vector<LegData> legData_
private

Definition at line 47 of file knockoutswap.hpp.

◆ barrierData_

BarrierData barrierData_
private

Definition at line 48 of file knockoutswap.hpp.

◆ barrierStartDate_

std::string barrierStartDate_
private

Definition at line 49 of file knockoutswap.hpp.