26 const Calendar& fixingCalendar,
const bool conditionalOnSurvival,
27 const QuantLib::ext::shared_ptr<EngineFactory>& engineFactory, Real bidAskAdjustment,
28 const bool bondIssueDateFallback)
31 securityData.populateFromBondReferenceData(engineFactory->referenceData());
32 bond_ = Bond(Envelope(), securityData);
33 bond_.build(engineFactory);
34 buildIndex(relative, fixingCalendar, conditionalOnSurvival, engineFactory, bidAskAdjustment, bondIssueDateFallback);
37BondIndexBuilder::BondIndexBuilder(
const Bond& bond,
const bool dirty,
const bool relative,
38 const Calendar& fixingCalendar,
const bool conditionalOnSurvival,
39 const QuantLib::ext::shared_ptr<EngineFactory>& engineFactory, Real bidAskAdjustment,
40 const bool bondIssueDateFallback)
41 :
bond_(bond), dirty_(dirty) {
42 buildIndex(relative, fixingCalendar, conditionalOnSurvival, engineFactory, bidAskAdjustment, bondIssueDateFallback);
45BondIndexBuilder::BondIndexBuilder(
const std::string& securityId,
const bool dirty,
const bool relative,
46 const Calendar& fixingCalendar,
const bool conditionalOnSurvival,
47 const QuantLib::ext::shared_ptr<EngineFactory>& engineFactory, Real bidAskAdjustment,
48 const bool bondIssueDateFallback)
50 BondData bondData(securityId, 100.0);
51 bondData.populateFromBondReferenceData(engineFactory->referenceData());
52 bond_ = Bond(Envelope(), bondData);
53 bond_.build(engineFactory);
54 buildIndex(relative, fixingCalendar, conditionalOnSurvival, engineFactory, bidAskAdjustment, bondIssueDateFallback);
57void BondIndexBuilder::buildIndex(
const bool relative,
const Calendar& fixingCalendar,
const bool conditionalOnSurvival,
58 const QuantLib::ext::shared_ptr<EngineFactory>& engineFactory, Real bidAskAdjustment,
59 const bool bondIssueDateFallback) {
61 fixings_ =
bond_.requiredFixings();
63 auto qlBond = QuantLib::ext::dynamic_pointer_cast<QuantLib::Bond>(
bond_.instrument()->qlInstrument());
64 QL_REQUIRE(qlBond,
"buildBondIndex(): could not cast to QuantLib::Bond, this is unexpected");
67 auto bondData =
bond_.bondData();
68 string securityId = bondData.securityId();
70 Handle<YieldTermStructure> discountCurve = engineFactory->market()->yieldCurve(
71 bondData.referenceCurveId(), engineFactory->configuration(MarketContext::pricing));
73 Handle<DefaultProbabilityTermStructure> defaultCurve;
74 if (!bondData.creditCurveId().empty())
76 engineFactory->configuration(MarketContext::pricing))
79 Handle<YieldTermStructure> incomeCurve;
80 if (!bondData.incomeCurveId().empty())
81 incomeCurve = engineFactory->market()->yieldCurve(bondData.incomeCurveId(),
82 engineFactory->configuration(MarketContext::pricing));
84 Handle<Quote> recovery;
87 engineFactory->market()->recoveryRate(securityId, engineFactory->configuration(MarketContext::pricing));
89 WLOG(
"security specific recovery rate not found for security ID "
90 << securityId <<
", falling back on the recovery rate for credit curve Id " << bondData.creditCurveId());
91 if (!bondData.creditCurveId().empty())
92 recovery = engineFactory->market()->recoveryRate(bondData.creditCurveId(),
93 engineFactory->configuration(MarketContext::pricing));
96 Handle<Quote> spread(QuantLib::ext::make_shared<SimpleQuote>(0.0));
99 engineFactory->market()->securitySpread(securityId, engineFactory->configuration(MarketContext::pricing));
103 if (!bondData.hasCreditRisk())
104 defaultCurve = Handle<DefaultProbabilityTermStructure>();
107 bondIndex_ = QuantLib::ext::make_shared<QuantExt::BondIndex>(securityId, dirty_, relative, fixingCalendar, qlBond,
108 discountCurve, defaultCurve, recovery, spread, incomeCurve, conditionalOnSurvival,
parseDate(bondData.issueDate()), bondData.priceQuoteMethod(),
109 bondData.priceQuoteBaseValue(), bondData.isInflationLinked(), bidAskAdjustment, bondIssueDateFallback);
112QuantLib::ext::shared_ptr<QuantExt::BondIndex> BondIndexBuilder::bondIndex()
const {
return bondIndex_; }
115 requiredFixings.
addData(fixings_.filteredFixingDates());
117 QL_REQUIRE(leg.size() > 0,
"BondIndexBuild: Leg is required if dirty flag set to true");
119 auto fixingGetter = QuantLib::ext::make_shared<FixingDateGetter>(legFixings);
120 fixingGetter->setRequireFixingStartDates(
true);
123 set<Date> fixingDates;
126 if (fixingMap.size() > 0) {
127 std::map<std::string, std::set<Date>> indexFixings;
128 for (
const auto& [_, dates] : fixingMap) {
129 for (
const auto& [d, mandatory] : dates) {
130 auto tmp = fixings_.filteredFixingDates(d);
138Real BondIndexBuilder::priceAdjustment(Real price) {
139 if (price == Null<Real>())
142 Real adj =
bond_.bondData().priceQuoteMethod() == QuantExt::BondIndex::PriceQuoteMethod::CurrencyPerUnit
143 ? 1.0 /
bond_.bondData().priceQuoteBaseValue()
Interface for building a bond index.
BondIndexBuilder(BondData bondData, const bool dirty, const bool relative, const Calendar &fixingCalendar, const bool conditionalOnSurvival, const QuantLib::ext::shared_ptr< EngineFactory > &engineFactory, QuantLib::Real bidAskAdjustment=0.0, const bool bondIssueDateFallback=false)
void addData(const RequiredFixings &requiredFixings)
std::map< std::string, FixingDates > fixingDatesIndices(const QuantLib::Date &settlementDate=QuantLib::Date()) const
Date parseDate(const string &s)
Convert std::string to QuantLib::Date.
#define WLOG(text)
Logging Macro (Level = Warning)
market data related utilties
void addToRequiredFixings(const QuantLib::Leg &leg, const QuantLib::ext::shared_ptr< FixingDateGetter > &fixingDateGetter)
QuantLib::Handle< QuantExt::CreditCurve > securitySpecificCreditCurve(const QuantLib::ext::shared_ptr< Market > &market, const std::string &securityId, const std::string &creditCurveId, const std::string &configuration)
Serializable Credit Default Swap.