20#include <ql/errors.hpp>
30#include <boost/algorithm/string/predicate.hpp>
35using QuantLib::Visitor;
41 if (iequals(s,
"Zero"))
43 else if (iequals(s,
"Zero Spread"))
45 else if (iequals(s,
"Discount"))
47 else if (iequals(s,
"Deposit"))
49 else if (iequals(s,
"FRA"))
51 else if (iequals(s,
"Future"))
53 else if (iequals(s,
"OIS"))
55 else if (iequals(s,
"Swap"))
57 else if (iequals(s,
"Average OIS"))
59 else if (iequals(s,
"Tenor Basis Swap"))
61 else if (iequals(s,
"Tenor Basis Two Swaps"))
63 else if (iequals(s,
"BMA Basis Swap"))
65 else if (iequals(s,
"FX Forward"))
67 else if (iequals(s,
"Cross Currency Basis Swap"))
69 else if (iequals(s,
"Cross Currency Fix Float Swap"))
71 else if (iequals(s,
"Discount Ratio"))
73 else if (iequals(s,
"FittedBond"))
75 else if (iequals(s,
"Yield Plus Default"))
77 else if (iequals(s,
"Weighted Average"))
79 else if (iequals(s,
"Ibor Fallback"))
81 else if (iequals(s,
"Bond Yield Shifted"))
83 QL_FAIL(
"Yield curve segment type " << s <<
" not recognized");
86class SegmentIDGetter :
public AcyclicVisitor,
87 public Visitor<YieldCurveSegment>,
88 public Visitor<SimpleYieldCurveSegment>,
89 public Visitor<AverageOISYieldCurveSegment>,
90 public Visitor<TenorBasisYieldCurveSegment>,
91 public Visitor<CrossCcyYieldCurveSegment>,
92 public Visitor<ZeroSpreadedYieldCurveSegment>,
93 public Visitor<DiscountRatioYieldCurveSegment>,
94 public Visitor<FittedBondYieldCurveSegment>,
95 public Visitor<WeightedAverageYieldCurveSegment>,
96 public Visitor<YieldPlusDefaultYieldCurveSegment>,
97 public Visitor<BondYieldShiftedYieldCurveSegment>,
98 public Visitor<IborFallbackCurveSegment> {
101 SegmentIDGetter(
const string& curveID, map<
CurveSpec::CurveType, set<string>>& requiredCurveIds)
102 : curveID_(curveID), requiredCurveIds_(requiredCurveIds) {}
104 void visit(YieldCurveSegment&)
override;
105 void visit(SimpleYieldCurveSegment& s)
override;
106 void visit(AverageOISYieldCurveSegment& s)
override;
107 void visit(TenorBasisYieldCurveSegment& s)
override;
108 void visit(CrossCcyYieldCurveSegment& s)
override;
109 void visit(ZeroSpreadedYieldCurveSegment& s)
override;
110 void visit(DiscountRatioYieldCurveSegment& s)
override;
111 void visit(FittedBondYieldCurveSegment& s)
override;
112 void visit(WeightedAverageYieldCurveSegment& s)
override;
113 void visit(YieldPlusDefaultYieldCurveSegment& s)
override;
114 void visit(BondYieldShiftedYieldCurveSegment& s)
override;
115 void visit(IborFallbackCurveSegment& s)
override;
119 map<CurveSpec::CurveType, set<string>>& requiredCurveIds_;
122void SegmentIDGetter::visit(YieldCurveSegment&) {
126void SegmentIDGetter::visit(SimpleYieldCurveSegment& s) {
127 string aCurveID = s.projectionCurveID();
128 if (curveID_ != aCurveID && !aCurveID.empty()) {
133void SegmentIDGetter::visit(AverageOISYieldCurveSegment& s) {
134 string aCurveID = s.projectionCurveID();
135 if (curveID_ != aCurveID && !aCurveID.empty()) {
140void SegmentIDGetter::visit(TenorBasisYieldCurveSegment& s) {
141 string aCurveID = s.receiveProjectionCurveID();
142 if (curveID_ != aCurveID && !aCurveID.empty()) {
145 aCurveID = s.payProjectionCurveID();
146 if (curveID_ != aCurveID && !aCurveID.empty()) {
151void SegmentIDGetter::visit(CrossCcyYieldCurveSegment& s) {
152 string aCurveID = s.foreignDiscountCurveID();
153 if (curveID_ != aCurveID && !aCurveID.empty()) {
156 aCurveID = s.domesticProjectionCurveID();
157 if (curveID_ != aCurveID && !aCurveID.empty()) {
160 aCurveID = s.foreignProjectionCurveID();
161 if (curveID_ != aCurveID && !aCurveID.empty()) {
166void SegmentIDGetter::visit(ZeroSpreadedYieldCurveSegment& s) {
167 string aCurveID = s.referenceCurveID();
168 if (curveID_ != aCurveID && !aCurveID.empty()) {
173void SegmentIDGetter::visit(DiscountRatioYieldCurveSegment& s) {
174 if (curveID_ != s.baseCurveId() && !s.baseCurveId().empty()) {
177 if (curveID_ != s.numeratorCurveId() && !s.numeratorCurveId().empty()) {
180 if (curveID_ != s.denominatorCurveId() && !s.denominatorCurveId().empty()) {
185void SegmentIDGetter::visit(FittedBondYieldCurveSegment& s) {
186 for (
auto const& c : s.iborIndexCurves())
190void SegmentIDGetter::visit(BondYieldShiftedYieldCurveSegment& s) {
191 for (
auto const& c : s.iborIndexCurves())
196void SegmentIDGetter::visit(WeightedAverageYieldCurveSegment& s) {
197 string aCurveID1 = s.referenceCurveID1();
198 string aCurveID2 = s.referenceCurveID2();
203void SegmentIDGetter::visit(YieldPlusDefaultYieldCurveSegment& s) {
205 for (
auto const& i : s.defaultCurveIDs()) {
210void SegmentIDGetter::visit(IborFallbackCurveSegment& s) {
216 const string& discountCurveID,
217 const vector<QuantLib::ext::shared_ptr<YieldCurveSegment>>& curveSegments,
218 const string& interpolationVariable,
const string& interpolationMethod,
219 const string& zeroDayCounter,
bool extrapolation,
220 const BootstrapConfig& bootstrapConfig,
const Size mixedInterpolationCutoff)
221 :
CurveConfig(curveID, curveDescription), currency_(currency), discountCurveID_(discountCurveID),
222 curveSegments_(curveSegments), interpolationVariable_(interpolationVariable),
223 interpolationMethod_(interpolationMethod), zeroDayCounter_(zeroDayCounter), extrapolation_(extrapolation),
224 bootstrapConfig_(bootstrapConfig), mixedInterpolationCutoff_(mixedInterpolationCutoff) {
230 bool addedFxSpot =
false;
232 for (
auto segmentQuote : c->quotes())
233 quotes_.push_back(segmentQuote.first);
237 if (
auto xccySegment = QuantLib::ext::dynamic_pointer_cast<CrossCcyYieldCurveSegment>(c)) {
239 quotes_.push_back(xccySegment->spotRateID());
261 QuantLib::ext::shared_ptr<YieldCurveSegment> segment;
264 if (childName ==
"Direct") {
266 }
else if (childName ==
"Simple") {
268 }
else if (childName ==
"AverageOIS") {
270 }
else if (childName ==
"TenorBasis") {
272 }
else if (childName ==
"CrossCurrency") {
274 }
else if (childName ==
"ZeroSpread") {
276 }
else if (childName ==
"DiscountRatio") {
278 }
else if (childName ==
"FittedBond") {
280 }
else if (childName ==
"BondYieldShifted") {
282 }
else if (childName ==
"WeightedAverage") {
284 }
else if (childName ==
"YieldPlusDefault") {
286 }
else if(childName ==
"IborFallback"){
289 QL_FAIL(
"Yield curve segment node name '" << childName <<
"' not recognized.");
294 segment->fromXML(child);
295 }
catch (std::exception& ex) {
296 QL_FAIL(
"Exception parsing yield curve segment XML Node, name = "
297 << childName <<
" and curveID = " <<
curveID_ <<
" : " << ex.what());
300 QL_FAIL(
"Unable to build yield curve segment for name = " << childName
306 QL_FAIL(
"No Segments node in XML doc for yield curve ID = " <<
curveID_);
379 const vector<string>& quoteNames)
381 for (
auto q : quoteNames)
390 std::map<std::string, std::list<std::string>> validSegmentTypes = {
391 {
"Direct", {
"Zero",
"Discount"}},
392 {
"Simple", {
"Deposit",
"FRA",
"Future",
"OIS",
"Swap",
"BMA Basis Swap"}},
393 {
"AverageOIS", {
"Average OIS"}},
394 {
"TenorBasis", {
"Tenor Basis Swap",
"Tenor Basis Two Swaps"}},
395 {
"CrossCurrency", {
"FX Forward",
"Cross Currency Basis Swap",
"Cross Currency Fix Float Swap"}},
396 {
"ZeroSpread", {
"Zero Spread"}},
397 {
"FittedBond", {
"FittedBond"}},
398 {
"YieldPlusDefault", {
"Yield Plus Default"}},
399 {
"WeightedAverage", {
"Weighted Average"}},
400 {
"DiscountRatio", {
"Discount Ratio"}},
401 {
"IborFallback", {
"Ibor Fallback"}},
402 {
"BondYieldShifted", {
"Bond Yield Shifted"}}
405 std::list<std::string> validTypes = validSegmentTypes.at(
name);
406 QL_REQUIRE(std::find(validTypes.begin(), validTypes.end(),
typeID_) != validTypes.end(),
407 "The curve type " <<
typeID_ <<
" is not a valid " <<
name <<
" curve segment type");
410 if (
name ==
"AverageOIS") {
419 QL_FAIL(
"No Quotes in segment. Remove segment or add quotes.");
426 bool opt = (!attr.empty() &&
parseBool(attr));
435 "PillarChoice " <<
pillarChoice_ <<
" not supported, expected MaturityDate, LastRelevantDate");
448 QL_REQUIRE(
quotes_.size() % 2 == 0,
"Invalid quotes vector should be even");
449 for (Size i = 0; i <
quotes_.size(); i = i + 2) {
450 string rateQuote =
quotes_[i].first;
451 string spreadQuote =
quotes_[i + 1].first;
478 Visitor<YieldCurveSegment>* v1 =
dynamic_cast<Visitor<YieldCurveSegment>*
>(&v);
482 QL_FAIL(
"Not a YieldCurveSegment visitor.");
486 const vector<string>& quotes)
501 Visitor<DirectYieldCurveSegment>* v1 =
dynamic_cast<Visitor<DirectYieldCurveSegment>*
>(&v);
509 const vector<string>& quotes,
const string& projectionCurveID)
510 :
YieldCurveSegment(typeID, conventionsID, quotes), projectionCurveID_(projectionCurveID) {}
527 Visitor<SimpleYieldCurveSegment>* v1 =
dynamic_cast<Visitor<SimpleYieldCurveSegment>*
>(&v);
535 const vector<string>& quotes,
const string& projectionCurveID)
536 :
YieldCurveSegment(typeID, conventionsID, quotes), projectionCurveID_(projectionCurveID) {}
553 Visitor<AverageOISYieldCurveSegment>* v1 =
dynamic_cast<Visitor<AverageOISYieldCurveSegment>*
>(&v);
561 const vector<string>& quotes,
562 const string& receiveProjectionCurveID,
563 const string& payProjectionCurveID)
564 :
YieldCurveSegment(typeID, conventionsID, quotes), receiveProjectionCurveID_(receiveProjectionCurveID),
565 payProjectionCurveID_(payProjectionCurveID) {}
575 if (projectionCurveShort) {
576 ALOG(
"TenorBasisYieldCurveSegment: ProjectionCurveShort is deprecated, fill empty receiveProjectionCurveID");
582 if (projectionCurveLong) {
583 ALOG(
"TenorBasisYieldCurveSegment: projectionCurveLong is deprecated, fill empty payProjectionCurveID");
600 Visitor<TenorBasisYieldCurveSegment>* v1 =
dynamic_cast<Visitor<TenorBasisYieldCurveSegment>*
>(&v);
608 const vector<string>& quotes,
const string& spotRateID,
609 const string& foreignDiscountCurveID,
610 const string& domesticProjectionCurveID,
611 const string& foreignProjectionCurveID)
613 foreignDiscountCurveID_(foreignDiscountCurveID), domesticProjectionCurveID_(domesticProjectionCurveID),
614 foreignProjectionCurveID_(foreignProjectionCurveID) {}
638 Visitor<CrossCcyYieldCurveSegment>* v1 =
dynamic_cast<Visitor<CrossCcyYieldCurveSegment>*
>(&v);
646 const vector<string>& quotes,
647 const string& referenceCurveID)
648 :
YieldCurveSegment(typeID, conventionsID, quotes), referenceCurveID_(referenceCurveID) {}
664 Visitor<ZeroSpreadedYieldCurveSegment>* v1 =
dynamic_cast<Visitor<ZeroSpreadedYieldCurveSegment>*
>(&v);
672 const string& typeId,
const string& baseCurveId,
const string& baseCurveCurrency,
const string& numeratorCurveId,
673 const string& numeratorCurveCurrency,
const string& denominatorCurveId,
const string& denominatorCurveCurrency)
674 :
YieldCurveSegment(typeId,
"", vector<string>()), baseCurveId_(baseCurveId), baseCurveCurrency_(baseCurveCurrency),
675 numeratorCurveId_(numeratorCurveId), numeratorCurveCurrency_(numeratorCurveCurrency),
676 denominatorCurveId_(denominatorCurveId), denominatorCurveCurrency_(denominatorCurveCurrency) {}
683 QL_REQUIRE(aNode,
"Discount ratio segment needs a BaseCurve node");
688 QL_REQUIRE(aNode,
"Discount ratio segment needs a NumeratorCurve node");
693 QL_REQUIRE(aNode,
"Discount ratio segment needs a DenominatorCurve node");
718 if (Visitor<DiscountRatioYieldCurveSegment>* v1 =
dynamic_cast<Visitor<DiscountRatioYieldCurveSegment>*
>(&v))
725 const map<string, string>& iborIndexCurves,
726 const bool extrapolateFlat)
727 :
YieldCurveSegment(typeID,
"", quotes), iborIndexCurves_(iborIndexCurves), extrapolateFlat_(extrapolateFlat) {}
733 vector<string> iborIndexNames;
735 node,
"IborIndexCurves",
"IborIndexCurve",
"iborIndex", iborIndexNames,
false);
736 for (Size i = 0; i < iborIndexNames.size(); ++i) {
751 vector<string> iborIndexNames;
754 iborIndexNames.push_back(c.first);
765 Visitor<FittedBondYieldCurveSegment>* v1 =
dynamic_cast<Visitor<FittedBondYieldCurveSegment>*
>(&v);
773 const string& referenceCurveID1,
774 const string& referenceCurveID2,
const Real weight1,
776 :
YieldCurveSegment(typeID,
"", {}), referenceCurveID1_(referenceCurveID1), referenceCurveID2_(referenceCurveID2),
777 weight1_(weight1), weight2_(weight2) {}
799 Visitor<WeightedAverageYieldCurveSegment>* v1 =
dynamic_cast<Visitor<WeightedAverageYieldCurveSegment>*
>(&v);
807 const string& referenceCurveID,
808 const std::vector<std::string>& defaultCurveIDs,
809 const std::vector<Real>& weights)
810 :
YieldCurveSegment(typeID,
"", {}), referenceCurveID_(referenceCurveID), defaultCurveIDs_(defaultCurveIDs),
831 Visitor<YieldPlusDefaultYieldCurveSegment>* v1 =
dynamic_cast<Visitor<YieldPlusDefaultYieldCurveSegment>*
>(&v);
839 const string& rfrCurve,
const boost::optional<string>& rfrIndex,
840 const boost::optional<Real>& spread)
841 :
YieldCurveSegment(typeID,
"", {}), iborIndex_(iborIndex), rfrCurve_(rfrCurve), rfrIndex_(rfrIndex),
870 Visitor<IborFallbackCurveSegment>* v1 =
dynamic_cast<Visitor<IborFallbackCurveSegment>*
>(&v);
878 const map<string, string>& iborIndexCurves,
const bool extrapolateFlat)
879 :
YieldCurveSegment(typeID,
"", quotes), referenceCurveID_(referenceCurveID), iborIndexCurves_(iborIndexCurves),
880 extrapolateFlat_(extrapolateFlat) {}
888 vector<string> iborIndexNames;
890 node,
"IborIndexCurves",
"IborIndexCurve",
"iborIndex", iborIndexNames,
false);
891 for (Size i = 0; i < iborIndexNames.size(); ++i) {
910 Visitor<BondYieldShiftedYieldCurveSegment>* v1 =
dynamic_cast<Visitor<BondYieldShiftedYieldCurveSegment>*
>(&v);
Average OIS yield curve segment.
string projectionCurveID_
AverageOISYieldCurveSegment()
Default constructor.
virtual void accept(AcyclicVisitor &) override
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
Bond yield shifted yield curve segment.
BondYieldShiftedYieldCurveSegment()
Default constructor.
const map< string, string > & iborIndexCurves() const
virtual void accept(AcyclicVisitor &) override
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
map< string, string > iborIndexCurves_
QuantLib::Real maxFactor() const
QuantLib::Real accuracy() const
void fromXML(ore::data::XMLNode *node) override
QuantLib::Real minFactor() const
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
QuantLib::Size maxAttempts() const
Cross Currency yield curve segment.
string foreignDiscountCurveID_
CrossCcyYieldCurveSegment()
Default constructor.
virtual void accept(AcyclicVisitor &) override
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
string foreignProjectionCurveID_
string domesticProjectionCurveID_
Base curve configuration.
map< CurveSpec::CurveType, set< string > > requiredCurveIds_
CurveType
Supported curve types.
Direct yield curve segment.
virtual void accept(AcyclicVisitor &) override
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
DirectYieldCurveSegment()
Default constructor.
Discount ratio yield curve segment.
std::string baseCurveCurrency_
DiscountRatioYieldCurveSegment()
Default constructor.
void accept(QuantLib::AcyclicVisitor &v) override
std::string denominatorCurveId_
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
std::string denominatorCurveCurrency_
std::string numeratorCurveId_
std::string numeratorCurveCurrency_
FittedBond yield curve segment.
FittedBondYieldCurveSegment()
Default constructor.
const map< string, string > & iborIndexCurves() const
virtual void accept(AcyclicVisitor &) override
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
map< string, string > iborIndexCurves_
Ibor Fallback yield curve segment.
boost::optional< string > rfrIndex_
virtual void accept(AcyclicVisitor &) override
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
boost::optional< Real > spread_
IborFallbackCurveSegment()
Default constructor.
Simple yield curve segment.
string projectionCurveID_
virtual void accept(AcyclicVisitor &) override
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
SimpleYieldCurveSegment()
Default constructor.
Tenor Basis yield curve segment.
TenorBasisYieldCurveSegment()
Default constructor.
virtual void accept(AcyclicVisitor &) override
virtual void fromXML(XMLNode *node) override
string payProjectionCurveID_
virtual XMLNode * toXML(XMLDocument &doc) const override
string receiveProjectionCurveID_
Weighted average yield curve segment.
string referenceCurveID2_
string referenceCurveID1_
virtual void accept(AcyclicVisitor &) override
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
WeightedAverageYieldCurveSegment()
Default constructor.
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 vector< Real > getChildrenValuesAsDoubles(XMLNode *node, const string &names, const string &name, bool mandatory=false)
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 Real getChildValueAsDouble(XMLNode *node, const string &name, bool mandatory=false, double defaultValue=0.0)
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 bool getChildValueAsBool(XMLNode *node, const string &name, bool mandatory=false, bool defaultValue=true)
static XMLNode * getChildNode(XMLNode *n, const string &name="")
static string getNodeValue(XMLNode *node)
Get a node's value.
static int getChildValueAsInt(XMLNode *node, const string &name, bool mandatory=false, int defaultValue=0)
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 void setNodeName(XMLDocument &doc, XMLNode *node, const string &name)
static XMLNode * addChild(XMLDocument &doc, XMLNode *n, const string &name)
static void appendNode(XMLNode *parent, XMLNode *child)
void populateRequiredCurveIds()
YieldCurveConfig()
Default constructor.
virtual void fromXML(XMLNode *node) override
BootstrapConfig bootstrapConfig_
virtual XMLNode * toXML(XMLDocument &doc) const override
const vector< string > & quotes() override
Return all the market quotes required for this config.
string interpolationVariable_
Size mixedInterpolationCutoff_
string interpolationMethod_
vector< QuantLib::ext::shared_ptr< YieldCurveSegment > > curveSegments_
Base class for yield curve segments.
QuantLib::Pillar::Choice pillarChoice_
Type
supported segment types
virtual void accept(AcyclicVisitor &)
vector< pair< string, bool > > quotes_
Quote and optional flag pair.
YieldCurveSegment()
Default constructor.
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
pair< string, bool > quote(const string &name, bool opt=false)
Utility to build a quote, optional flag defaults to false.
Yield plus default curves segment.
YieldPlusDefaultYieldCurveSegment()
Default constructor.
std::vector< std::string > defaultCurveIDs_
virtual void accept(AcyclicVisitor &) override
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
std::vector< Real > weights_
Zero Spreaded yield curve segment.
virtual void accept(AcyclicVisitor &) override
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
ZeroSpreadedYieldCurveSegment()
Default constructor.
Curve requirements specification.
QuantLib::ext::shared_ptr< CurveSpec > parseCurveSpec(const string &s)
function to convert a string into a curve spec
QuantLib::Pillar::Choice parsePillarChoice(const std::string &s)
Convert text to QuantLib::Pillar::Choice.
bool parseBool(const string &s)
Convert text to bool.
Real parseReal(const string &s)
Convert text to Real.
Classes and functions for log message handling.
#define ALOG(text)
Logging Macro (Level = Alert)
YieldCurveSegment::Type parseYieldCurveSegment(const string &s)
std::string to_string(const LocationInfo &l)
Serializable Credit Default Swap.
Map text representations to QuantLib/QuantExt types.
string conversion utilities
Yield curve configuration classes.