Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
marketdata.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2020 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
26
27#include <boost/algorithm/string.hpp>
28
29using QuantLib::DefaultProbabilityTermStructure;
30using QuantLib::Handle;
31using QuantLib::YieldTermStructure;
32using std::string;
33
34namespace ore {
35namespace data {
36
37const string xccyCurveNamePrefix = "__XCCY__";
38
39string xccyCurveName(const string& ccyCode) { return xccyCurveNamePrefix + "-" + ccyCode; }
40
41Handle<YieldTermStructure> xccyYieldCurve(const QuantLib::ext::shared_ptr<Market>& market, const string& ccyCode,
42 const string& configuration) {
43 bool dummy;
44 return xccyYieldCurve(market, ccyCode, dummy, configuration);
45}
46
47Handle<YieldTermStructure> xccyYieldCurve(const QuantLib::ext::shared_ptr<Market>& market, const string& ccyCode,
48 bool& outXccyExists, const string& configuration) {
49
50 Handle<YieldTermStructure> curve;
51 string xccyCurve = xccyCurveName(ccyCode);
52 outXccyExists = true;
53 try {
54 curve = market->yieldCurve(xccyCurve, configuration);
55 } catch (const Error&) {
56 DLOG("Could not link " << ccyCode << " termstructure to cross currency yield curve " << xccyCurve
57 << " so just using " << ccyCode << " discount curve.");
58 curve = market->discountCurve(ccyCode, configuration);
59 outXccyExists = false;
60 }
61
62 return curve;
63}
64
65Handle<YieldTermStructure> indexOrYieldCurve(const QuantLib::ext::shared_ptr<Market>& market, const std::string& name,
66 const std::string& configuration) {
67 try {
68 return market->iborIndex(name, configuration)->forwardingTermStructure();
69 } catch (...) {
70 }
71 try {
72 return market->yieldCurve(name, configuration);
73 } catch (...) {
74 }
75 QL_FAIL("Could not find index or yield curve with name '" << name << "' under configuration '" << configuration
76 << "' or default configuration.");
77}
78
79std::string securitySpecificCreditCurveName(const std::string& securityId, const std::string& creditCurveId) {
80 auto tmp = "__SECCRCRV_" + securityId + "_&_" + creditCurveId + "_&_";
81 return tmp;
82}
83
85 if (boost::starts_with(name, "__SECCRCRV_")) {
86 std::size_t pos = name.find("_&_", 11);
87 if (pos != std::string::npos) {
88 std::size_t pos2 = name.find("_&_", pos + 3);
89 if (pos2 != std::string::npos) {
90 auto tmp = name.substr(pos + 3, pos2 - (pos + 3));
91 return tmp;
92 }
93 }
94 }
95 return name;
96}
97
98QuantLib::Handle<QuantExt::CreditCurve> securitySpecificCreditCurve(const QuantLib::ext::shared_ptr<Market>& market,
99 const std::string& securityId,
100 const std::string& creditCurveId,
101 const std::string& configuration) {
102 Handle<QuantExt::CreditCurve> curve;
103 std::string name = securitySpecificCreditCurveName(securityId, creditCurveId);
104 try {
105 curve = market->defaultCurve(name, configuration);
106 } catch (const std::exception&) {
107 DLOG("Could not link " << securityId << " to security specific credit curve " << name << " so just using "
108 << creditCurveId << " default curve.");
109 curve = market->defaultCurve(creditCurveId, configuration);
110 }
111 return curve;
112}
113
114std::string prettyPrintInternalCurveName(std::string name) {
115 std::size_t pos = 0;
116 bool found;
117 do {
118 found = false;
119 std::size_t pos2 = name.find("__SECCRCRV_", pos);
120 if (pos2 != std::string::npos) {
121 std::size_t pos3 = name.find("_&_", pos2);
122 if (pos3 != std::string::npos) {
123 std::size_t pos4 = name.find("_&_", pos3 + 3);
124 if (pos4 != std::string::npos) {
125 name.replace(pos2, pos4 + 3 - pos2,
126 name.substr(pos2 + 11, pos3 - (pos2 + 11)) + "(" +
127 name.substr(pos3 + 3, pos4 - (pos3 + 3)) + ")");
128 pos = pos + (pos4 - pos2 - 12);
129 found = true;
130 }
131 }
132 }
133 } while (found);
134 return name;
135}
136
137QuantLib::ext::shared_ptr<QuantExt::FxIndex> buildFxIndex(const string& fxIndex, const string& domestic, const string& foreign,
138 const QuantLib::ext::shared_ptr<Market>& market, const string& configuration,
139 bool useXbsCurves) {
140
141 auto fxInd = parseFxIndex(fxIndex);
142
143 string source = fxInd->sourceCurrency().code();
144 string target = fxInd->targetCurrency().code();
145 string family = fxInd->familyName();
146
147 fxInd = *market->fxIndex("FX-" + family + "-" + foreign + "-" + domestic);
148
149 QL_REQUIRE((domestic == target && foreign == source) || (domestic == source && foreign == target),
150 "buildFxIndex(): index '" << fxIndex << "' does not match given currencies " << domestic << ", "
151 << foreign);
152
153 if (!useXbsCurves)
154 return fxInd;
155
156 return fxInd->clone(Handle<Quote>(), xccyYieldCurve(market, foreign, configuration),
157 xccyYieldCurve(market, domestic, configuration));
158}
159
160std::tuple<Natural, Calendar, BusinessDayConvention> getFxIndexConventions(const string& index) {
161 // can take an fx index or ccy pair e.g. EURUSD
162 string ccy1, ccy2;
163 string fixingSource;
164 if (isFxIndex(index)) {
165 auto ind = parseFxIndex(index);
166 ccy1 = ind->sourceCurrency().code();
167 ccy2 = ind->targetCurrency().code();
168 fixingSource = ind->familyName();
169 } else {
170 QL_REQUIRE(index.size() == 6, "getFxIndexConventions: index must be an FXIndex of form FX-ECB-EUR-USD, "
171 << "or a currency pair e.g. EURUSD, got '" + index + "'");
172 ccy1 = index.substr(0, 3);
173 ccy2 = index.substr(3);
174 fixingSource = "GENERIC";
175 }
176
177 if (ccy1 == ccy2)
178 return std::make_tuple(0, NullCalendar(), Unadjusted);
179
180 const QuantLib::ext::shared_ptr<Conventions>& conventions = InstrumentConventions::instance().conventions();
181 QuantLib::ext::shared_ptr<Convention> con;
182 // first look for the index and inverse index directly
183 try {
184 con = conventions->get("FX-" + fixingSource + "-" + ccy1 + "-" + ccy2);
185 } catch (...) {
186 }
187 if (con == nullptr) {
188 try {
189 con = conventions->get("FX-" + fixingSource + "-" + ccy2 + "-" + ccy1);
190 } catch (...) {
191 }
192 }
193 // then by currency pair and inverse currency pair (getFxConvention() handles both)
194 if (con == nullptr) {
195 try {
196 con = conventions->getFxConvention(ccy1, ccy2);
197 } catch (...) {
198 }
199 }
200 if (auto fxCon = QuantLib::ext::dynamic_pointer_cast<FXConvention>(con)) {
201 TLOG("getFxIndexConvention(" << index << "): " << fxCon->spotDays() << " / " << fxCon->advanceCalendar().name()
202 << " from convention.");
203 return std::make_tuple(fxCon->spotDays(), fxCon->advanceCalendar(), fxCon->convention());
204 } else if (auto comCon = QuantLib::ext::dynamic_pointer_cast<CommodityForwardConvention>(con); comCon !=nullptr
205 && (isPseudoCurrency(ccy1) || isPseudoCurrency(ccy2))) {
206 TLOG("getFxIndexConvention(" << index << "): " << fxCon->spotDays() << " / " << fxCon->advanceCalendar().name()
207 << " from convention.");
208 return std::make_tuple(0, comCon->advanceCalendar(), comCon->bdc());
209 }
210
211 // default calendar for pseudo currencies is USD
212 if (isPseudoCurrency(ccy1))
213 ccy1 = "USD";
214 if (isPseudoCurrency(ccy2))
215 ccy2 = "USD";
216
217 try {
218 Calendar cal = parseCalendar(ccy1 + "," + ccy2);
219 TLOG("getFxIndexConvention(" << index << "): 2 (default) / " << cal.name()
220 << " (from ccys), no convention found.");
221 return std::make_tuple(2, cal, Following);
222 } catch (const std::exception& e) {
223 ALOG("could not get fx index convention for '" << index << "': " << e.what() << ", continue with 'USD'");
224 }
225 TLOG("getFxIndexConvention(" << index
226 << "): 2 (default) / USD (default), no convention found, could not parse calendar '"
227 << (ccy1 + "," + ccy2) << "'");
228 return std::make_tuple(2, parseCalendar("USD"), Following);
229}
230
231std::pair<std::string, QuantLib::Period> splitCurveIdWithTenor(const std::string& creditCurveId) {
232 Size pos = creditCurveId.rfind("_");
233 if (pos != std::string::npos) {
234 Period term;
235 string termString = creditCurveId.substr(pos + 1, creditCurveId.length());
236 if (tryParse<Period>(termString, term, parsePeriod)) {
237 return make_pair(creditCurveId.substr(0, pos), term);
238 }
239 }
240 return make_pair(creditCurveId, 0 * Days);
241}
242
243QuantLib::Handle<QuantExt::CreditCurve> indexCdsDefaultCurve(const QuantLib::ext::shared_ptr<Market>& market,
244 const std::string& creditCurveId,
245 const std::string& config) {
246 try {
247 return market->defaultCurve(creditCurveId, config);
248 } catch (...) {
249 DLOG("indexCdsDefaultCurve: could not get '" << creditCurveId << "', fall back on curve id without tenor.");
250 }
251
252 auto p = splitCurveIdWithTenor(creditCurveId);
253 return market->defaultCurve(p.first, config);
254}
255
256} // namespace data
257} // namespace ore
Currency and instrument specific conventions/defaults.
currency parser singleton class
Calendar parseCalendar(const string &s)
Convert text to QuantLib::Calendar.
Definition: parsers.cpp:157
QuantLib::ext::shared_ptr< FxIndex > parseFxIndex(const string &s, const Handle< Quote > &fxSpot, const Handle< YieldTermStructure > &sourceYts, const Handle< YieldTermStructure > &targetYts, const bool useConventions)
Convert std::string to QuantExt::FxIndex.
Period parsePeriod(const string &s)
Convert text to QuantLib::Period.
Definition: parsers.cpp:171
bool isPseudoCurrency(const string &code)
check for pseudo currency = precious metal or crypto currency *‍/
Definition: parsers.cpp:318
Map text representations to QuantLib/QuantExt types.
Classes and functions for log message handling.
@ data
Definition: log.hpp:77
#define DLOG(text)
Logging Macro (Level = Debug)
Definition: log.hpp:554
#define ALOG(text)
Logging Macro (Level = Alert)
Definition: log.hpp:544
#define TLOG(text)
Logging Macro (Level = Data)
Definition: log.hpp:556
market data related utilties
Handle< YieldTermStructure > xccyYieldCurve(const QuantLib::ext::shared_ptr< Market > &market, const string &ccyCode, const string &configuration)
Definition: marketdata.cpp:41
bool isFxIndex(const std::string &indexName)
std::string creditCurveNameFromSecuritySpecificCreditCurveName(const std::string &name)
Definition: marketdata.cpp:84
QuantLib::Handle< QuantExt::CreditCurve > indexCdsDefaultCurve(const QuantLib::ext::shared_ptr< Market > &market, const std::string &creditCurveId, const std::string &config)
Definition: marketdata.cpp:243
std::string prettyPrintInternalCurveName(std::string name)
Definition: marketdata.cpp:114
Handle< YieldTermStructure > indexOrYieldCurve(const QuantLib::ext::shared_ptr< Market > &market, const std::string &name, const std::string &configuration)
Definition: marketdata.cpp:65
string xccyCurveName(const string &ccyCode)
Definition: marketdata.cpp:39
std::tuple< Natural, Calendar, BusinessDayConvention > getFxIndexConventions(const string &index)
Definition: marketdata.cpp:160
std::pair< std::string, QuantLib::Period > splitCurveIdWithTenor(const std::string &creditCurveId)
Definition: marketdata.cpp:231
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
QuantLib::ext::shared_ptr< QuantExt::FxIndex > buildFxIndex(const string &fxIndex, const string &domestic, const string &foreign, const QuantLib::ext::shared_ptr< Market > &market, const string &configuration, bool useXbsCurves)
Definition: marketdata.cpp:137
const string xccyCurveNamePrefix
Definition: marketdata.cpp:37
std::string securitySpecificCreditCurveName(const std::string &securityId, const std::string &creditCurveId)
Definition: marketdata.cpp:79
Serializable Credit Default Swap.
Definition: namespaces.docs:23
Map text representations to QuantLib/QuantExt types.
string conversion utilities
string name