25#include <boost/algorithm/string.hpp>
26#include <boost/make_shared.hpp>
27#include <boost/regex.hpp>
37#include <ql/errors.hpp>
38#include <ql/indexes/all.hpp>
39#include <ql/time/calendars/target.hpp>
40#include <ql/time/daycounters/all.hpp>
120class IborIndexParser {
122 virtual ~IborIndexParser() {}
123 virtual QuantLib::ext::shared_ptr<IborIndex> build(Period p,
const Handle<YieldTermStructure>& h)
const = 0;
124 virtual string family()
const = 0;
128template <
class T>
class IborIndexParserWithPeriod :
public IborIndexParser {
130 QuantLib::ext::shared_ptr<IborIndex> build(Period p,
const Handle<YieldTermStructure>& h)
const override {
131 return QuantLib::ext::make_shared<T>(p, h);
133 string family()
const override {
return T(3 * Months).familyName(); }
140template <>
class IborIndexParserWithPeriod<
MXNTiie> :
public IborIndexParser {
142 QuantLib::ext::shared_ptr<IborIndex> build(Period p,
const Handle<YieldTermStructure>& h)
const override {
143 if (p.units() == Days && p.length() == 28) {
144 return QuantLib::ext::make_shared<MXNTiie>(4 * Weeks, h);
145 }
else if (p.units() == Days && p.length() == 91) {
146 return QuantLib::ext::make_shared<MXNTiie>(3 * Months, h);
147 }
else if (p.units() == Days && (p.length() >= 180 || p.length() <= 183)) {
148 return QuantLib::ext::make_shared<MXNTiie>(6 * Months, h);
150 return QuantLib::ext::make_shared<MXNTiie>(p, h);
154 string family()
const override {
return MXNTiie(4 * Weeks).familyName(); }
159template <>
class IborIndexParserWithPeriod<
KRWCd> :
public IborIndexParser {
161 QuantLib::ext::shared_ptr<IborIndex> build(Period p,
const Handle<YieldTermStructure>& h)
const override {
162 if (p.units() == Days && p.length() == 91) {
163 return QuantLib::ext::make_shared<KRWCd>(3 * Months, h);
165 return QuantLib::ext::make_shared<KRWCd>(p, h);
169 string family()
const override {
return KRWCd(3 * Months).familyName(); }
175template <>
class IborIndexParserWithPeriod<
CNYRepoFix> :
public IborIndexParser {
177 QuantLib::ext::shared_ptr<IborIndex> build(Period p,
const Handle<YieldTermStructure>& h)
const override {
178 if (p.units() == Days && p.length() == 7) {
179 return QuantLib::ext::make_shared<CNYRepoFix>(1 * Weeks, h);
180 }
else if (p.units() == Days && p.length() == 14) {
181 return QuantLib::ext::make_shared<CNYRepoFix>(2 * Weeks, h);
183 return QuantLib::ext::make_shared<CNYRepoFix>(p, h);
187 string family()
const override {
return CNYRepoFix(1 * Weeks).familyName(); }
191void checkOneToOne(
const map<
string, QuantLib::ext::shared_ptr<OvernightIndex>>& onIndices,
192 const map<
string, QuantLib::ext::shared_ptr<IborIndexParser>>& iborIndices) {
195 set<string> familyNames;
197 for (
const auto& kv : onIndices) {
198 auto p = familyNames.insert(kv.second->familyName());
199 QL_REQUIRE(p.second,
"Duplicate mapping for overnight index family " << *p.first <<
" not allowed");
202 for (
const auto& kv : iborIndices) {
203 auto p = familyNames.insert(kv.second->family());
204 QL_REQUIRE(p.second,
"Duplicate mapping for ibor index family " << *p.first <<
" not allowed");
208QuantLib::ext::shared_ptr<FxIndex>
parseFxIndex(
const string& s,
const Handle<Quote>& fxSpot,
209 const Handle<YieldTermStructure>& sourceYts,
210 const Handle<YieldTermStructure>& targetYts,
const bool useConventions) {
211 std::vector<string> tokens;
212 split(tokens, s, boost::is_any_of(
"-"));
213 QL_REQUIRE(tokens.size() == 4,
"four tokens required in " << s <<
": FX-TAG-CCY1-CCY2");
214 QL_REQUIRE(tokens[0] ==
"FX",
"expected first token to be FX");
215 Natural fixingDays = 0;
216 Calendar fixingCalendar = NullCalendar();
217 BusinessDayConvention bdc;
221 fixingCalendar, fxSpot, sourceYts, targetYts);
223 IndexNameTranslator::instance().add(index->name(), s);
228 std::vector<string> tokens;
229 split(tokens, s, boost::is_any_of(
"-"));
230 QL_REQUIRE(tokens.size() == 2,
"two tokens required in " << s <<
": EQ-NAME");
231 QL_REQUIRE(tokens[0] ==
"EQ",
"expected first token to be EQ");
232 auto index = QuantLib::ext::make_shared<QuantExt::EquityIndex2>(tokens[1], NullCalendar(), Currency());
233 IndexNameTranslator::instance().add(index->name(), s);
238 QL_REQUIRE(boost::starts_with(s,
"GENERIC-"),
"generic index expected to be of the form GENERIC-*");
239 auto index = QuantLib::ext::make_shared<GenericIndex>(s);
240 IndexNameTranslator::instance().add(index->name(), s);
247 }
catch (
const std::exception& e) {
248 DLOG(
"tryParseIborIndex(" << s <<
") failed: " << e.what());
254QuantLib::ext::shared_ptr<IborIndex>
parseIborIndex(
const string& s,
const Handle<YieldTermStructure>& h) {
259QuantLib::ext::shared_ptr<IborIndex>
parseIborIndex(
const string& s,
string& tenor,
const Handle<YieldTermStructure>& h) {
262 vector<string> tokens;
263 split(tokens, s, boost::is_any_of(
"-"));
264 QL_REQUIRE(tokens.size() == 2 || tokens.size() == 3,
265 "Two or three tokens required in " << s <<
": CCY-INDEX or CCY-INDEX-TERM");
268 string indexStem = tokens[0] +
"-" + tokens[1];
269 if (tokens.size() == 3) {
275 const QuantLib::ext::shared_ptr<Conventions>& conventions = InstrumentConventions::instance().conventions();
276 QuantLib::ext::shared_ptr<Convention> c;
278 c = conventions->get(s);
283 QL_REQUIRE(c->id() == s,
"ibor index convention id ('"
284 << c->id() <<
"') not matching ibor index string to parse ('" << s <<
"'");
286 if (
auto conv = QuantLib::ext::dynamic_pointer_cast<OvernightIndexConvention>(c)) {
287 QL_REQUIRE(tenor.empty(),
"no tenor allowed for convention based overnight index ('" << s <<
"')");
288 auto res = QuantLib::ext::make_shared<OvernightIndex>(tokens[0] +
"-" + tokens[1], conv->settlementDays(), ccy,
291 IndexNameTranslator::instance().add(res->name(), s);
293 }
else if (
auto conv = QuantLib::ext::dynamic_pointer_cast<IborIndexConvention>(c)) {
294 QL_REQUIRE(!tenor.empty(),
"no tenor given for convention based Ibor index ('" << s <<
"'");
295 auto res = QuantLib::ext::make_shared<IborIndex>(tokens[0] +
"-" + tokens[1],
parsePeriod(tenor),
296 conv->settlementDays(), ccy,
parseCalendar(conv->fixingCalendar()),
299 IndexNameTranslator::instance().add(res->name(), s);
302 QL_FAIL(
"invalid convention passed to parseIborIndex(): expected OvernightIndexConvention or "
303 "IborIndexConvention");
310 static map<string, QuantLib::ext::shared_ptr<OvernightIndex>> onIndices = {
311 {
"EUR-EONIA", QuantLib::ext::make_shared<Eonia>()},
312 {
"EUR-ESTER", QuantLib::ext::make_shared<Estr>()},
313 {
"GBP-SONIA", QuantLib::ext::make_shared<Sonia>()},
314 {
"JPY-TONAR", QuantLib::ext::make_shared<Tonar>()},
315 {
"SGD-SORA", QuantLib::ext::make_shared<Sora>()},
316 {
"CHF-TOIS", QuantLib::ext::make_shared<CHFTois>()},
317 {
"CHF-SARON", QuantLib::ext::make_shared<CHFSaron>()},
318 {
"USD-FedFunds", QuantLib::ext::make_shared<FedFunds>()},
319 {
"USD-SOFR", QuantLib::ext::make_shared<Sofr>()},
320 {
"USD-Prime", QuantLib::ext::make_shared<PrimeIndex>()},
321 {
"USD-AMERIBOR", QuantLib::ext::make_shared<USDAmeribor>()},
322 {
"AUD-AONIA", QuantLib::ext::make_shared<Aonia>()},
323 {
"CAD-CORRA", QuantLib::ext::make_shared<CORRA>()},
324 {
"DKK-DKKOIS", QuantLib::ext::make_shared<DKKOis>()},
325 {
"SEK-SIOR", QuantLib::ext::make_shared<SEKSior>()},
326 {
"COP-IBR", QuantLib::ext::make_shared<COPIbr>()},
327 {
"BRL-CDI", QuantLib::ext::make_shared<BRLCdi>()},
328 {
"NOK-NOWA", QuantLib::ext::make_shared<Nowa>()},
329 {
"CLP-CAMARA", QuantLib::ext::make_shared<CLPCamara>()},
330 {
"NZD-OCR", QuantLib::ext::make_shared<Nzocr>()},
331 {
"PLN-POLONIA", QuantLib::ext::make_shared<PLNPolonia>()},
332 {
"INR-MIBOROIS", QuantLib::ext::make_shared<INRMiborOis>()},
333 {
"GBP-BoEBase", QuantLib::ext::make_shared<BOEBaseRateIndex>()},
334 {
"HKD-HONIA", QuantLib::ext::make_shared<HKDHonia>()},
335 {
"SEK-STINA", QuantLib::ext::make_shared<SEKStina>()},
336 {
"DKK-CITA", QuantLib::ext::make_shared<DKKCita>()},
337 {
"THB-THOR", QuantLib::ext::make_shared<THBThor>()}};
340 static map<string, QuantLib::ext::shared_ptr<IborIndexParser>> iborIndices = {
341 {
"AUD-BBSW", QuantLib::ext::make_shared<IborIndexParserWithPeriod<Bbsw>>()},
342 {
"AUD-LIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<AUDLibor>>()},
343 {
"EUR-EURIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<Euribor>>()},
344 {
"EUR-EURIBOR365", QuantLib::ext::make_shared<IborIndexParserWithPeriod<Euribor365>>()},
345 {
"CAD-CDOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<Cdor>>()},
346 {
"CNY-SHIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<Shibor>>()},
347 {
"CZK-PRIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<CZKPribor>>()},
348 {
"EUR-LIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<EURLibor>>()},
349 {
"USD-AMBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<USDAmbor>>()},
350 {
"USD-LIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<USDLibor>>()},
351 {
"GBP-LIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<GBPLibor>>()},
352 {
"JPY-LIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<JPYLibor>>()},
353 {
"JPY-TIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<Tibor>>()},
354 {
"JPY-EYTIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<JPYEYTIBOR>>()},
355 {
"CAD-LIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<CADLibor>>()},
356 {
"CHF-LIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<CHFLibor>>()},
357 {
"SEK-LIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<SEKLibor>>()},
358 {
"SEK-STIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<SEKStibor>>()},
359 {
"NOK-NIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<NOKNibor>>()},
360 {
"HKD-HIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<HKDHibor>>()},
361 {
"CNH-HIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<CNHHibor>>()},
362 {
"CNH-SHIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<CNHShibor>>()},
363 {
"SAR-SAIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<SAibor>>()},
364 {
"SGD-SIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<SGDSibor>>()},
365 {
"SGD-SOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<SGDSor>>()},
366 {
"DKK-CIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<DKKCibor>>()},
367 {
"DKK-LIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<DKKLibor>>()},
368 {
"HUF-BUBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<HUFBubor>>()},
369 {
"IDR-IDRFIX", QuantLib::ext::make_shared<IborIndexParserWithPeriod<IDRIdrfix>>()},
370 {
"IDR-JIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<IDRJibor>>()},
371 {
"ILS-TELBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<ILSTelbor>>()},
372 {
"INR-MIFOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<INRMifor>>()},
373 {
"MXN-TIIE", QuantLib::ext::make_shared<IborIndexParserWithPeriod<MXNTiie>>()},
374 {
"PLN-WIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<Wibor>>()},
375 {
"SKK-BRIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<SKKBribor>>()},
376 {
"NZD-BKBM", QuantLib::ext::make_shared<IborIndexParserWithPeriod<NZDBKBM>>()},
377 {
"TRY-TRLIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<TRLibor>>()},
378 {
"TWD-TAIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<TWDTaibor>>()},
379 {
"MYR-KLIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<MYRKlibor>>()},
380 {
"KRW-CD", QuantLib::ext::make_shared<IborIndexParserWithPeriod<KRWCd>>()},
381 {
"KRW-KORIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<KRWKoribor>>()},
382 {
"ZAR-JIBAR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<Jibar>>()},
383 {
"RUB-MOSPRIME", QuantLib::ext::make_shared<IborIndexParserWithPeriod<Mosprime>>()},
384 {
"RUB-KEYRATE", QuantLib::ext::make_shared<IborIndexParserWithPeriod<RUBKeyRate>>()},
385 {
"THB-BIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<THBBibor>>()},
386 {
"THB-THBFIX", QuantLib::ext::make_shared<IborIndexParserWithPeriod<THBFIX>>()},
387 {
"PHP-PHIREF", QuantLib::ext::make_shared<IborIndexParserWithPeriod<PHPPhiref>>()},
388 {
"RON-ROBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<Robor>>()},
389 {
"DEM-LIBOR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<DEMLibor>>()},
390 {
"CNY-REPOFIX", QuantLib::ext::make_shared<IborIndexParserWithPeriod<CNYRepoFix>>()},
391 {
"USD-SOFR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<QuantExt::SofrTerm>>()},
392 {
"GBP-SONIA", QuantLib::ext::make_shared<IborIndexParserWithPeriod<QuantExt::SoniaTerm>>()},
393 {
"JPY-TONAR", QuantLib::ext::make_shared<IborIndexParserWithPeriod<QuantExt::TonarTerm>>()},
394 {
"CAD-CORRA", QuantLib::ext::make_shared<IborIndexParserWithPeriod<QuantExt::CORRATerm>>()}};
397 static bool checked =
false;
404 if (indexStem ==
"USD-SIFMA") {
405 QL_REQUIRE(tenor.empty(),
"A tenor is not allowed with USD-SIFMA as it is implied");
406 auto res = QuantLib::ext::make_shared<BMAIndexWrapper>(QuantLib::ext::make_shared<BMAIndex>(h));
407 IndexNameTranslator::instance().add(res->name(), s);
412 auto it = iborIndices.find(indexStem);
413 if (it != iborIndices.end() && !tenor.empty()) {
415 auto res = it->second->build(p, h);
416 IndexNameTranslator::instance().add(res->name(), s);
421 auto onIt = onIndices.find(indexStem);
422 if (onIt != onIndices.end()) {
423 QL_REQUIRE(tenor.empty(),
424 "A tenor is not allowed with the overnight index " << indexStem <<
" as it is implied");
425 auto res = onIt->second->clone(h);
426 IndexNameTranslator::instance().add(res->name(), s);
431 if (tokens[1] ==
"GENERIC") {
434 auto res = QuantLib::ext::make_shared<GenericIborIndex>(p, ccy, h);
435 IndexNameTranslator::instance().add(res->name(), s);
439 QL_FAIL(
"parseIborIndex \"" << s <<
"\" not recognized");
442bool isGenericIborIndex(
const string& indexName) {
return indexName.find(
"-GENERIC-") != string::npos; }
444pair<bool, QuantLib::ext::shared_ptr<ZeroInflationIndex>>
isInflationIndex(
const string& indexName) {
446 QuantLib::ext::shared_ptr<ZeroInflationIndex> index;
451 return make_pair(
false,
nullptr);
453 return make_pair(
true, index);
485class SwapIndexParser {
487 virtual ~SwapIndexParser() {}
488 virtual QuantLib::ext::shared_ptr<SwapIndex> build(Period p,
const Handle<YieldTermStructure>& f,
489 const Handle<YieldTermStructure>& d)
const = 0;
493template <
class T>
class SwapIndexParserDualCurve :
public SwapIndexParser {
495 QuantLib::ext::shared_ptr<SwapIndex> build(Period p,
const Handle<YieldTermStructure>& f,
496 const Handle<YieldTermStructure>& d)
const override {
497 return QuantLib::ext::make_shared<T>(p, f, d);
501QuantLib::ext::shared_ptr<SwapIndex>
parseSwapIndex(
const string& s,
const Handle<YieldTermStructure>& f,
502 const Handle<YieldTermStructure>& d) {
504 std::vector<string> tokens;
505 split(tokens, s, boost::is_any_of(
"-"));
506 QL_REQUIRE(tokens.size() == 3 || tokens.size() == 4,
507 "three or four tokens required in " << s <<
": CCY-CMS-TENOR or CCY-CMS-TAG-TENOR");
508 QL_REQUIRE(tokens[0].
size() == 3,
"invalid currency code in " << s);
509 QL_REQUIRE(tokens[1] ==
"CMS",
"expected CMS as middle token in " << s);
512 string familyName = tokens.size() == 4 ? tokens[0] +
"-CMS-" + tokens[2] : tokens[0] +
"LiborSwapIsdaFix";
515 const QuantLib::ext::shared_ptr<Conventions>& conventions = InstrumentConventions::instance().conventions();
516 QuantLib::ext::shared_ptr<SwapIndexConvention> swapIndexConvention;
517 QuantLib::ext::shared_ptr<IRSwapConvention> irSwapConvention;
518 QuantLib::ext::shared_ptr<OisConvention> oisCompConvention;
519 QuantLib::ext::shared_ptr<AverageOisConvention> oisAvgConvention;
521 swapIndexConvention = QuantLib::ext::dynamic_pointer_cast<SwapIndexConvention>(conventions->get(s));
522 QL_REQUIRE(swapIndexConvention,
"internal error: could not cast to SwapIndexConvention");
526 "do not have swap or ois conventions for '"
527 << swapIndexConvention->conventions() <<
"', required from swap index convention '" << s <<
"'");
529 QuantLib::ext::dynamic_pointer_cast<IRSwapConvention>(conventions->get(swapIndexConvention->conventions()));
531 QuantLib::ext::dynamic_pointer_cast<OisConvention>(conventions->get(swapIndexConvention->conventions()));
533 QuantLib::ext::dynamic_pointer_cast<AverageOisConvention>(conventions->get(swapIndexConvention->conventions()));
534 QL_REQUIRE(irSwapConvention || oisCompConvention || oisAvgConvention,
535 "internal error: could not cast to IRSwapConvention, OisConvention, AverageOisConvention");
538 irSwapConvention = QuantLib::ext::make_shared<IRSwapConvention>(
"dummy_swap_conv_" + tokens[0], tokens[0],
"Annual",
539 "MF",
"A365", tokens[0] +
"-GENERIC-3M");
540 swapIndexConvention = QuantLib::ext::make_shared<SwapIndexConvention>(
"dummy_swapindex_conv_" + tokens[0],
541 "dummy_swap_conv_" + tokens[0],
"");
544 QuantLib::ext::shared_ptr<SwapIndex> index;
545 if (irSwapConvention) {
546 Calendar fixingCalendar = swapIndexConvention->fixingCalendar().empty()
547 ? irSwapConvention->fixedCalendar()
549 index = QuantLib::ext::make_shared<SwapIndex>(familyName, p, irSwapConvention->index()->fixingDays(), ccy,
550 fixingCalendar, Period(irSwapConvention->fixedFrequency()),
551 irSwapConvention->fixedConvention(), irSwapConvention->fixedDayCounter(),
552 irSwapConvention->index()->clone(f), d);
553 }
else if (oisCompConvention) {
554 Calendar fixingCalendar = swapIndexConvention->fixingCalendar().empty()
555 ? oisCompConvention->index()->fixingCalendar()
557 index = QuantLib::ext::make_shared<OvernightIndexedSwapIndex>(
558 familyName, p, oisCompConvention->spotLag(), ccy,
559 QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(oisCompConvention->index()->clone(f)),
true,
560 RateAveraging::Compound, Period(oisCompConvention->fixedFrequency()), d);
561 }
else if (oisAvgConvention) {
562 Calendar fixingCalendar = swapIndexConvention->fixingCalendar().empty()
563 ? oisAvgConvention->index()->fixingCalendar()
565 auto index = QuantLib::ext::make_shared<OvernightIndexedSwapIndex>(
566 familyName, p, oisAvgConvention->spotLag(), ccy,
567 QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(oisAvgConvention->index()->clone(f)),
true,
568 RateAveraging::Simple, Period(oisAvgConvention->fixedFrequency()), d);
569 IndexNameTranslator::instance().add(index->name(), s);
572 QL_FAIL(
"internal error: expected irSwapConvention, oisConvention, averageOisConvention to be not null");
574 IndexNameTranslator::instance().add(index->name(), s);
579class ZeroInflationIndexParserBase {
581 virtual ~ZeroInflationIndexParserBase() {}
582 virtual QuantLib::ext::shared_ptr<ZeroInflationIndex> build(
const Handle<ZeroInflationTermStructure>& h)
const = 0;
583 virtual QL_DEPRECATED QuantLib::ext::shared_ptr<ZeroInflationIndex>
584 build(
bool isInterpolated,
const Handle<ZeroInflationTermStructure>& h)
const = 0;
587template <
class T>
class ZeroInflationIndexParser :
public ZeroInflationIndexParserBase {
589 QuantLib::ext::shared_ptr<ZeroInflationIndex> build(
const Handle<ZeroInflationTermStructure>& h)
const override {
590 return QuantLib::ext::make_shared<T>(h);
593 QL_DEPRECATED QuantLib::ext::shared_ptr<ZeroInflationIndex> build(
bool isInterpolated,
594 const Handle<ZeroInflationTermStructure>& h)
const override {
595 return QuantLib::ext::make_shared<T>(isInterpolated, h);
599template <
class T>
class ZeroInflationIndexParserWithFrequency :
public ZeroInflationIndexParserBase {
601 ZeroInflationIndexParserWithFrequency(Frequency frequency) : frequency_(frequency) {}
603 QuantLib::ext::shared_ptr<ZeroInflationIndex> build(
const Handle<ZeroInflationTermStructure>& h)
const override {
604 return QuantLib::ext::make_shared<T>(frequency_,
false, h);
607 QuantLib::ext::shared_ptr<ZeroInflationIndex> build(
bool isInterpolated,
608 const Handle<ZeroInflationTermStructure>& h)
const override {
609 return QuantLib::ext::make_shared<T>(frequency_,
false, isInterpolated, h);
613 Frequency frequency_;
617 const Handle<ZeroInflationTermStructure>& h) {
618 const QuantLib::ext::shared_ptr<Conventions>& conventions = InstrumentConventions::instance().conventions();
625 auto c = QuantLib::ext::dynamic_pointer_cast<ZeroInflationIndexConvention>(p.second);
626 auto index = QuantLib::ext::make_shared<ZeroInflationIndex>(s, c->region(), c->revised(),
627 c->frequency(), c->availabilityLag(), c->currency(), h);
628 IndexNameTranslator::instance().add(index->name(), s);
633 static map<string, QuantLib::ext::shared_ptr<ZeroInflationIndexParserBase>> m = {
634 {
"AUCPI", QuantLib::ext::make_shared<ZeroInflationIndexParserWithFrequency<AUCPI>>(Quarterly)},
635 {
"AU CPI", QuantLib::ext::make_shared<ZeroInflationIndexParserWithFrequency<AUCPI>>(Quarterly)},
636 {
"BEHICP", QuantLib::ext::make_shared<ZeroInflationIndexParser<BEHICP>>()},
637 {
"BE HICP", QuantLib::ext::make_shared<ZeroInflationIndexParser<BEHICP>>()},
638 {
"EUHICP", QuantLib::ext::make_shared<ZeroInflationIndexParser<EUHICP>>()},
639 {
"EU HICP", QuantLib::ext::make_shared<ZeroInflationIndexParser<EUHICP>>()},
640 {
"EUHICPXT", QuantLib::ext::make_shared<ZeroInflationIndexParser<EUHICPXT>>()},
641 {
"EU HICPXT", QuantLib::ext::make_shared<ZeroInflationIndexParser<EUHICPXT>>()},
642 {
"FRHICP", QuantLib::ext::make_shared<ZeroInflationIndexParser<FRHICP>>()},
643 {
"FR HICP", QuantLib::ext::make_shared<ZeroInflationIndexParser<FRHICP>>()},
644 {
"FRCPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<FRCPI>>()},
645 {
"FR CPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<FRCPI>>()},
646 {
"UKRPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<UKRPI>>()},
647 {
"UK RPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<UKRPI>>()},
648 {
"USCPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<USCPI>>()},
649 {
"US CPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<USCPI>>()},
650 {
"ZACPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<ZACPI>>()},
651 {
"ZA CPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<ZACPI>>()},
652 {
"SECPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<SECPI>>()},
653 {
"DKCPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<DKCPI>>()},
654 {
"CACPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<CACPI>>()},
655 {
"ESCPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<ESCPI>>()},
656 {
"DECPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<DECPI>>()},
657 {
"DE CPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<DECPI>>()}};
661 auto index = it->second->build(h);
662 IndexNameTranslator::instance().add(index->name(), s);
665 QL_FAIL(
"parseZeroInflationIndex: \"" << s <<
"\" not recognized");
672 const Handle<ZeroInflationTermStructure>& h) {
674 const QuantLib::ext::shared_ptr<Conventions>& conventions = InstrumentConventions::instance().conventions();
681 auto c = QuantLib::ext::dynamic_pointer_cast<ZeroInflationIndexConvention>(p.second);
682 auto index = QuantLib::ext::make_shared<ZeroInflationIndex>(s, c->region(), c->revised(), isInterpolated,
683 c->frequency(), c->availabilityLag(), c->currency(), h);
684 IndexNameTranslator::instance().add(index->name(), s);
689 static map<string, QuantLib::ext::shared_ptr<ZeroInflationIndexParserBase>> m = {
690 {
"AUCPI", QuantLib::ext::make_shared<ZeroInflationIndexParserWithFrequency<AUCPI>>(Quarterly)},
691 {
"AU CPI", QuantLib::ext::make_shared<ZeroInflationIndexParserWithFrequency<AUCPI>>(Quarterly)},
692 {
"BEHICP", QuantLib::ext::make_shared<ZeroInflationIndexParser<BEHICP>>()},
693 {
"BE HICP", QuantLib::ext::make_shared<ZeroInflationIndexParser<BEHICP>>()},
694 {
"EUHICP", QuantLib::ext::make_shared<ZeroInflationIndexParser<EUHICP>>()},
695 {
"EU HICP", QuantLib::ext::make_shared<ZeroInflationIndexParser<EUHICP>>()},
696 {
"EUHICPXT", QuantLib::ext::make_shared<ZeroInflationIndexParser<EUHICPXT>>()},
697 {
"EU HICPXT", QuantLib::ext::make_shared<ZeroInflationIndexParser<EUHICPXT>>()},
698 {
"FRHICP", QuantLib::ext::make_shared<ZeroInflationIndexParser<FRHICP>>()},
699 {
"FR HICP", QuantLib::ext::make_shared<ZeroInflationIndexParser<FRHICP>>()},
700 {
"FRCPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<FRCPI>>()},
701 {
"FR CPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<FRCPI>>()},
702 {
"UKRPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<UKRPI>>()},
703 {
"UK RPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<UKRPI>>()},
704 {
"USCPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<USCPI>>()},
705 {
"US CPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<USCPI>>()},
706 {
"ZACPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<ZACPI>>()},
707 {
"ZA CPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<ZACPI>>()},
708 {
"SECPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<SECPI>>()},
709 {
"DKCPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<DKCPI>>()},
710 {
"CACPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<CACPI>>()},
711 {
"ESCPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<ESCPI>>()},
712 {
"DECPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<DECPI>>()},
713 {
"DE CPI", QuantLib::ext::make_shared<ZeroInflationIndexParser<DECPI>>()}
718 QL_DEPRECATED_DISABLE_WARNING
719 auto index = it->second->build(isInterpolated, h);
720 QL_DEPRECATED_ENABLE_WARNING
721 IndexNameTranslator::instance().add(index->name(), s);
724 QL_FAIL(
"parseZeroInflationIndex: \"" << s <<
"\" not recognized");
731 string prefix =
name.substr(0, 5);
732 QL_REQUIRE(prefix ==
"BOND-",
"A bond index string must start with 'BOND-' but got " << prefix);
739 string nameWoPrefix =
name.substr(5);
740 string bondName = nameWoPrefix;
743 if (nameWoPrefix.size() > 10) {
744 string test = nameWoPrefix.substr(nameWoPrefix.size() - 10);
745 if (boost::regex_match(test, boost::regex(
"\\d{4}-\\d{2}-\\d{2}"))) {
747 bondName = nameWoPrefix.substr(0, nameWoPrefix.size() - test.size() - 1);
752 if (expiry == Date() && nameWoPrefix.size() > 7) {
753 string test = nameWoPrefix.substr(nameWoPrefix.size() - 7);
754 if (boost::regex_match(test, boost::regex(
"\\d{4}-\\d{2}"))) {
756 bondName = nameWoPrefix.substr(0, nameWoPrefix.size() - test.size() - 1);
761 QuantLib::ext::shared_ptr<BondIndex> index;
762 if (expiry != Date()) {
763 index= QuantLib::ext::make_shared<BondFuturesIndex>(expiry, bondName);
765 index= QuantLib::ext::make_shared<BondIndex>(bondName);
767 IndexNameTranslator::instance().add(index->name(),
name);
775 std::vector<string> tokens;
776 split(tokens,
name, boost::is_any_of(
"-"));
777 QL_REQUIRE(tokens.size() >= 3,
"Generic Bond ID with at least two tokens separated by - expected, found " <<
name);
780 std::string prefix = tokens[0];
781 QL_REQUIRE(prefix ==
"CMB",
"A constant maturity bond yield index string must start with 'CMB' but got " << prefix);
783 std::string securityFamily = tokens[1];
784 for (Size i = 2; i < tokens.size() - 1; ++i)
785 securityFamily = securityFamily +
"-" + tokens[i];
786 Period underlyingPeriod =
parsePeriod(tokens.back());
787 QuantLib::ext::shared_ptr<ConstantMaturityBondIndex> i;
789 i = QuantLib::ext::make_shared<ConstantMaturityBondIndex>(prefix +
"-" + securityFamily, underlyingPeriod);
790 }
catch(std::exception& e) {
791 ALOG(
"error creating CMB index: " << e.what());
793 IndexNameTranslator::instance().add(i->name(),
name);
798 const Handle<PriceTermStructure>& ts,
799 const Calendar& cal,
const bool enforceFutureIndex) {
802 string commName =
name;
805 string prefix =
name.substr(0, 5);
806 QL_REQUIRE(prefix ==
"COMM-",
"A commodity index string must start with 'COMM-' but got " << prefix);
807 commName =
name.substr(5);
817 if (commName.size() > 10) {
818 string test = commName.substr(commName.size() - 10);
819 if (boost::regex_match(test, boost::regex(
"\\d{4}-\\d{2}-\\d{2}"))) {
821 commName = commName.substr(0, commName.size() - test.size() - 1);
826 if (expiry == Date() && commName.size() > 7) {
827 string test = commName.substr(commName.size() - 7);
828 if (boost::regex_match(test, boost::regex(
"\\d{4}-\\d{2}"))) {
830 commName = commName.substr(0, commName.size() - test.size() - 1);
836 string indexName = commName;
839 QuantLib::ext::shared_ptr<Conventions> conventions = InstrumentConventions::instance().conventions();
841 QuantLib::ext::shared_ptr<CommodityFutureConvention> convention;
844 convention = QuantLib::ext::dynamic_pointer_cast<CommodityFutureConvention>(p.second);
846 if (!convention->indexName().empty())
847 indexName = convention->indexName();
850 if (convention->offPeakPowerIndexData()) {
852 const auto& oppIdxData = *convention->offPeakPowerIndexData();
854 if (expiry == Date()) {
856 expiry = Settings::instance().evaluationDate();
860 auto offPeakIndex = QuantLib::ext::dynamic_pointer_cast<CommodityFuturesIndex>(
parseCommodityIndex(
861 oppIdxData.offPeakIndex() + suffix,
false));
862 auto peakIndex = QuantLib::ext::dynamic_pointer_cast<CommodityFuturesIndex>(
parseCommodityIndex(
863 oppIdxData.peakIndex() + suffix,
false));
865 auto index = QuantLib::ext::make_shared<OffPeakPowerIndex>(indexName, expiry, offPeakIndex, peakIndex,
866 oppIdxData.offPeakHours(), oppIdxData.peakCalendar(), ts);
867 IndexNameTranslator::instance().add(index->name(), hasPrefix ?
name :
"COMM-" +
name);
868 DLOG(
"parseCommodityIndex(" <<
name <<
") -> " << index->name() <<
" with expiry " << index->expiryDate());
874 QuantLib::ext::shared_ptr<CommodityIndex> index;
875 if (expiry != Date() || (convention && enforceFutureIndex)) {
878 if (expiry == Date()) {
883 bool keepDays = convention && convention->contractFrequency() == Daily;
886 if (convention && cdr == NullCalendar()) {
887 cdr = convention->calendar();
890 auto basisCurve = ts.empty() ? nullptr :
891 QuantLib::ext::dynamic_pointer_cast<CommodityBasisPriceTermStructure>(*ts);
894 index = QuantLib::ext::make_shared<CommodityBasisFutureIndex>(indexName, expiry, cdr, basisCurve);
896 index = QuantLib::ext::make_shared<CommodityFuturesIndex>(indexName, expiry, cdr, keepDays, ts);
902 index = QuantLib::ext::make_shared<CommoditySpotIndex>(commName, cal, ts);
904 IndexNameTranslator::instance().add(index->name(), index->name());
905 DLOG(
"parseCommodityIndex(" <<
name <<
") -> " << index->name() <<
" with expiry " << index->expiryDate());
909QuantLib::ext::shared_ptr<Index>
parseIndex(
const string& s) {
910 QuantLib::ext::shared_ptr<QuantLib::Index> ret_idx;
923 ret_idx =
parseCommodityIndex(s,
true, QuantLib::Handle<QuantExt::PriceTermStructure>(), QuantLib::NullCalendar(),
false);
953 ret_idx =
parseSwapIndex(s, Handle<YieldTermStructure>(), Handle<YieldTermStructure>());
963 QL_REQUIRE(ret_idx,
"parseIndex \"" << s <<
"\" not recognized");
969 QuantLib::ext::shared_ptr<IborIndex> index;
971 auto onIndex = QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(index);
980 QuantLib::ext::shared_ptr<IborIndex> index;
983 return QuantLib::ext::dynamic_pointer_cast<BMAIndexWrapper>(index) !=
nullptr;
991 vector<string> tokens;
992 split(tokens, indexName, boost::is_any_of(
"-"));
993 QL_REQUIRE(tokens.size() == 2 || tokens.size() == 3,
994 "Two or three tokens required in " << indexName <<
": CCY-INDEX or CCY-INDEX-TERM");
997 static map<string, string> m = {{
"DKK-TNR",
"DKK-DKKOIS"}, {
"EUR-EURIB",
"EUR-EURIBOR"}, {
"CAD-BA",
"CAD-CDOR"},
998 {
"EUR-ESTR",
"EUR-ESTER"}, {
"EUR-STR",
"EUR-ESTER"}, {
"JPY-TONA",
"JPY-TONAR"},
999 {
"JPY-TORF",
"JPY-TONAR"}};
1002 string tmpName = tokens[0] +
"-" + tokens[1];
1003 if (m.count(tmpName) == 1) {
1004 tmpName = m.at(tmpName);
1008 if (tokens.size() == 2) {
1020 if (tmpName ==
"USD-SIFMA" && (tokens[2] ==
"1W" || tokens[2] ==
"7D")) {
1024 return tmpName +
"-" + tokens[2];
1028 std::vector<string> tokens;
1029 split(tokens, indexName, boost::is_any_of(
"-"));
1030 return tokens.size() == 4 && tokens[0] ==
"FX";
1034 std::vector<string> tokens;
1035 split(tokens, indexName, boost::is_any_of(
"-"));
1036 QL_REQUIRE(tokens.size() == 4 && tokens[0] ==
"FX",
"no fx index given (" << indexName <<
")");
1037 return "FX-" + tokens[1] +
"-" + tokens[3] +
"-" + tokens[2];
Abstract base class for convention objects.
Perform date calculations for future contracts based on conventions.
QuantLib::Date nextExpiry(bool includeExpiry=true, const QuantLib::Date &referenceDate=QuantLib::Date(), QuantLib::Natural offset=0, bool forOption=false) override
Currency and instrument specific conventions/defaults.
Base class for classes that perform date calculations for future contracts.
QuantLib::ext::shared_ptr< ZeroInflationIndex > parseZeroInflationIndex(const string &s, const Handle< ZeroInflationTermStructure > &h)
Convert std::string to QuantLib::ZeroInflationIndex.
Calendar parseCalendar(const string &s)
Convert text to QuantLib::Calendar.
QuantLib::ext::shared_ptr< SwapIndex > parseSwapIndex(const string &s, const Handle< YieldTermStructure > &f, const Handle< YieldTermStructure > &d)
Convert std::string to QuantLib::SwapIndex.
bool isEquityIndex(const string &indexName)
Return true if the indexName is that of an EquityIndex, otherwise false.
QuantLib::ext::shared_ptr< IborIndex > parseIborIndex(const string &s, const Handle< YieldTermStructure > &h)
Convert std::string to QuantLib::IborIndex.
bool isOvernightIndex(const string &indexName)
Return true if the indexName is that of an overnight index, otherwise false.
bool isBmaIndex(const string &indexName)
Return true if the indexName is that of an bma/sifma index, otherwise false.
QuantLib::ext::shared_ptr< QuantExt::EquityIndex2 > parseEquityIndex(const string &s)
Convert std::string (e.g SP5) to QuantExt::EquityIndex.
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.
pair< bool, QuantLib::ext::shared_ptr< ZeroInflationIndex > > isInflationIndex(const string &indexName)
bool isCommodityIndex(const string &indexName)
Return true if the indexName is that of an CommodityIndex, otherwise false.
bool tryParseIborIndex(const string &s, QuantLib::ext::shared_ptr< IborIndex > &index)
Try to convert std::string to QuantLib::IborIndex.
Date parseDate(const string &s)
Convert std::string to QuantLib::Date.
string internalIndexName(const string &indexName)
bool isGenericIndex(const string &indexName)
Currency parseCurrency(const string &s)
Convert text to QuantLib::Currency.
QuantLib::ext::shared_ptr< BondIndex > parseBondIndex(const string &name)
Convert std::string to QuantExt::BondIndex.
BusinessDayConvention parseBusinessDayConvention(const string &s)
Convert text to QuantLib::BusinessDayConvention.
bool isGenericIborIndex(const string &indexName)
Return true if the indexName is that of a generic ibor index, otherwise false.
Period parsePeriod(const string &s)
Convert text to QuantLib::Period.
QuantLib::ext::shared_ptr< Index > parseIndex(const string &s)
Convert std::string to QuantLib::Index.
QuantLib::ext::shared_ptr< QuantLib::Index > parseGenericIndex(const string &s)
Convert std::string (GENERIC-...) to QuantExt::Index.
QuantLib::ext::shared_ptr< ConstantMaturityBondIndex > parseConstantMaturityBondIndex(const string &name)
Convert std::string to QuantExt::ConstantMaturityBondIndex.
DayCounter parseDayCounter(const string &s)
Convert text to QuantLib::DayCounter.
translates between QuantLib::Index::name() and ORE names
Map text representations to QuantLib/QuantExt types.
Classes and functions for log message handling.
#define DLOG(text)
Logging Macro (Level = Debug)
#define ALOG(text)
Logging Macro (Level = Alert)
market data related utilties
bool isFxIndex(const std::string &indexName)
Size size(const ValueType &v)
std::string to_string(const LocationInfo &l)
void checkOneToOne(const map< string, QuantLib::ext::shared_ptr< OvernightIndex > > &onIndices, const map< string, QuantLib::ext::shared_ptr< IborIndexParser > > &iborIndices)
std::tuple< Natural, Calendar, BusinessDayConvention > getFxIndexConventions(const string &index)
QuantLib::ext::shared_ptr< QuantExt::CommodityIndex > parseCommodityIndex(const string &name, bool hasPrefix, const Handle< PriceTermStructure > &ts, const Calendar &cal, const bool enforceFutureIndex)
std::string inverseFxIndex(const std::string &indexName)
Serializable Credit Default Swap.
Map text representations to QuantLib/QuantExt types.
string conversion utilities