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

Serializable Bond-Basket Data. More...

#include <ored/portfolio/bondbasket.hpp>

+ Inheritance diagram for BondBasket:
+ Collaboration diagram for BondBasket:

Public Member Functions

 BondBasket ()
 Default constructor. 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...
 

Serialisation

vector< QuantLib::ext::shared_ptr< Bond > > bonds_
 
std::map< string, QuantLib::ext::shared_ptr< QuantExt::FxIndex > > fxIndexMap_
 
RequiredFixings requiredFixings_
 
QuantLib::Date reinvestment_
 
std::map< std::string, std::vector< double > > reinvestmentScalar_
 
std::map< std::string, std::vector< std::string > > flowType_
 
virtual void fromXML (XMLNode *node) override
 
virtual XMLNodetoXML (ore::data::XMLDocument &doc) const override
 
std::map< AssetClass, std::set< std::string > > underlyingIndices (const QuantLib::ext::shared_ptr< ReferenceDataManager > &referenceDataManager=nullptr) const
 Add underlying Bond names. More...
 
bool empty ()
 
void clear ()
 
QuantLib::ext::shared_ptr< QuantExt::BondBasketbuild (const QuantLib::ext::shared_ptr< EngineFactory > &engineFactory, const QuantLib::Currency &ccy, const std::string &reinvestmentEndDate)
 
const std::vector< QuantLib::ext::shared_ptr< Bond > > & bonds () const
 
const RequiredFixingsrequiredFixings () const
 
bool isFeeFlow (const ext::shared_ptr< QuantLib::CashFlow > &cf, const std::string &name)
 
void setReinvestmentScalar ()
 

Detailed Description

Serializable Bond-Basket Data.

Definition at line 48 of file bondbasket.hpp.

Constructor & Destructor Documentation

◆ BondBasket()

Default constructor.

Definition at line 51 of file bondbasket.hpp.

51{}

Member Function Documentation

◆ fromXML()

void fromXML ( XMLNode node)
overridevirtual

Implements XMLSerializable.

Definition at line 261 of file bondbasket.cpp.

261 {
262
263 clear();
264
265 XMLUtils::checkNode(node, "BondBasketData");
266 bonds_.clear();
267 for (XMLNode* child = XMLUtils::getChildNode(node, "Trade"); child; child = XMLUtils::getNextSibling(child)) {
268 string id = XMLUtils::getAttribute(child, "id");
269 auto bonddata = QuantLib::ext::make_shared<ore::data::Bond>();
270 bonddata->fromXML(child);
271 bonddata->id() = id;
272 bonds_.push_back(bonddata);
273 }
274}
vector< QuantLib::ext::shared_ptr< Bond > > bonds_
Definition: bondbasket.hpp:78

◆ toXML()

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

Implements XMLSerializable.

Definition at line 276 of file bondbasket.cpp.

276 {
277 XMLNode* node = doc.allocNode("BondBasketData");
278 for (Size i = 0; i < bonds_.size(); i++) {
279 XMLUtils::appendNode(node, bonds_[i]->toXML(doc));
280 }
281 return node;
282}
virtual XMLNode * toXML(ore::data::XMLDocument &doc) const override
Definition: bondbasket.cpp:276
XMLNode * allocNode(const string &nodeName)
util functions that wrap rapidxml
Definition: xmlutils.cpp:132
rapidxml::xml_node< char > XMLNode
Definition: xmlutils.hpp:60
+ Here is the call graph for this function:

◆ underlyingIndices()

std::map< AssetClass, std::set< std::string > > underlyingIndices ( const QuantLib::ext::shared_ptr< ReferenceDataManager > &  referenceDataManager = nullptr) const

Add underlying Bond names.

Definition at line 284 of file bondbasket.cpp.

284 {
285 std::map<AssetClass, std::set<std::string>> result;
286 result[AssetClass::BOND] = {};
287 for ( auto b : bonds_)
288 result[AssetClass::BOND].insert(b->bondData().securityId());
289 return result;
290}

◆ empty()

bool empty ( )

Definition at line 62 of file bondbasket.hpp.

62{ return bonds_.empty(); }

◆ clear()

void clear ( )

Definition at line 256 of file bondbasket.cpp.

256 {
257
258 bonds_.clear();
259}

◆ build()

QuantLib::ext::shared_ptr< QuantExt::BondBasket > build ( const QuantLib::ext::shared_ptr< EngineFactory > &  engineFactory,
const QuantLib::Currency &  ccy,
const std::string &  reinvestmentEndDate 
)

Definition at line 56 of file bondbasket.cpp.

58 {
59 DLOG("BondBasket::build() called");
60
61 QuantLib::ext::shared_ptr<Pool> pool(new Pool());
62 vector<Issuer> issuerPair;
63 set<Currency> currencies_unique;
64
65 map<string, QuantLib::ext::shared_ptr<QuantLib::Bond>> qlBonds;
66 map<string, double> recoveries;
67 map<string, double> multipliers;
68 map<string, Handle<YieldTermStructure>> yieldTermStructures;
69 map<string, Currency> currencies;
70
71 const QuantLib::ext::shared_ptr<Market> market = engineFactory->market();
72
73 for (size_t i = 0; i < bonds_.size(); i++) {
74 DLOG("BondBasket::build() -- processing issuer number " << i);
75
76 bonds_[i]->build(engineFactory);
77 string creditId = bonds_[i]->bondData().creditCurveId();
78 string securityId = bonds_[i]->bondData().securityId();
79
80 Handle<DefaultProbabilityTermStructure> defaultOriginal =
81 securitySpecificCreditCurve(market, securityId, creditId)->curve();
82 Handle<DefaultProbabilityTermStructure> defaultTS;
83 Handle<Quote> recovery;
84 try {
85 recovery = market->recoveryRate(securityId, Market::defaultConfiguration);
86 } catch (...) {
87 }
88
89 try {
90
91 Real rr = recovery.empty() ? 0.0 : recovery->value();
92 auto m = [rr](Real x) { return x / (1.0 - rr); };
93 Handle<Quote> scaledSpread(QuantLib::ext::make_shared<DerivedQuote<decltype(m)>>(
94 market->securitySpread(securityId, Market::defaultConfiguration), m));
95
96 defaultTS = Handle<DefaultProbabilityTermStructure>(
97 QuantLib::ext::make_shared<QuantExt::HazardSpreadedDefaultTermStructure>(defaultOriginal, scaledSpread));
98
99 bonds_[i]->instrument()->qlInstrument()->registerWith(scaledSpread);
100 recoveries[bonds_[i]->id()] = rr;
101
102 } catch (...) {
103 defaultTS = defaultOriginal;
104 recoveries[bonds_[i]->id()] = 0.0;
105 }
106
107
108 issuerPair.push_back(dummyIssuer(defaultTS));
109 pool->add(bonds_[i]->id(), issuerPair[i]);
110 currencies_unique.insert(parseCurrency(bonds_[i]->bondData().currency()));
112
113 QuantLib::ext::shared_ptr<QuantLib::Bond> qlBond = QuantLib::ext::dynamic_pointer_cast<QuantLib::Bond>(bonds_[i]->instrument()->qlInstrument());
114 QL_REQUIRE(qlBond, "ql bond expected " << bonds_[i]->id());
115 qlBonds[bonds_[i]->id()]= qlBond;
116
117 multipliers[bonds_[i]->id()] = bonds_[i]->instrument()->multiplier();
118 yieldTermStructures[bonds_[i]->id()] = market->discountCurve(bonds_[i]->bondData().currency());
119 currencies[bonds_[i]->id()] = parseCurrency(bonds_[i]->bondData().currency());
120
121 }
122
123 DLOG("pool names");
124 for (size_t i = 0; i < pool->names().size(); i++) {
125 DLOG("name: " << pool->names()[i] << ", included: " << pool->has(bonds_[i]->id()));
126 }
127
128 //create a fx index map for each requred currency...
129 for (auto it = currencies_unique.begin(); it!=currencies_unique.end(); ++it){
130 if(it->code() != baseCcy.code()){
131 string source = it->code();
132 string target = baseCcy.code();
133 Handle<YieldTermStructure> sorTS = market->discountCurve(source);
134 Handle<YieldTermStructure> tarTS = market->discountCurve(target);
135 Handle<Quote> spot = market->fxSpot(source + target);
136 Calendar cal = NullCalendar();
137 Natural fixingDays = 0;
138
139 string name = source + target + "Index";
140
141 QuantLib::ext::shared_ptr<QuantExt::FxIndex> fxi = QuantLib::ext::make_shared<QuantExt::FxIndex>(
142 name, fixingDays, parseCurrency(source), baseCcy, cal, spot, sorTS, tarTS);
143
144 fxIndexMap_[source] = fxi;
145
146 DLOG("BondBasket::build() -- created FX Index for " << source + target);
147 }
148 }
149
150 reinvestment_ = Date().minDate();
151 if(reinvestmentEndDate != "")
152 reinvestment_ = ore::data::parseDate(reinvestmentEndDate);
153
155
156 QuantLib::ext::shared_ptr<QuantExt::BondBasket> basket(
157 new QuantExt::BondBasket(qlBonds, recoveries, multipliers, yieldTermStructures, currencies,
158 pool, baseCcy, fxIndexMap_, reinvestment_, reinvestmentScalar_, flowType_));
159
160 DLOG("BondBasket::build() -- completed");
161
162 return basket;
163}
const std::map< std::string, boost::shared_ptr< QuantExt::FxIndex > > fxIndexMap_
const std::map< std::string, std::vector< double > > reinvestmentScalar_
const Currency currency(const std::string &name) const
const boost::shared_ptr< QuantLib::Pool > & pool() const
const std::map< std::string, std::vector< std::string > > flowType_
const RequiredFixings & requiredFixings() const
Definition: bondbasket.hpp:72
RequiredFixings requiredFixings_
Definition: bondbasket.hpp:80
QuantLib::Date reinvestment_
Definition: bondbasket.hpp:81
void addData(const RequiredFixings &requiredFixings)
Date parseDate(const string &s)
Convert std::string to QuantLib::Date.
Definition: parsers.cpp:51
Currency parseCurrency(const string &s)
Convert text to QuantLib::Currency.
Definition: parsers.cpp:290
#define DLOG(text)
Logging Macro (Level = Debug)
Definition: log.hpp:554
Size size(const ValueType &v)
Definition: value.cpp:145
QuantLib::Handle< QuantExt::CreditCurve > securitySpecificCreditCurve(const QuantLib::ext::shared_ptr< Market > &market, const std::string &securityId, const std::string &creditCurveId, const std::string &configuration)
Definition: marketdata.cpp:98
string name
+ Here is the call graph for this function:

◆ bonds()

const std::vector< QuantLib::ext::shared_ptr< Bond > > & bonds ( ) const

Definition at line 70 of file bondbasket.hpp.

70{ return bonds_; }

◆ requiredFixings()

const RequiredFixings & requiredFixings ( ) const

Definition at line 72 of file bondbasket.hpp.

72{ return requiredFixings_; }

◆ isFeeFlow()

bool isFeeFlow ( const ext::shared_ptr< QuantLib::CashFlow > &  cf,
const std::string &  name 
)
private

Definition at line 165 of file bondbasket.cpp.

165 {
166
167 //in order to identify as fees, the method expects, (upfront) fees in the form of CashflowData legdata within xml representation
168 //this could be dangerous, as 5% upfront and 5% amortisation at the same date could trigger wrong assessment
169
170 bool result = false;
171 for(auto& bond : bonds_){
172 if(bond->id() == name){
173 auto oreBondData = QuantLib::ext::make_shared<ore::data::BondData>(bond->bondData());
174 if(oreBondData){
175 for (auto legData : oreBondData->coupons()){
176 auto cfData = QuantLib::ext::dynamic_pointer_cast<ore::data::CashflowData>(legData.concreteLegData());
177 if(cfData){
178 auto amounts = cfData->amounts();
179 auto dates = cfData->dates();
180 for(size_t d = 0; d < dates.size(); d++){
181 if(cf->date() == ore::data::parseDate(dates[d])){
182 if(cf->amount() == amounts[d])
183 result = true;
184 }
185 }
186 }
187 }
188 }
189 }
190 }
191 return result;
192 }
+ Here is the call graph for this function:

◆ setReinvestmentScalar()

void setReinvestmentScalar ( )
private

Definition at line 194 of file bondbasket.cpp.

194 {
195
196 Date today = Settings::instance().evaluationDate();
197
198 for(auto& bond : bonds_){
199
200 string name = bond->id();
201 if(bond->maturity() <= reinvestment_)
202 ALOG("bond " << name << " maturity " << io::iso_date(bond->maturity()) << " <= " << "reinvestment end " << io::iso_date(reinvestment_));
203
204 //identify adjustment factor (scalars) -> rescale to todays notional
205 const vector<Leg>& legs = bond->legs();
206 if(legs.size() > 1)
207 ALOG("bond " << name << " has more than one leg, only the first is considered.")
208 const Leg& leg = legs[0];
209
210 size_t jmax = 0; //index for first coupon date after reinvestment period end date
211 for (size_t j = 0; j < leg.size(); j++) {
212 QuantLib::ext::shared_ptr<QuantLib::Coupon> ptrCoupon =
213 QuantLib::ext::dynamic_pointer_cast<QuantLib::Coupon>(leg[j]);
214 if(ptrCoupon){
215 if(ptrCoupon->date() > reinvestment_){
216 jmax = j;
217 break;
218 }
219 }
220 }
221
222 double baseNotional = bond->notional(); //notional as of today, as set in the ore::data::Bond::build
223 vector<double>scalars(leg.size(), 1.0);
224 vector<string>flowType(leg.size(), "");
225 double currentScalar = 1.0;
226
227 for (size_t j = 0; j < leg.size(); j++) {
228
229 QuantLib::ext::shared_ptr<QuantLib::Coupon> ptrCoupon =
230 QuantLib::ext::dynamic_pointer_cast<QuantLib::Coupon>(leg[j]);
231 flowType[j] = "xnl"; //notional
232 if(isFeeFlow(leg[j], name))
233 flowType[j] = "fee"; //fees
234
235 if(ptrCoupon){
236 flowType[j] = "int"; //interest
237 if(j <= jmax && ptrCoupon->date() >= today){
238 double periodNotional = ptrCoupon->nominal();
239
240 if(periodNotional < 1e-10)
241 ALOG(name << " amortises too early: periodNotional " << periodNotional
242 << " cpnDate " << io::iso_date(ptrCoupon->date())
243 << " (first period after) reinvestment end " << io::iso_date(reinvestment_));
244
245 if(periodNotional < baseNotional && periodNotional > 1e-10)
246 currentScalar = baseNotional/periodNotional;
247 }
248 }
249 scalars[j] = currentScalar;
250 }
251 reinvestmentScalar_[name] = scalars;
253 }
254}
const std::string flowType(const std::string &name, int idx) const
bool isFeeFlow(const ext::shared_ptr< QuantLib::CashFlow > &cf, const std::string &name)
Definition: bondbasket.cpp:165
#define ALOG(text)
Logging Macro (Level = Alert)
Definition: log.hpp:544
+ Here is the call graph for this function:

Member Data Documentation

◆ bonds_

vector<QuantLib::ext::shared_ptr<Bond> > bonds_
private

Definition at line 78 of file bondbasket.hpp.

◆ fxIndexMap_

std::map<string, QuantLib::ext::shared_ptr<QuantExt::FxIndex> > fxIndexMap_
private

Definition at line 79 of file bondbasket.hpp.

◆ requiredFixings_

RequiredFixings requiredFixings_
private

Definition at line 80 of file bondbasket.hpp.

◆ reinvestment_

QuantLib::Date reinvestment_
private

Definition at line 81 of file bondbasket.hpp.

◆ reinvestmentScalar_

std::map<std::string, std::vector<double> > reinvestmentScalar_
private

Definition at line 82 of file bondbasket.hpp.

◆ flowType_

std::map<std::string, std::vector<std::string> > flowType_
private

Definition at line 83 of file bondbasket.hpp.