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

Serializable risk participation agreement. More...

#include <ored/portfolio/riskparticipationagreement.hpp>

+ Inheritance diagram for RiskParticipationAgreement:
+ Collaboration diagram for RiskParticipationAgreement:

Public Member Functions

 RiskParticipationAgreement ()
 
 RiskParticipationAgreement (const ore::data::Envelope &env, const std::vector< ore::data::LegData > &underlying, const std::vector< ore::data::LegData > &protectionFee, const Real participationRate, const Date &protectionStart, const Date &protectionEnd, const std::string &creditCurveId, const std::string &issuerId="", const bool settlesAccrual=true, const Real fixedRecoveryRate=Null< Real >(), const boost::optional< ore::data::OptionData > &optionData=boost::none)
 Leg-based constructur, i.e. with Swap underyling. More...
 
 RiskParticipationAgreement (const ore::data::Envelope &env, const ore::data::TreasuryLockData &tlockData, const std::vector< ore::data::LegData > &protectionFee, const Real participationRate, const Date &protectionStart, const Date &protectionEnd, const std::string &creditCurveId, const std::string &issuerId="", const bool settlesAccrual=true, const Real fixedRecoveryRate=Null< Real >())
 
- 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
 
virtual QuantLib::Real notional () const
 Return the current notional in npvCurrency. See individual sub-classes for the precise definition. More...
 
virtual string notionalCurrency () 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...
 

Inspectors

std::vector< ore::data::LegDataunderlying_
 
ore::data::TreasuryLockData tlockData_
 
std::vector< ore::data::LegDataprotectionFee_
 
Real participationRate_
 
Date protectionStart_
 
Date protectionEnd_
 
std::string creditCurveId_
 
std::string issuerId_
 
bool settlesAccrual_
 
Real fixedRecoveryRate_
 
boost::optional< ore::data::OptionDataoptionData_
 
bool nakedOption_
 
const std::vector< ore::data::LegData > & underlying () const
 
const boost::optional< ore::data::OptionData > & optionData () const
 
const ore::data::TreasuryLockDatatlockData () const
 
const std::vector< ore::data::LegData > & protectionFee () const
 
Real participationRate () const
 
const Date & protectionStart () const
 
const Date & protectionEnd () const
 
const std::string & creditCurveId () const
 
const std::string & issuerId () const
 
bool settlesAccrual () const
 
Real fixedRecoveryRate () const
 
void build (const QuantLib::ext::shared_ptr< ore::data::EngineFactory > &) override
 
virtual void fromXML (ore::data::XMLNode *node) override
 
virtual ore::data::XMLNodetoXML (ore::data::XMLDocument &doc) const override
 
void buildWithSwapUnderlying (const QuantLib::ext::shared_ptr< ore::data::EngineFactory > &engineFactory)
 
void buildWithTlockUnderlying (const QuantLib::ext::shared_ptr< ore::data::EngineFactory > &engineFactory)
 

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 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

Serializable risk participation agreement.

Definition at line 42 of file riskparticipationagreement.hpp.

Constructor & Destructor Documentation

◆ RiskParticipationAgreement() [1/3]

Definition at line 44 of file riskparticipationagreement.hpp.

44: Trade("RiskParticipationAgreement") {}
Trade()
Default constructor.
Definition: trade.hpp:59

◆ RiskParticipationAgreement() [2/3]

RiskParticipationAgreement ( const ore::data::Envelope env,
const std::vector< ore::data::LegData > &  underlying,
const std::vector< ore::data::LegData > &  protectionFee,
const Real  participationRate,
const Date &  protectionStart,
const Date &  protectionEnd,
const std::string &  creditCurveId,
const std::string &  issuerId = "",
const bool  settlesAccrual = true,
const Real  fixedRecoveryRate = Null<Real>(),
const boost::optional< ore::data::OptionData > &  optionData = boost::none 
)

Leg-based constructur, i.e. with Swap underyling.

Definition at line 46 of file riskparticipationagreement.hpp.

52 : Trade("RiskParticipationAgreement", env), underlying_(underlying), tlockData_(ore::data::TreasuryLockData()),
54 protectionEnd_(protectionEnd), creditCurveId_(creditCurveId), issuerId_(issuerId),
const std::vector< Leg > & underlying() const
const std::vector< Leg > underlying_
const std::vector< Leg > protectionFee_
const std::vector< Leg > & protectionFee() const
const Date & protectionEnd() const
const Date & protectionStart() const
boost::optional< ore::data::OptionData > optionData_
+ Here is the call graph for this function:

◆ RiskParticipationAgreement() [3/3]

RiskParticipationAgreement ( const ore::data::Envelope env,
const ore::data::TreasuryLockData tlockData,
const std::vector< ore::data::LegData > &  protectionFee,
const Real  participationRate,
const Date &  protectionStart,
const Date &  protectionEnd,
const std::string &  creditCurveId,
const std::string &  issuerId = "",
const bool  settlesAccrual = true,
const Real  fixedRecoveryRate = Null<Real>() 
)

Definition at line 57 of file riskparticipationagreement.hpp.

+ Here is the call graph for this function:

Member Function Documentation

◆ underlying()

const std::vector< ore::data::LegData > & underlying ( ) const

Definition at line 69 of file riskparticipationagreement.hpp.

69{ return underlying_; }

◆ optionData()

const boost::optional< ore::data::OptionData > & optionData ( ) const

Definition at line 70 of file riskparticipationagreement.hpp.

70{ return optionData_; }
+ Here is the caller graph for this function:

◆ tlockData()

const ore::data::TreasuryLockData & tlockData ( ) const

Definition at line 71 of file riskparticipationagreement.hpp.

71{ return tlockData_; }

◆ protectionFee()

const std::vector< ore::data::LegData > & protectionFee ( ) const

Definition at line 72 of file riskparticipationagreement.hpp.

72{ return protectionFee_; }

◆ participationRate()

Real participationRate ( ) const

Definition at line 73 of file riskparticipationagreement.hpp.

73{ return participationRate_; }

◆ protectionStart()

const Date & protectionStart ( ) const

Definition at line 74 of file riskparticipationagreement.hpp.

74{ return protectionStart_; }

◆ protectionEnd()

const Date & protectionEnd ( ) const

Definition at line 75 of file riskparticipationagreement.hpp.

75{ return protectionEnd_; }

◆ creditCurveId()

const std::string & creditCurveId ( ) const

Definition at line 76 of file riskparticipationagreement.hpp.

76{ return creditCurveId_; }

◆ issuerId()

const std::string & issuerId ( ) const

Definition at line 77 of file riskparticipationagreement.hpp.

77{ return issuerId_; }
+ Here is the caller graph for this function:

◆ settlesAccrual()

bool settlesAccrual ( ) const

Definition at line 78 of file riskparticipationagreement.hpp.

78{ return settlesAccrual_; }

◆ fixedRecoveryRate()

Real fixedRecoveryRate ( ) const

Definition at line 79 of file riskparticipationagreement.hpp.

79{ return fixedRecoveryRate_; }

◆ build()

void build ( const QuantLib::ext::shared_ptr< ore::data::EngineFactory > &  )
override

Definition at line 37 of file riskparticipationagreement.cpp.

37 {
38
39 LOG("RiskParticipationAgreement::build() for id \"" << id() << "\" called.");
40
41 // ISDA taxonomy
42 additionalData_["isdaAssetClass"] = string("Interest Rate");
43 additionalData_["isdaBaseProduct"] = string("Exotic");
44 additionalData_["isdaSubProduct"] = string("");
45 additionalData_["isdaTransaction"] = string("");
46
47 // do some checks
48
49 QL_REQUIRE(!protectionFee_.empty(), "protection fees must not be empty");
50
51 QL_REQUIRE(underlying_.empty() || tlockData_.empty(),
52 "RiskParticipationAgreement::build(): both LegData and TreasuryLockData given in Underlying node.");
53
54 if (!underlying_.empty())
55 buildWithSwapUnderlying(engineFactory);
56 else if (!tlockData_.empty())
57 buildWithTlockUnderlying(engineFactory);
58 else {
59 QL_FAIL("RiskParticipationAgreement::build(): Underlying node must not be empty, LegData or TreasuryLockData "
60 "required as subnode");
61 }
62
63 // set start date
65}
void buildWithSwapUnderlying(const QuantLib::ext::shared_ptr< ore::data::EngineFactory > &engineFactory)
void buildWithTlockUnderlying(const QuantLib::ext::shared_ptr< ore::data::EngineFactory > &engineFactory)
std::map< std::string, boost::any > additionalData_
Definition: trade.hpp:224
#define LOG(text)
Logging Macro (Level = Notice)
Definition: log.hpp:552
std::string to_string(const LocationInfo &l)
Definition: ast.cpp:28
+ Here is the call graph for this function:

◆ fromXML()

void fromXML ( ore::data::XMLNode node)
overridevirtual

Reimplemented from Trade.

Definition at line 298 of file riskparticipationagreement.cpp.

298 {
299 Trade::fromXML(node);
300 XMLNode* n = XMLUtils::getChildNode(node, "RiskParticipationAgreementData");
301 QL_REQUIRE(n, "RiskParticipationAgreement::fromXML(): RiskParticipationAgreementData not found");
302 participationRate_ = XMLUtils::getChildValueAsDouble(n, "ParticipationRate", true);
303 protectionStart_ = parseDate(XMLUtils::getChildValue(n, "ProtectionStart", true));
304 protectionEnd_ = parseDate(XMLUtils::getChildValue(n, "ProtectionEnd", true));
305 creditCurveId_ = XMLUtils::getChildValue(n, "CreditCurveId", true);
306 issuerId_ = XMLUtils::getChildValue(n, "IssuerId", false); // defaults to empty string
307 settlesAccrual_ = XMLUtils::getChildValueAsBool(n, "SettlesAccrual", false); // defaults to true
308 tryParseReal(XMLUtils::getChildValue(n, "FixedRecoveryRate"), fixedRecoveryRate_); // defaults to null
309
310 underlying_.clear();
311 XMLNode* u = XMLUtils::getChildNode(n, "Underlying");
312 QL_REQUIRE(u, "RiskParticipationAgreement::fromXML(): Underlying not found");
313
314 vector<XMLNode*> nodes = XMLUtils::getChildrenNodes(u, "LegData");
315 for (auto const n : nodes) {
316 LegData ld;
317 ld.fromXML(n);
318 underlying_.push_back(ld);
319 }
320
321 if (auto tmp = XMLUtils::getChildNode(u, "OptionData")) {
322 optionData_ = OptionData();
323 (*optionData_).fromXML(tmp);
324 }
325
326 nakedOption_ = XMLUtils::getChildValueAsBool(u, "NakedOption", false, false);
327
328 if (auto tmp = XMLUtils::getChildNode(u, "TreasuryLockData")) {
329 tlockData_.fromXML(tmp);
330 }
331
332 protectionFee_.clear();
333 XMLNode* p = XMLUtils::getChildNode(n, "ProtectionFee");
334 QL_REQUIRE(p, "RiskParticipationAgreement::fromXML(): ProtectionFee not found");
335 vector<XMLNode*> nodes2 = XMLUtils::getChildrenNodes(p, "LegData");
336 for (auto const n : nodes2) {
337 LegData ld; // we do not allow ORE+ leg types anyway
338 ld.fromXML(n);
339 protectionFee_.push_back(ld);
340 }
341}
virtual void fromXML(XMLNode *node) override
XMLSerializable interface.
Definition: tlockdata.cpp:30
bool tryParseReal(const string &s, QuantLib::Real &result)
Attempt to convert text to Real.
Definition: parsers.cpp:126
Date parseDate(const string &s)
Convert std::string to QuantLib::Date.
Definition: parsers.cpp:51
rapidxml::xml_node< char > XMLNode
Definition: xmlutils.hpp:60
+ Here is the call graph for this function:

◆ toXML()

XMLNode * toXML ( ore::data::XMLDocument doc) const
overridevirtual

Reimplemented from Trade.

Definition at line 343 of file riskparticipationagreement.cpp.

343 {
344 XMLNode* node = Trade::toXML(doc);
345 XMLNode* n = doc.allocNode("RiskParticipationAgreementData");
346 XMLUtils::appendNode(node, n);
347 XMLUtils::addChild(doc, n, "ParticipationRate", participationRate_);
348 XMLUtils::addChild(doc, n, "ProtectionStart", ore::data::to_string(protectionStart_));
349 XMLUtils::addChild(doc, n, "ProtectionEnd", ore::data::to_string(protectionEnd_));
350 XMLUtils::addChild(doc, n, "CreditCurveId", creditCurveId_);
351 XMLUtils::addChild(doc, n, "IssuerId", issuerId_);
352 XMLUtils::addChild(doc, n, "SettlesAccrual", settlesAccrual_);
353 if (fixedRecoveryRate_ != Null<Real>())
354 XMLUtils::addChild(doc, n, "FixedRecoveryRate", fixedRecoveryRate_);
355 XMLNode* p = doc.allocNode("ProtectionFee");
356 XMLNode* u = doc.allocNode("Underlying");
357 XMLUtils::appendNode(n, p);
358 XMLUtils::appendNode(n, u);
359 if (optionData_)
360 XMLUtils::appendNode(u, (*optionData_).toXML(doc));
361 if (nakedOption_)
362 XMLUtils::addChild(doc, n, "NakedOption", nakedOption_);
363 for (auto& l : protectionFee_)
364 XMLUtils::appendNode(p, l.toXML(doc));
365 for (auto& l : underlying_)
366 XMLUtils::appendNode(u, l.toXML(doc));
367 if (!tlockData_.empty()) {
368 XMLUtils::appendNode(u, tlockData_.toXML(doc));
369 }
370 return node;
371}
virtual XMLNode * toXML(XMLDocument &doc) const override
Definition: tlockdata.cpp:44
XMLNode * allocNode(const string &nodeName)
util functions that wrap rapidxml
Definition: xmlutils.cpp:132
+ Here is the call graph for this function:

◆ buildWithSwapUnderlying()

void buildWithSwapUnderlying ( const QuantLib::ext::shared_ptr< ore::data::EngineFactory > &  engineFactory)
private

Definition at line 67 of file riskparticipationagreement.cpp.

67 {
68 npvCurrency_ = notionalCurrency_ = underlying_.front().currency();
69
70 bool isXccy = false;
71 for (auto const& u : underlying_) {
72 isXccy = isXccy || u.currency() != npvCurrency_;
73 }
74
75 for (auto const& p : protectionFee_)
76 QL_REQUIRE(p.isPayer() == protectionFee_.front().isPayer(),
77 "the protection fee legs must all be pay or all receive");
78
79 /* determine product variant used to retrieve engine builder
80
81 RiskParticipationAgreement_Vanilla:
82 - exactly one fixed and one floating leg with opposite payer flags
83 - only fixed, ibor, ois (comp, avg) coupons allowed, no cap / floors, no in arrears fixings for ibor
84
85 RiskParticipationAgreement_Structured:
86 - arbitrary number of fixed, floating, cashflow legs
87 - only fixed, ibor coupons, ois (comp, avg), simple cashflows allowed, but possibly capped / floored,
88 as naked option, with in arrears fixing for ibor
89 - with optionData (i.e. callable underlying), as naked option (i.e. swaption)
90
91 RiskParticipationAgreement_Vanilla_XCcy:
92 - two legs in different currencies with arbitrary coupons allowed, no optionData though
93 */
94
95 std::set<std::string> legTypes;
96 std::set<bool> legPayers;
97 bool hasCapFloors = false, hasIborInArrears = false;
98 for (auto const& l : underlying_) {
99 QL_REQUIRE(l.legType() == "Fixed" || l.legType() == "Floating" || l.legType() == "Cashflow",
100 "RiskParticipationAgreement: leg type " << l.legType()
101 << " not supported, expected Fixed, Floating, Cashflow");
102 legTypes.insert(l.legType());
103 legPayers.insert(l.isPayer());
104 if (auto c = QuantLib::ext::dynamic_pointer_cast<FloatingLegData>(l.concreteLegData())) {
105 hasCapFloors = hasCapFloors || !c->caps().empty();
106 hasCapFloors = hasCapFloors || !c->floors().empty();
107 hasIborInArrears = hasIborInArrears || (c->isInArrears() && !isOvernightIndex(c->index()));
108 }
109 }
110
111 std::string productVariant;
112 if (isXccy) {
113 productVariant = "RiskParticipationAgreement_Vanilla_XCcy";
114 QL_REQUIRE(!optionData_, "XCcy Risk Participation Agreement does not allow for OptionData");
115 } else if (underlying_.size() == 2 &&
116 (legTypes == std::set<std::string>{"Fixed", "Floating"} ||
117 legTypes == std::set<std::string>{"Cashflow", "Floating"}) &&
118 legPayers == std::set<bool>{false, true} && !hasCapFloors && !hasIborInArrears && !optionData_) {
119 productVariant = "RiskParticipationAgreement_Vanilla";
120 } else {
121 productVariant = "RiskParticipationAgreement_Structured";
122 }
123
124 // get engine builder
125
126 DLOG("get engine builder for product variant " << productVariant);
127 auto builder = QuantLib::ext::dynamic_pointer_cast<RiskParticipationAgreementEngineBuilderBase>(
128 engineFactory->builder(productVariant));
129 QL_REQUIRE(builder, "wrong builder, expected RiskParticipationAgreementEngineBuilderBase");
130 auto configuration = builder->configuration(MarketContext::pricing);
131
132 // build underlying legs and protection fee legs
133
134 std::vector<Leg> underlyingLegs, protectionFeeLegs;
135 std::vector<bool> underlyingPayer, protectionPayer;
136 std::vector<string> underlyingCcys, protectionCcys;
137 for (auto const& l : underlying_) {
138 auto legBuilder = engineFactory->legBuilder(l.legType());
139 underlyingLegs.push_back(legBuilder->buildLeg(l, engineFactory, requiredFixings_, configuration));
140 underlyingPayer.push_back(l.isPayer());
141 underlyingCcys.push_back(l.currency());
142 auto leg = buildNotionalLeg(l, underlyingLegs.back(), requiredFixings_, engineFactory->market(), configuration);
143 if (!leg.empty()) {
144 underlyingLegs.push_back(leg);
145 underlyingPayer.push_back(l.isPayer());
146 underlyingCcys.push_back(l.currency());
147 }
148 }
149 for (auto const& l : protectionFee_) {
150 auto legBuilder = engineFactory->legBuilder(l.legType());
151 protectionFeeLegs.push_back(legBuilder->buildLeg(l, engineFactory, requiredFixings_, configuration));
152 protectionPayer.push_back(l.isPayer());
153 protectionCcys.push_back(protectionFeeLegs.back().empty() ? npvCurrency_ : l.currency());
154 }
155
156 // build exercise, if option data is present
157
158 QuantLib::ext::shared_ptr<QuantLib::Exercise> exercise;
159 bool exerciseIsLong = true;
160 std::vector<QuantLib::ext::shared_ptr<CashFlow>> vectorPremium;
161 if (optionData_) {
162 ExerciseBuilder eb(*optionData_, underlyingLegs);
163 exercise = eb.exercise();
164 exerciseIsLong = parsePositionType((*optionData_).longShort()) == QuantLib::Position::Long;
165 for (const auto& premium : (*optionData_).premiumData().premiumData()) {
166 QL_REQUIRE((premium.ccy == underlyingCcys[0]) && (premium.ccy == underlyingCcys[1]),
167 "premium currency must be the same than the swaption legs");
168 vectorPremium.push_back(QuantLib::ext::make_shared<SimpleCashFlow>(premium.amount, premium.payDate));
169 }
170 }
171
172 // build ql instrument
173
174 auto qleInstr = QuantLib::ext::make_shared<QuantExt::RiskParticipationAgreement>(
175 underlyingLegs, underlyingPayer, underlyingCcys, protectionFeeLegs, protectionPayer.front(), protectionCcys,
177 exerciseIsLong, vectorPremium, nakedOption_);
178
179 // wrap instrument
180
181 instrument_ = QuantLib::ext::make_shared<VanillaInstrument>(qleInstr);
182
183 // set trade members
184
185 notional_ = 0.0;
186 for (Size i = 0; i < underlyingLegs.size(); ++i) {
187 notional_ = std::max(notional_, currentNotional(underlyingLegs[i]) *
188 engineFactory->market()
189 ->fxRate(underlyingCcys[i] + notionalCurrency_,
190 engineFactory->configuration(MarketContext::pricing))
191 ->value());
192 }
193 legs_ = underlyingLegs;
196 legs_.insert(legs_.end(), protectionFeeLegs.begin(), protectionFeeLegs.end());
197 legCurrencies_.insert(legCurrencies_.end(), protectionCcys.begin(), protectionCcys.end());
198 legPayers_.insert(legPayers_.end(), protectionPayer.begin(), protectionPayer.end());
199 maturity_ = qleInstr->maturity();
200
201 // set pricing engine
202 qleInstr->setPricingEngine(builder->engine(id(), this));
203 setSensitivityTemplate(*builder);
204}
const boost::shared_ptr< Exercise > & exercise() const
const std::vector< std::string > & underlyingCcys() const
const std::vector< bool > & underlyingPayer() const
string npvCurrency_
Definition: trade.hpp:201
std::vector< bool > legPayers_
Definition: trade.hpp:200
std::vector< string > legCurrencies_
Definition: trade.hpp:199
std::vector< QuantLib::Leg > legs_
Definition: trade.hpp:198
QuantLib::Real notional_
Definition: trade.hpp:202
void setSensitivityTemplate(const EngineBuilder &builder)
Definition: trade.cpp:295
const std::vector< bool > & legPayers() const
Definition: trade.hpp:147
QuantLib::ext::shared_ptr< InstrumentWrapper > instrument_
Definition: trade.hpp:197
string notionalCurrency_
Definition: trade.hpp:203
bool isOvernightIndex(const string &indexName)
Return true if the indexName is that of an overnight index, otherwise false.
Position::Type parsePositionType(const std::string &s)
Convert text to QuantLib::Position::Type.
Definition: parsers.cpp:404
#define DLOG(text)
Logging Macro (Level = Debug)
Definition: log.hpp:554
Real currentNotional(const Leg &leg)
Definition: legdata.cpp:2435
Leg buildNotionalLeg(const LegData &data, const Leg &leg, RequiredFixings &requiredFixings, const QuantLib::ext::shared_ptr< Market > &market, const std::string &configuration)
Definition: legdata.cpp:2729
+ Here is the call graph for this function:

◆ buildWithTlockUnderlying()

void buildWithTlockUnderlying ( const QuantLib::ext::shared_ptr< ore::data::EngineFactory > &  engineFactory)
private

Definition at line 220 of file riskparticipationagreement.cpp.

220 {
221 std::string productVariant = "RiskParticipationAgreement_TLock";
222
223 // get bond reference data and build bond
224
226 tlockData_.bondData().populateFromBondReferenceData(engineFactory->referenceData());
227 ore::data::Bond tmp(Envelope(), tlockData_.bondData());
228 tmp.build(engineFactory);
229 auto bond = QuantLib::ext::dynamic_pointer_cast<QuantLib::Bond>(tmp.instrument()->qlInstrument());
230 QL_REQUIRE(bond != nullptr, "RiskParticipationAgreement: could not build tlock underlying, cast failed (internal "
231 "error that dev needs to look at)");
232
233 // set currency and notional
234
237
238 // checks
239
240 for (auto const& p : protectionFee_)
241 QL_REQUIRE(p.isPayer() == protectionFee_.front().isPayer(),
242 "the protection fee legs must all be pay or all receive");
243
244 // get engine builder
245
246 DLOG("get engine builder for product variant " << productVariant);
247 auto builder = QuantLib::ext::dynamic_pointer_cast<RiskParticipationAgreementEngineBuilderBase>(
248 engineFactory->builder(productVariant));
249 QL_REQUIRE(builder, "wrong builder, expected RiskParticipationAgreementEngineBuilderBase");
250 auto configuration = builder->configuration(MarketContext::pricing);
251
252 // build ql instrument and set the pricing engine
253
254 bool payer = tlockData_.payer();
255 Real referenceRate = tlockData_.referenceRate();
256 DayCounter dayCounter =
257 tlockData_.dayCounter().empty() ? getDayCounter(bond->cashflows()) : parseDayCounter(tlockData_.dayCounter());
258 Date terminationDate = parseDate(tlockData_.terminationDate());
259 Size paymentGap = tlockData_.paymentGap();
260 Calendar paymentCalendar = parseCalendar(tlockData_.paymentCalendar());
261
262 std::vector<Leg> protectionFeeLegs;
263 std::vector<bool> protectionPayer;
264 std::vector<string> protectionCcys;
265 for (auto const& l : protectionFee_) {
266 auto legBuilder = engineFactory->legBuilder(l.legType());
267 protectionFeeLegs.push_back(legBuilder->buildLeg(l, engineFactory, requiredFixings_, configuration));
268 protectionPayer.push_back(l.isPayer());
269 protectionCcys.push_back(protectionFeeLegs.back().empty() ? npvCurrency_ : l.currency());
270 }
271
272 Date paymentDate = paymentCalendar.advance(terminationDate, paymentGap * Days);
273 auto qleInstr = QuantLib::ext::make_shared<QuantExt::RiskParticipationAgreementTLock>(
274 bond, notional_, payer, referenceRate, dayCounter, terminationDate, paymentDate, protectionFeeLegs,
275 protectionPayer.front(), protectionCcys, participationRate_, protectionStart_, protectionEnd_, settlesAccrual_,
277
278 // wrap instrument
279
280 instrument_ = QuantLib::ext::make_shared<VanillaInstrument>(qleInstr);
281
282 // set trade members
283
284 legs_ = {bond->cashflows()};
286 legPayers_ = {payer};
287 legs_.insert(legs_.end(), protectionFeeLegs.begin(), protectionFeeLegs.end());
288 legCurrencies_.insert(legCurrencies_.end(), protectionCcys.begin(), protectionCcys.end());
289 legPayers_.insert(legPayers_.end(), protectionPayer.begin(), protectionPayer.end());
290 maturity_ = qleInstr->maturity();
291
292 // set pricing engine
293
294 qleInstr->setPricingEngine(builder->engine(id(), this));
295 setSensitivityTemplate(*builder);
296}
const string & currency() const
Definition: bond.hpp:94
void populateFromBondReferenceData(const QuantLib::ext::shared_ptr< BondReferenceDatum > &referenceDatum, const std::string &startDate="", const std::string &endDate="")
populate data from reference datum and check data for completeness
Definition: bond.cpp:175
Real bondNotional() const
Definition: bond.hpp:95
Serializable Bond.
Definition: bond.hpp:153
const string & dayCounter() const
Definition: tlockdata.hpp:55
const string & terminationDate() const
Definition: tlockdata.hpp:56
const string & paymentCalendar() const
Definition: tlockdata.hpp:58
const BondData & originalBondData() const
Definition: tlockdata.hpp:53
Calendar parseCalendar(const string &s)
Convert text to QuantLib::Calendar.
Definition: parsers.cpp:157
DayCounter parseDayCounter(const string &s)
Convert text to QuantLib::DayCounter.
Definition: parsers.cpp:209
+ Here is the call graph for this function:

Member Data Documentation

◆ underlying_

std::vector<ore::data::LegData> underlying_
private

Definition at line 90 of file riskparticipationagreement.hpp.

◆ tlockData_

ore::data::TreasuryLockData tlockData_
private

Definition at line 91 of file riskparticipationagreement.hpp.

◆ protectionFee_

std::vector<ore::data::LegData> protectionFee_
private

Definition at line 92 of file riskparticipationagreement.hpp.

◆ participationRate_

Real participationRate_
private

Definition at line 93 of file riskparticipationagreement.hpp.

◆ protectionStart_

Date protectionStart_
private

Definition at line 94 of file riskparticipationagreement.hpp.

◆ protectionEnd_

Date protectionEnd_
private

Definition at line 94 of file riskparticipationagreement.hpp.

◆ creditCurveId_

std::string creditCurveId_
private

Definition at line 95 of file riskparticipationagreement.hpp.

◆ issuerId_

std::string issuerId_
private

Definition at line 95 of file riskparticipationagreement.hpp.

◆ settlesAccrual_

bool settlesAccrual_
private

Definition at line 96 of file riskparticipationagreement.hpp.

◆ fixedRecoveryRate_

Real fixedRecoveryRate_
private

Definition at line 97 of file riskparticipationagreement.hpp.

◆ optionData_

boost::optional<ore::data::OptionData> optionData_
private

Definition at line 98 of file riskparticipationagreement.hpp.

◆ nakedOption_

bool nakedOption_
private

Definition at line 99 of file riskparticipationagreement.hpp.