Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
iborfallbackconfig.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2021 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
24
25#include <ql/time/date.hpp>
26
27namespace ore {
28namespace data {
29
30using namespace QuantLib;
31
33IborFallbackConfig::IborFallbackConfig(const bool enableIborFallbacks, const bool useRfrCurveInTodaysMarket,
34 const bool useRfrCurveInSimulationMarket,
35 const std::map<std::string, FallbackData>& fallbacks)
36 : enableIborFallbacks_(enableIborFallbacks), useRfrCurveInTodaysMarket_(useRfrCurveInTodaysMarket),
37 useRfrCurveInSimulationMarket_(useRfrCurveInSimulationMarket), fallbacks_(fallbacks) {}
38
43 fallbacks_.clear();
44}
45
49
50void IborFallbackConfig::addIndexFallbackRule(const string& iborIndex, const FallbackData& fallbackData) {
51 fallbacks_[iborIndex] = fallbackData;
52}
53
54bool IborFallbackConfig::isIndexReplaced(const string& iborIndex, const Date& asof) const {
56 return false;
57 auto i = fallbacks_.find(iborIndex);
58 return i != fallbacks_.end() && asof >= i->second.switchDate;
59}
60
62 auto i = fallbacks_.find(iborIndex);
63 QL_REQUIRE(
64 i != fallbacks_.end(),
65 "No fallback data found for ibor index '"
66 << iborIndex
67 << "', client code should check whether an index is replaced with IsIndexReplaced() before querying data.");
68 return i->second;
69}
70
72 clear();
73 XMLUtils::checkNode(node, "IborFallbackConfig");
74 if (auto global = XMLUtils::getChildNode(node, "GlobalSettings")) {
75 enableIborFallbacks_ = XMLUtils::getChildValueAsBool(global, "EnableIborFallbacks", true);
76 useRfrCurveInTodaysMarket_ = XMLUtils::getChildValueAsBool(global, "UseRfrCurveInTodaysMarket", true);
77 useRfrCurveInSimulationMarket_ = XMLUtils::getChildValueAsBool(global, "UseRfrCurveInSimulationMarket", true);
78 }
79 if (auto fallbacks = XMLUtils::getChildNode(node, "Fallbacks")) {
80 for (auto const repl : XMLUtils::getChildrenNodes(fallbacks, "Fallback")) {
81 XMLUtils::checkNode(repl, "Fallback");
82 string ibor = XMLUtils::getChildValue(repl, "IborIndex", true);
83 fallbacks_[ibor].rfrIndex = XMLUtils::getChildValue(repl, "RfrIndex", true);
84 fallbacks_[ibor].spread = parseReal(XMLUtils::getChildValue(repl, "Spread", true));
85 fallbacks_[ibor].switchDate = parseDate(XMLUtils::getChildValue(repl, "SwitchDate", true));
86 }
87 }
88}
89
91 XMLNode* node = doc.allocNode("IborFallbackConfig");
92 XMLNode* global = XMLUtils::addChild(doc, node, "GlobalSettings");
93 XMLUtils::addChild(doc, global, "EnableIborFallbacks", enableIborFallbacks_);
94 XMLUtils::addChild(doc, global, "UseRfrCurveInTodaysMarket", useRfrCurveInTodaysMarket_);
95 XMLUtils::addChild(doc, global, "UseRfrCurveInSimulationMarket", useRfrCurveInSimulationMarket_);
96 XMLNode* repl = XMLUtils::addChild(doc, node, "Fallbacks");
97 for (auto const& r : fallbacks_) {
98 XMLNode* tmp = XMLUtils::addChild(doc, repl, "Fallback");
99 XMLUtils::addChild(doc, tmp, "IborIndex", r.first);
100 XMLUtils::addChild(doc, tmp, "RfrIndex", r.second.rfrIndex);
101 XMLUtils::addChild(doc, tmp, "Spread", r.second.spread);
102 XMLUtils::addChild(doc, tmp, "SwitchDate", ore::data::to_string(r.second.switchDate));
103 }
104 return node;
105}
106
108 // A switch date 1 Jan 2100 indicates that the cessation date is not yet known.
109 // Sources:
110 // [1] BBG ISDA IBOR Fallback Dashboard (Tenor Effective Date = switchDate, Spread Adjustment Today => spread)
111 // [2] https://assets.bbhub.io/professional/sites/10/IBOR-Fallbacks-LIBOR-Cessation_Announcement_20210305.pdf
112 // [3] https://www.isda.org/2021/03/05/isda-statement-on-uk-fca-libor-announcement/
113 // [4] https://www.fca.org.uk/publication/documents/future-cessation-loss-representativeness-libor-benchmarks.pdf
114 // [5] https://www.isda.org/2021/03/29/isda-statement-on-jbata-announcement-on-yen-tibor-and-euroyen-tibor/
115 // [6] https://www.isda.org/a/rwNTE/CDOR-tenor-cessation_ISDA-guidance_17.11.2020_PDF.pdf
116 static IborFallbackConfig c = {true,
117 true,
118 false,
119 {{"CHF-LIBOR-SN", FallbackData{"CHF-SARON", -0.000551, Date(1, Jan, 2022)}},
120 {"CHF-LIBOR-1W", FallbackData{"CHF-SARON", -0.000705, Date(1, Jan, 2022)}},
121 {"CHF-LIBOR-1M", FallbackData{"CHF-SARON", -0.000571, Date(1, Jan, 2022)}},
122 {"CHF-LIBOR-2M", FallbackData{"CHF-SARON", -0.000231, Date(1, Jan, 2022)}},
123 {"CHF-LIBOR-3M", FallbackData{"CHF-SARON", 0.000031, Date(1, Jan, 2022)}},
124 {"CHF-LIBOR-6M", FallbackData{"CHF-SARON", 0.000741, Date(1, Jan, 2022)}},
125 {"CHF-LIBOR-12M", FallbackData{"CHF-SARON", 0.002048, Date(1, Jan, 2022)}},
126 {"EUR-EONIA", FallbackData{"EUR-ESTER", 0.00085, Date(1, Jan, 2022)}},
127 {"EUR-EURIBOR-1W", FallbackData{"EUR-ESTER", 0.000577, Date(1, Jan, 2100)}},
128 {"EUR-EURIBOR-1M", FallbackData{"EUR-ESTER", 0.000738, Date(1, Jan, 2100)}},
129 {"EUR-EURIBOR-3M", FallbackData{"EUR-ESTER", 0.001244, Date(1, Jan, 2100)}},
130 {"EUR-EURIBOR-6M", FallbackData{"EUR-ESTER", 0.001977, Date(1, Jan, 2100)}},
131 {"EUR-EURIBOR-12M", FallbackData{"EUR-ESTER", 0.002048, Date(1, Jan, 2100)}},
132 {"EUR-LIBOR-ON", FallbackData{"EUR-ESTER", 0.000017, Date(1, Jan, 2022)}},
133 {"EUR-LIBOR-1W", FallbackData{"EUR-ESTER", 0.000243, Date(1, Jan, 2022)}},
134 {"EUR-LIBOR-1M", FallbackData{"EUR-ESTER", 0.000456, Date(1, Jan, 2022)}},
135 {"EUR-LIBOR-2M", FallbackData{"EUR-ESTER", 0.000753, Date(1, Jan, 2022)}},
136 {"EUR-LIBOR-3M", FallbackData{"EUR-ESTER", 0.000962, Date(1, Jan, 2022)}},
137 {"EUR-LIBOR-6M", FallbackData{"EUR-ESTER", 0.001537, Date(1, Jan, 2022)}},
138 {"EUR-LIBOR-12M", FallbackData{"EUR-ESTER", 0.002993, Date(1, Jan, 2022)}},
139 {"JPY-TIBOR-1W", FallbackData{"JPY-TONAR", 0.0005564, Date(1, Jan, 2025)}},
140 {"JPY-TIBOR-1M", FallbackData{"JPY-TONAR", 0.0009608, Date(1, Jan, 2025)}},
141 {"JPY-TIBOR-3M", FallbackData{"JPY-TONAR", 0.0010989, Date(1, Jan, 2025)}},
142 {"JPY-TIBOR-6M", FallbackData{"JPY-TONAR", 0.0016413, Date(1, Jan, 2025)}},
143 {"JPY-TIBOR-12M", FallbackData{"JPY-TONAR", 0.0018181, Date(1, Jan, 2025)}},
144 {"JPY-EYTIBOR-1W", FallbackData{"JPY-TONAR", 0.0006506, Date(1, Jan, 2025)}},
145 {"JPY-EYTIBOR-1M", FallbackData{"JPY-TONAR", 0.0013485, Date(1, Jan, 2025)}},
146 {"JPY-EYTIBOR-3M", FallbackData{"JPY-TONAR", 0.0010252, Date(1, Jan, 2025)}},
147 {"JPY-EYTIBOR-6M", FallbackData{"JPY-TONAR", 0.0014848, Date(1, Jan, 2025)}},
148 {"JPY-EYTIBOR-12M", FallbackData{"JPY-TONAR", 0.0018567, Date(1, Jan, 2025)}},
149 {"JPY-LIBOR-SN", FallbackData{"JPY-TONAR", -0.0001839, Date(1, Jan, 2022)}},
150 {"JPY-LIBOR-1W", FallbackData{"JPY-TONAR", -0.0001981, Date(1, Jan, 2022)}},
151 {"JPY-LIBOR-1M", FallbackData{"JPY-TONAR", -0.0002923, Date(1, Jan, 2022)}},
152 {"JPY-LIBOR-2M", FallbackData{"JPY-TONAR", -0.0000449, Date(1, Jan, 2022)}},
153 {"JPY-LIBOR-3M", FallbackData{"JPY-TONAR", 0.0000835, Date(1, Jan, 2022)}},
154 {"JPY-LIBOR-6M", FallbackData{"JPY-TONAR", 0.0005809, Date(1, Jan, 2022)}},
155 {"JPY-LIBOR-12M", FallbackData{"JPY-TONAR", 0.00166, Date(1, Jan, 2022)}},
156 {"AUD-BBSW-1M", FallbackData{"AUD-AONIA", 0.001191, Date(1, Jan, 2100)}},
157 {"AUD-BBSW-2M", FallbackData{"AUD-AONIA", 0.002132, Date(1, Jan, 2100)}},
158 {"AUD-BBSW-3M", FallbackData{"AUD-AONIA", 0.002623, Date(1, Jan, 2100)}},
159 {"AUD-BBSW-4M", FallbackData{"AUD-AONIA", 0.003313, Date(1, Jan, 2100)}},
160 {"AUD-BBSW-5M", FallbackData{"AUD-AONIA", 0.004104, Date(1, Jan, 2100)}},
161 {"AUD-BBSW-6M", FallbackData{"AUD-AONIA", 0.004845, Date(1, Jan, 2100)}},
162 {"HKD-HIBOR-ON", FallbackData{"HKD-HONIA", 0.0003219, Date(1, Jan, 2100)}},
163 {"HKD-HIBOR-1W", FallbackData{"HKD-HONIA", 0.001698, Date(1, Jan, 2100)}},
164 {"HKD-HIBOR-2W", FallbackData{"HKD-HONIA", 0.002370, Date(1, Jan, 2100)}},
165 {"HKD-HIBOR-1M", FallbackData{"HKD-HONIA", 0.0039396, Date(1, Jan, 2100)}},
166 {"HKD-HIBOR-2M", FallbackData{"HKD-HONIA", 0.0056768, Date(1, Jan, 2100)}},
167 {"HKD-HIBOR-3M", FallbackData{"HKD-HONIA", 0.0072642, Date(1, Jan, 2100)}},
168 {"HKD-HIBOR-6M", FallbackData{"HKD-HONIA", 0.0093495, Date(1, Jan, 2100)}},
169 {"HKD-HIBOR-12M", FallbackData{"HKD-HONIA", 0.0121231, Date(1, Jan, 2100)}},
170 {"CAD-CDOR-1M", FallbackData{"CAD-CORRA", 0.0029547, Date(1, July, 2024)}},
171 {"CAD-CDOR-2M", FallbackData{"CAD-CORRA", 0.0030190, Date(1, July, 2024)}},
172 {"CAD-CDOR-3M", FallbackData{"CAD-CORRA", 0.0032138, Date(1, July, 2024)}},
173 {"CAD-CDOR-6M", FallbackData{"CAD-CORRA", 0.0049375, Date(17, May, 2021)}},
174 {"CAD-CDOR-12M", FallbackData{"CAD-CORRA", 0.005482, Date(17, May, 2021)}},
175 {"GBP-LIBOR-ON", FallbackData{"GBP-SONIA", -0.000024, Date(1, Jan, 2022)}},
176 {"GBP-LIBOR-1W", FallbackData{"GBP-SONIA", 0.000168, Date(1, Jan, 2022)}},
177 {"GBP-LIBOR-1M", FallbackData{"GBP-SONIA", 0.000326, Date(1, Jan, 2022)}},
178 {"GBP-LIBOR-2M", FallbackData{"GBP-SONIA", 0.000633, Date(1, Jan, 2022)}},
179 {"GBP-LIBOR-3M", FallbackData{"GBP-SONIA", 0.001193, Date(1, Jan, 2022)}},
180 {"GBP-LIBOR-6M", FallbackData{"GBP-SONIA", 0.002766, Date(1, Jan, 2022)}},
181 {"GBP-LIBOR-12M", FallbackData{"GBP-SONIA", 0.004644, Date(1, Jan, 2022)}},
182 {"USD-LIBOR-ON", FallbackData{"USD-SOFR", 0.0000644, Date(1, Jul, 2023)}},
183 {"USD-LIBOR-1W", FallbackData{"USD-SOFR", 0.0003839, Date(1, Jan, 2023)}},
184 {"USD-LIBOR-1M", FallbackData{"USD-SOFR", 0.0011448, Date(1, Jul, 2023)}},
185 {"USD-LIBOR-2M", FallbackData{"USD-SOFR", 0.0018456, Date(1, Jan, 2023)}},
186 {"USD-LIBOR-3M", FallbackData{"USD-SOFR", 0.0026161, Date(1, Jul, 2023)}},
187 {"USD-LIBOR-6M", FallbackData{"USD-SOFR", 0.0042826, Date(1, Jul, 2023)}},
188 {"USD-LIBOR-12M", FallbackData{"USD-SOFR", 0.0071513, Date(1, Jul, 2023)}},
189 {"TRY-TRLIBOR-1M", FallbackData{"TRY-TLREF", 0.0100, Date(1, July, 2022)}},
190 {"TRY-TRLIBOR-3M", FallbackData{"TRY-TLREF", 0.0093, Date(1, July, 2022)}},
191 {"TRY-TRLIBOR-6M", FallbackData{"TRY-TLREF", 0.0058, Date(1, July, 2022)}}}};
192 return c;
193}
194
195void IborFallbackConfig::updateSwitchDate(QuantLib::Date targetSwitchDate, const std::string& indexName) {
196 for (std::map<std::string, FallbackData>::iterator f = fallbacks_.begin(); f != fallbacks_.end(); f++) {
197 if ((f->first == indexName || indexName == "") && // selected index or all of them if indexName is left blank
198 f->second.switchDate > targetSwitchDate) { // skipping IBORs with switch dates before the target switch date
199 StructuredConfigurationWarningMessage("IborFallbackConfig", f->first, "",
200 "Updating switch date from " + to_string(f->second.switchDate) +
201 " to " + to_string(targetSwitchDate))
202 .log();
203 f->second.switchDate = targetSwitchDate;
204 }
205 }
206}
207
209 for (auto f : fallbacks_) {
210 DLOG("IBOR index " << f.first << " has fallback switch date " << to_string(f.second.switchDate));
211 }
212}
213
214} // namespace data
215} // namespace ore
void updateSwitchDate(QuantLib::Date targetSwitchDate, const std::string &indexName="")
const FallbackData & fallbackData(const string &iborIndex) const
void fromXML(XMLNode *node) override
XMLNode * toXML(XMLDocument &doc) const override
std::map< std::string, FallbackData > fallbacks_
static IborFallbackConfig defaultConfig()
bool isIndexReplaced(const string &iborIndex, const QuantLib::Date &asof=QuantLib::Date::maxDate()) const
void addIndexFallbackRule(const string &iborIndex, const FallbackData &fallbackData)
void log() const
generate Boost log record to pass to corresponding sinks
Definition: log.cpp:491
Utility classes for Structured warnings, contains the configuration type and ID (NettingSetId,...
Small XML Document wrapper class.
Definition: xmlutils.hpp:65
XMLNode * allocNode(const string &nodeName)
util functions that wrap rapidxml
Definition: xmlutils.cpp:132
static void checkNode(XMLNode *n, const string &expectedName)
Definition: xmlutils.cpp:175
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 bool getChildValueAsBool(XMLNode *node, const string &name, bool mandatory=false, bool defaultValue=true)
Definition: xmlutils.cpp:296
static XMLNode * getChildNode(XMLNode *n, const string &name="")
Definition: xmlutils.cpp:387
static XMLNode * addChild(XMLDocument &doc, XMLNode *n, const string &name)
Definition: xmlutils.cpp:181
Date parseDate(const string &s)
Convert std::string to QuantLib::Date.
Definition: parsers.cpp:51
Real parseReal(const string &s)
Convert text to Real.
Definition: parsers.cpp:112
ibor fallback configuration
Classes and functions for log message handling.
@ data
Definition: log.hpp:77
#define DLOG(text)
Logging Macro (Level = Debug)
Definition: log.hpp:554
std::string to_string(const LocationInfo &l)
Definition: ast.cpp:28
Serializable Credit Default Swap.
Definition: namespaces.docs:23
Map text representations to QuantLib/QuantExt types.
Class for structured configuration warnings.
string conversion utilities