Function to parse a market datum.
221 {
222
223 vector<string> tokens;
224 boost::split(tokens, datumName, boost::is_any_of("/"));
225 QL_REQUIRE(tokens.size() > 2, "more than 2 tokens expected in " << datumName);
226
227 MarketDatum::InstrumentType instrumentType = parseInstrumentType(tokens[0]);
228 MarketDatum::QuoteType quoteType = parseQuoteType(tokens[1]);
229
230 switch (instrumentType) {
231
232 case MarketDatum::InstrumentType::ZERO: {
233
234 QL_REQUIRE(quoteType == MarketDatum::QuoteType::RATE || quoteType == MarketDatum::QuoteType::YIELD_SPREAD,
235 "Invalid quote type for " << datumName);
236 QL_REQUIRE(tokens.size() == 6, "6 tokens expected in " << datumName);
237 const string& ccy = tokens[2];
239
240 Date date = Date();
241 Period tenor = Period();
242 bool isDate;
244 return QuantLib::ext::make_shared<ZeroQuote>(
value, asof, datumName, quoteType, ccy, date, dc, tenor);
245 }
246
247 case MarketDatum::InstrumentType::DISCOUNT: {
248
249
250 QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName);
251 const string& ccy = tokens[2];
252
253 Date date = Date();
254 Period tenor = Period();
255 bool isDate;
257 return QuantLib::ext::make_shared<DiscountQuote>(
value, asof, datumName, quoteType, ccy, date, tenor);
258 }
259
260 case MarketDatum::InstrumentType::MM: {
261 QL_REQUIRE(tokens.size() == 5 || tokens.size() == 6, "5 or 6 tokens expected in " << datumName);
262 const string& ccy = tokens[2];
263 Size offset = 0;
264 string indexName;
265 if (tokens.size() == 6) {
266 indexName = tokens[3];
267 offset = 1;
268 }
271 return QuantLib::ext::make_shared<MoneyMarketQuote>(
value, asof, datumName, quoteType, ccy, fwdStart, term, indexName);
272 }
273
274 case MarketDatum::InstrumentType::MM_FUTURE: {
275 QL_REQUIRE(tokens.size() == 6, "6 tokens expected in " << datumName);
276 const string& ccy = tokens[2];
277 const string& expiry = tokens[3];
278 const string& contract = tokens[4];
280 return QuantLib::ext::make_shared<MMFutureQuote>(
value, asof, datumName, quoteType, ccy, expiry, contract, term);
281 }
282
283 case MarketDatum::InstrumentType::OI_FUTURE: {
284 QL_REQUIRE(tokens.size() == 6, "6 tokens expected in " << datumName);
285 const string& ccy = tokens[2];
286 const string& expiry = tokens[3];
287 const string& contract = tokens[4];
289 return QuantLib::ext::make_shared<OIFutureQuote>(
value, asof, datumName, quoteType, ccy, expiry, contract, term);
290 }
291
292 case MarketDatum::InstrumentType::FRA: {
293 QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName);
294 const string& ccy = tokens[2];
297 return QuantLib::ext::make_shared<FRAQuote>(
value, asof, datumName, quoteType, ccy, fwdStart, term);
298 }
299
300 case MarketDatum::InstrumentType::IMM_FRA: {
301 QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName);
302 const string& ccy = tokens[2];
303 string imm1 = tokens[3];
304 string imm2 = tokens[4];
307 QL_REQUIRE(m2 > m1, "Second IMM date must be after the first in " << datumName);
308 return QuantLib::ext::make_shared<ImmFraQuote>(
value, asof, datumName, quoteType, ccy, m1, m2);
309 }
310
311 case MarketDatum::InstrumentType::IR_SWAP: {
312 QL_REQUIRE(tokens.size() == 6 || tokens.size() == 7, "6 or 7 tokens expected in " << datumName);
313 const string& ccy = tokens[2];
314 Size offset = 0;
315 string indexName;
316 if (tokens.size() == 7) {
317 indexName = tokens[3];
318 offset = 1;
319 }
321 boost::variant<QuantLib::Date, QuantLib::Period> start =
parseDateOrPeriod(tokens[3 + offset]);
322 boost::variant<QuantLib::Date, QuantLib::Period> end =
parseDateOrPeriod(tokens[5 + offset]);
323
324 if (start.type() == typeid(QuantLib::Period) && end.type() == typeid(QuantLib::Period)) {
325 Period fwdStart = QuantLib::ext::get<QuantLib::Period>(start);
326 Period term = QuantLib::ext::get<QuantLib::Period>(end);
327 return QuantLib::ext::make_shared<SwapQuote>(
value, asof, datumName, quoteType, ccy, fwdStart, term, tenor,
328 indexName);
329 } else if (start.type() == typeid(QuantLib::Date) && end.type() == typeid(QuantLib::Date)) {
330 Date startDate = QuantLib::ext::get<QuantLib::Date>(start);
331 Date maturityDate = QuantLib::ext::get<QuantLib::Date>(end);
332 return QuantLib::ext::make_shared<SwapQuote>(
value, asof, datumName, quoteType, ccy, startDate, maturityDate, tenor,
333 indexName);
334 } else {
335 QL_FAIL("Expect swap quote with start/end as either periods or dates");
336 }
337 }
338
339 case MarketDatum::InstrumentType::BASIS_SWAP: {
340
341
342
343 QL_REQUIRE(tokens.size() == 6 || tokens.size() == 7, "Either 6 or 7 tokens expected in " << datumName);
346 const string& ccy = tokens[4];
348 if (tokens.size() == 7) {
350 } else {
352 }
353 return QuantLib::ext::make_shared<BasisSwapQuote>(
value, asof, datumName, quoteType, flatTerm, term, ccy,
maturity);
354 }
355
356 case MarketDatum::InstrumentType::BMA_SWAP: {
357 QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName);
358 const string& ccy = tokens[2];
361 return QuantLib::ext::make_shared<BMASwapQuote>(
value, asof, datumName, quoteType, term, ccy,
maturity);
362 }
363
364 case MarketDatum::InstrumentType::CC_BASIS_SWAP: {
365 QL_REQUIRE(tokens.size() == 7, "7 tokens expected in " << datumName);
366 const string& flatCcy = tokens[2];
368 const string& ccy = tokens[4];
371 return QuantLib::ext::make_shared<CrossCcyBasisSwapQuote>(
value, asof, datumName, quoteType, flatCcy, flatTerm, ccy,
373 }
374
375 case MarketDatum::InstrumentType::CC_FIX_FLOAT_SWAP: {
376
377 QL_REQUIRE(tokens.size() == 7, "7 tokens expected in " << datumName);
381 return QuantLib::ext::make_shared<CrossCcyFixFloatSwapQuote>(
value, asof, datumName, quoteType, tokens[2], floatTenor,
383 }
384
385 case MarketDatum::InstrumentType::CDS: {
386
387
388
389
390
391
392
393
394 QL_REQUIRE(tokens.size() == 6 || tokens.size() == 7 || tokens.size() == 8,
395 "6, 7 or 8 tokens expected in " << datumName);
396 const string& underlyingName = tokens[2];
397 const string& seniority = tokens[3];
398 const string& ccy = tokens[4];
399
400 string docClause;
401 Period term;
402 Real runningSpread = Null<Real>();
403 if (tokens.size() == 6) {
405 } else if (tokens.size() == 8) {
406 docClause = tokens[5];
408 runningSpread =
parseReal(tokens[7]) / 10000;
409 } else {
410
412 if (tryParse<CdsDocClause>(tokens[5], cdsDocClause, &parseCdsDocClause)) {
413 docClause = tokens[5];
415 } else {
417 runningSpread =
parseReal(tokens[6]) / 10000;
418 }
419 }
420
421 return QuantLib::ext::make_shared<CdsQuote>(
value, asof, datumName, quoteType, underlyingName,
422 seniority, ccy, term, docClause, runningSpread);
423 }
424
425 case MarketDatum::InstrumentType::HAZARD_RATE: {
426 QL_REQUIRE(tokens.size() == 6 || tokens.size() == 7, "6 or 7 tokens expected in " << datumName);
427 const string& underlyingName = tokens[2];
428 const string& seniority = tokens[3];
429 const string& ccy = tokens[4];
430 string docClause = tokens.size() == 7 ? tokens[5] : "";
432 return QuantLib::ext::make_shared<HazardRateQuote>(
value, asof, datumName, underlyingName, seniority, ccy, term,
433 docClause);
434 }
435
436 case MarketDatum::InstrumentType::RECOVERY_RATE: {
437 QL_REQUIRE(tokens.size() == 3 || tokens.size() == 5 || tokens.size() == 6,
438 "3, 5 or 6 tokens expected in " << datumName);
439 const string& underlyingName = tokens[2];
440 string seniority = "";
441 string ccy = "";
442 string docClause = "";
443 if (tokens.size() >= 5) {
444
445 seniority = tokens[3];
446 ccy = tokens[4];
447 if (tokens.size() == 6)
448 docClause = tokens[5];
449 }
450 return QuantLib::ext::make_shared<RecoveryRateQuote>(
value, asof, datumName, underlyingName, seniority, ccy, docClause);
451 }
452
453 case MarketDatum::InstrumentType::CAPFLOOR: {
454 QL_REQUIRE((tokens.size() >= 8 && tokens.size() <= 10) || tokens.size() == 4 || tokens.size() == 5,
455 "Either 4, 5 or 8, 9, 10 tokens expected in " << datumName);
456 const string& ccy = tokens[2];
457 Size offset = 0;
458 std::string indexName;
459 Size hasCapFloorToken = (tokens.back() == "C" || tokens.back() == "F") ? 1 : 0;
460 QL_REQUIRE(quoteType != MarketDatum::QuoteType::PRICE || hasCapFloorToken == 1,
461 "CAPFLOOR PRICE quotes must specify whether the datum represents a cap or a floor with a \"C\" or"
462 " \"F\" as the final token.");
463
464 if (tokens.size() == 9 + hasCapFloorToken || tokens.size() == 5 + hasCapFloorToken) {
465
466 offset = 1;
467 indexName = tokens[3];
468 }
469 if (tokens.size() == 8 + hasCapFloorToken || tokens.size() == 9 + hasCapFloorToken) {
472 bool atm =
parseBool(tokens[5 + offset].c_str());
473 bool relative =
parseBool(tokens[6 + offset].c_str());
474 Real strike =
parseReal(tokens[7 + offset]);
475 bool isCap = !(hasCapFloorToken==1 && tokens.back() == "F");
476 return QuantLib::ext::make_shared<CapFloorQuote>(
value, asof, datumName, quoteType, ccy, term, tenor, atm, relative,
477 strike, indexName, isCap);
478 } else {
479
480 Period indexTenor =
parsePeriod(tokens[3 + offset]);
481 return QuantLib::ext::make_shared<CapFloorShiftQuote>(
value, asof, datumName, quoteType, ccy, indexTenor,
482 indexName);
483 }
484 }
485
486 case MarketDatum::InstrumentType::SWAPTION: {
487 QL_REQUIRE(tokens.size() >= 4 && tokens.size() <= 9, "4...9 tokens expected in " << datumName);
488 const string& ccy = tokens[2];
490 std::string quoteTag;
491 Size hasPayReceiveToken = (tokens.back() == "P" || tokens.back() == "R") ? 1 : 0;
492 QL_REQUIRE(quoteType != MarketDatum::QuoteType::PRICE || hasPayReceiveToken == 1,
493 "SWAPTION PRICE quotes must specify whether the datum represents a payer or a receiver"
494 " swaption with a \"P\" or \"R\" as the final token.");
495
496 if (offset == 1)
497 quoteTag = tokens[3];
498 if (tokens.size() >= 6 + offset + hasPayReceiveToken) {
501 const string& dimension = tokens[5 + offset];
502 Real strike = 0.0;
503 if (dimension == "ATM")
504 QL_REQUIRE(tokens.size() == 6 + offset + hasPayReceiveToken, 6 + offset + hasPayReceiveToken
505 << " tokens expected in ATM quote " << datumName);
506 else if (dimension == "Smile") {
507 QL_REQUIRE(tokens.size() == 7 + offset + hasPayReceiveToken, 7 + offset + hasPayReceiveToken
508 << " tokens expected in Smile quote " << datumName);
510 } else
511 QL_FAIL("Swaption vol quote dimension " << dimension << " not recognised");
512 bool isPayer = !(hasPayReceiveToken == 1 && tokens.back() == "R");
513 return QuantLib::ext::make_shared<SwaptionQuote>(
value, asof, datumName, quoteType, ccy, expiry, term, dimension,
514 strike, quoteTag, isPayer);
515 } else {
516 return QuantLib::ext::make_shared<SwaptionShiftQuote>(
value, asof, datumName, quoteType, ccy,
518 }
519 }
520
521 case MarketDatum::InstrumentType::BOND_OPTION: {
522 QL_REQUIRE(tokens.size() == 4 || tokens.size() == 6, "4 or 6 tokens expected in " << datumName);
523 const string& qualifier = tokens[2];
526 if (tokens.size() == 6) {
527 QL_REQUIRE(tokens[5] == "ATM", "only ATM allowed for bond option quotes");
528 return QuantLib::ext::make_shared<BondOptionQuote>(
value, asof, datumName, quoteType, qualifier, expiry, term);
529 } else {
530 return QuantLib::ext::make_shared<BondOptionShiftQuote>(
value, asof, datumName, quoteType, qualifier, term);
531 }
532 }
533
534 case MarketDatum::InstrumentType::FX_SPOT: {
535 QL_REQUIRE(tokens.size() == 4, "4 tokens expected in " << datumName);
536 const string& unitCcy = tokens[2];
537 const string& ccy = tokens[3];
538 return QuantLib::ext::make_shared<FXSpotQuote>(
value, asof, datumName, quoteType, unitCcy, ccy);
539 }
540
541 case MarketDatum::InstrumentType::FX_FWD: {
542 QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName);
543 const string& unitCcy = tokens[2];
544 const string& ccy = tokens[3];
545 boost::variant<QuantLib::Period, FXForwardQuote::FxFwdString> term =
parseFxPeriod(tokens[4]);
546 return QuantLib::ext::make_shared<FXForwardQuote>(
value, asof, datumName, quoteType, unitCcy, ccy, term);
547 }
548
549 case MarketDatum::InstrumentType::FX_OPTION: {
550 QL_REQUIRE(tokens.size() == 6, "6 tokens expected in " << datumName);
551 const string& unitCcy = tokens[2];
552 const string& ccy = tokens[3];
554 const string& strike = tokens[5];
555 return QuantLib::ext::make_shared<FXOptionQuote>(
value, asof, datumName, quoteType, unitCcy, ccy, expiry, strike);
556 }
557
558 case MarketDatum::InstrumentType::ZC_INFLATIONSWAP: {
559 QL_REQUIRE(tokens.size() == 4, "4 tokens expected in " << datumName);
560 const string& index = tokens[2];
562 return QuantLib::ext::make_shared<ZcInflationSwapQuote>(
value, asof, datumName, index, term);
563 }
564
565 case MarketDatum::InstrumentType::YY_INFLATIONSWAP: {
566 QL_REQUIRE(tokens.size() == 4, "4 tokens expected in " << datumName);
567 const string& index = tokens[2];
569 return QuantLib::ext::make_shared<YoYInflationSwapQuote>(
value, asof, datumName, index, term);
570 }
571
572 case MarketDatum::InstrumentType::ZC_INFLATIONCAPFLOOR: {
573 QL_REQUIRE(tokens.size() == 6, "6 tokens expected in " << datumName);
574 const string& index = tokens[2];
576 QL_REQUIRE(tokens[4] == "C" || tokens[4] == "F",
577 "expected C or F for Cap or Floor at position 5 in " << datumName);
578 bool isCap = tokens[4] == "C";
579 string strike = tokens[5];
580 return QuantLib::ext::make_shared<ZcInflationCapFloorQuote>(
value, asof, datumName, quoteType, index, term, isCap,
581 strike);
582 }
583
584 case MarketDatum::InstrumentType::YY_INFLATIONCAPFLOOR: {
585 QL_REQUIRE(tokens.size() == 6, "6 tokens expected in " << datumName);
586 const string& index = tokens[2];
588 QL_REQUIRE(tokens[4] == "C" || tokens[4] == "F",
589 "expected C or F for Cap or Floor at position 5 in " << datumName);
590 bool isCap = tokens[4] == "C";
591 string strike = tokens[5];
592 return QuantLib::ext::make_shared<YyInflationCapFloorQuote>(
value, asof, datumName, quoteType, index, term, isCap,
593 strike);
594 }
595
596 case MarketDatum::InstrumentType::SEASONALITY: {
597 QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName);
598 const string& index = tokens[3];
599 const string& type = tokens[2];
600 const string& month = tokens[4];
601 return QuantLib::ext::make_shared<SeasonalityQuote>(
value, asof, datumName, index, type, month);
602 }
603 case MarketDatum::InstrumentType::EQUITY_SPOT: {
604 QL_REQUIRE(tokens.size() == 4, "4 tokens expected in " << datumName);
605 QL_REQUIRE(quoteType == MarketDatum::QuoteType::PRICE, "Invalid quote type for " << datumName);
606 const string& equityName = tokens[2];
607 const string& ccy = tokens[3];
608 return QuantLib::ext::make_shared<EquitySpotQuote>(
value, asof, datumName, quoteType, equityName, ccy);
609 }
610
611 case MarketDatum::InstrumentType::EQUITY_FWD: {
612 QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName);
613 QL_REQUIRE(quoteType == MarketDatum::QuoteType::PRICE, "Invalid quote type for " << datumName);
614 const string& equityName = tokens[2];
615 const string& ccy = tokens[3];
617 return QuantLib::ext::make_shared<EquityForwardQuote>(
value, asof, datumName, quoteType, equityName, ccy, expiryDate);
618 }
619
620 case MarketDatum::InstrumentType::EQUITY_DIVIDEND: {
621 QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName);
622 QL_REQUIRE(quoteType == MarketDatum::QuoteType::RATE, "Invalid quote type for " << datumName);
623 const string& equityName = tokens[2];
624 const string& ccy = tokens[3];
626 return QuantLib::ext::make_shared<EquityDividendYieldQuote>(
value, asof, datumName, quoteType, equityName, ccy,
627 tenorDate);
628 }
629
630 case MarketDatum::InstrumentType::EQUITY_OPTION: {
631 QL_REQUIRE(tokens.size() >= 6 || tokens.size() <= 9, "6 - 9 tokens expected in " << datumName);
632 QL_REQUIRE(quoteType == MarketDatum::QuoteType::RATE_LNVOL || quoteType == MarketDatum::QuoteType::PRICE,
633 "Invalid quote type for " << datumName);
634 const string& equityName = tokens[2];
635 const string& ccy = tokens[3];
636 string expiryString = tokens[4];
637
638 bool hasCallPutToken = tokens.back() == "C" || tokens.back() == "P";
639
640 string strikeStr;
641 for(Size i=5; i < tokens.size() - (hasCallPutToken ? 1 : 0); ++i) {
642 strikeStr += (i > 5 ? "/" : "") + tokens[i];
643 }
644 QuantLib::ext::shared_ptr<BaseStrike> strike;
645
646 if(strikeStr == "ATM")
647 strike = QuantLib::ext::make_shared<AtmStrike>(QuantLib::DeltaVolQuote::AtmType::AtmSpot);
648 else if(strikeStr == "ATMF")
649 strike = QuantLib::ext::make_shared<AtmStrike>(QuantLib::DeltaVolQuote::AtmType::AtmFwd);
650 else
652 bool isCall = true;
653 if (hasCallPutToken) {
654 QL_REQUIRE(tokens.back() == "C" || tokens.back() == "P",
655 "expected C or P for Call or Put at position " << tokens.size() << " in " << datumName);
656 isCall = tokens.back() == "C";
657 }
658
659
660
661 return QuantLib::ext::make_shared<EquityOptionQuote>(
value, asof, datumName, quoteType, equityName, ccy, expiryString,
662 strike, isCall);
663 }
664
665 case MarketDatum::InstrumentType::BOND: {
666 QL_REQUIRE(tokens.size() == 3, "3 tokens expected in " << datumName);
667 const string& securityID = tokens[2];
668 if (quoteType == MarketDatum::QuoteType::YIELD_SPREAD)
669 return QuantLib::ext::make_shared<SecuritySpreadQuote>(
value, asof, datumName, securityID);
670 else if (quoteType == MarketDatum::QuoteType::PRICE)
671 return QuantLib::ext::make_shared<BondPriceQuote>(
value, asof, datumName, securityID);
672 }
673
674 case MarketDatum::InstrumentType::CDS_INDEX: {
675 QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName);
676 QL_REQUIRE(quoteType == MarketDatum::QuoteType::BASE_CORRELATION, "Invalid quote type for " << datumName);
677 const string& cdsIndexName = tokens[2];
679 Real detachmentPoint =
parseReal(tokens[4]);
680 return QuantLib::ext::make_shared<BaseCorrelationQuote>(
value, asof, datumName, quoteType, cdsIndexName, term,
681 detachmentPoint);
682 }
683
684 case MarketDatum::InstrumentType::INDEX_CDS_OPTION: {
685
686
687
688 QL_REQUIRE(tokens.size() >= 4 || tokens.size() <= 6, "4, 5 or 6 tokens expected in " << datumName);
689 QL_REQUIRE(quoteType == MarketDatum::QuoteType::RATE_LNVOL, "Invalid quote type for " << datumName);
690
691 QuantLib::ext::shared_ptr<Expiry> expiry;
692 QuantLib::ext::shared_ptr<BaseStrike> strike;
693 string indexTerm;
694 if (tokens.size() == 6) {
695
696 indexTerm = tokens[3];
699 } else if (tokens.size() == 5) {
700
701
702 Real tmp;
706 } else {
707 indexTerm = tokens[3];
709 }
710 } else {
711
713 }
714
715 return QuantLib::ext::make_shared<IndexCDSOptionQuote>(
value, asof, datumName, tokens[2], expiry, indexTerm, strike);
716 }
717
718 case MarketDatum::InstrumentType::COMMODITY_SPOT: {
719 QL_REQUIRE(tokens.size() == 4, "4 tokens expected in " << datumName);
720 QL_REQUIRE(quoteType == MarketDatum::QuoteType::PRICE, "Invalid quote type for " << datumName);
721
722 return QuantLib::ext::make_shared<CommoditySpotQuote>(
value, asof, datumName, quoteType, tokens[2], tokens[3]);
723 }
724
725 case MarketDatum::InstrumentType::COMMODITY_FWD: {
726
727
728 QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName);
729 QL_REQUIRE(quoteType == MarketDatum::QuoteType::PRICE, "Invalid quote type for " << datumName);
730
731
732 if (tokens[4] == "ON") {
733 return QuantLib::ext::make_shared<CommodityForwardQuote>(
value, asof, datumName, quoteType, tokens[2], tokens[3],
734 1 * Days, 0 * Days);
735 } else if (tokens[4] == "TN") {
736 return QuantLib::ext::make_shared<CommodityForwardQuote>(
value, asof, datumName, quoteType, tokens[2], tokens[3],
737 1 * Days, 1 * Days);
738 } else if (tokens[4] == "SN") {
739 return QuantLib::ext::make_shared<CommodityForwardQuote>(
value, asof, datumName, quoteType, tokens[2], tokens[3],
740 1 * Days);
741 }
742
743
744 Date date;
745 Period tenor;
746 bool isDate;
748
749 if (isDate) {
750 return QuantLib::ext::make_shared<CommodityForwardQuote>(
value, asof, datumName, quoteType, tokens[2], tokens[3],
751 date);
752 } else {
753 return QuantLib::ext::make_shared<CommodityForwardQuote>(
value, asof, datumName, quoteType, tokens[2], tokens[3],
754 tenor);
755 }
756 }
757
758 case MarketDatum::InstrumentType::COMMODITY_OPTION: {
759
760
761
762
763 using QT = MarketDatum::QuoteType;
764 QL_REQUIRE(tokens.size() >= 6, "At least 6 tokens expected in " << datumName);
765 QL_REQUIRE(quoteType == QT::RATE_LNVOL || quoteType == QT::PRICE,
766 "Quote type for " << datumName << " should be 'RATE_LNVOL' or 'PRICE'");
767
768 QuantLib::ext::shared_ptr<Expiry> expiry =
parseExpiry(tokens[4]);
769
770
771 auto itStkBeg = tokens.begin() + 5;
772 auto itStkEnd = tokens.end();
773 Option::Type optionType = Option::Call;
774 if (tokens.back() == "C" || tokens.back() == "P") {
775 if (tokens.back() == "P")
776 optionType = Option::Put;
777 itStkEnd = prev(itStkEnd);
778 }
779
780
781 QL_REQUIRE(itStkBeg != itStkEnd, "");
782 string strStrike = boost::algorithm::join(boost::make_iterator_range(itStkBeg, itStkEnd), "/");
783 QuantLib::ext::shared_ptr<BaseStrike> strike =
parseBaseStrike(strStrike);
784
785 return QuantLib::ext::make_shared<CommodityOptionQuote>(
value, asof, datumName, quoteType, tokens[2],
786 tokens[3], expiry, strike, optionType);
787 }
788
789 case MarketDatum::InstrumentType::CORRELATION: {
790
791
792 QL_REQUIRE(tokens.size() == 6, "6 tokens expected in " << datumName);
793 QL_REQUIRE(quoteType == MarketDatum::QuoteType::RATE || quoteType == MarketDatum::QuoteType::PRICE,
794 "Quote type for " << datumName << " should be 'CORRELATION' or 'PRICE'");
795
796 return QuantLib::ext::make_shared<CorrelationQuote>(
value, asof, datumName, quoteType, tokens[2], tokens[3], tokens[4],
797 tokens[5]);
798 }
799
800 case MarketDatum::InstrumentType::CPR: {
801 QL_REQUIRE(tokens.size() == 3, "3 tokens expected in " << datumName);
802 const string& securityID = tokens[2];
803 QL_REQUIRE(quoteType == MarketDatum::QuoteType::RATE, "Invalid quote type for " << datumName);
804 return QuantLib::ext::make_shared<CPRQuote>(
value, asof, datumName, securityID);
805 }
806
807 case MarketDatum::InstrumentType::RATING: {
808 QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName);
809 const string&
name = tokens[2];
810 const string& fromRating = tokens[3];
811 const string& toRating = tokens[4];
812 QL_REQUIRE(quoteType == MarketDatum::QuoteType::TRANSITION_PROBABILITY, "Invalid quote type for " << datumName);
813 return QuantLib::ext::make_shared<TransitionProbabilityQuote>(
value, asof, datumName,
name, fromRating, toRating);
814 }
815
816 default:
817 QL_FAIL("Cannot convert \"" << datumName << "\" to MarketDatum");
818 }
819}
SafeStack< ValueType > value
Date getDateFromDateOrPeriod(const string &token, Date asof, QuantLib::Calendar cal, QuantLib::BusinessDayConvention bdc)
Get a date from a date string or period.
boost::variant< QuantLib::Period, FXForwardQuote::FxFwdString > parseFxPeriod(const string &s)
Convert text to QuantLib::Period of Fx forward string.
bool tryParseReal(const string &s, QuantLib::Real &result)
Attempt to convert text to Real.
boost::variant< QuantLib::Date, QuantLib::Period > parseDateOrPeriod(const string &s)
Convert text to QuantLib::Period or QuantLib::Date.
Period parsePeriod(const string &s)
Convert text to QuantLib::Period.
bool parseBool(const string &s)
Convert text to bool.
Real parseReal(const string &s)
Convert text to Real.
Integer parseInteger(const string &s)
Convert text to QuantLib::Integer.
DayCounter parseDayCounter(const string &s)
Convert text to QuantLib::DayCounter.
CdsDocClause
CDS documentation clause enumeration.
bool isOnePeriod(const string &s)
return true if s represents a period of the form [0-9][D|W|M|Y] (i.e. 1Y6M would return false)
QuantLib::ext::shared_ptr< Expiry > parseExpiry(const string &strExpiry)
Parse an Expiry from its string representation, strExpiry.
QuantLib::ext::shared_ptr< BaseStrike > parseBaseStrike(const string &strStrike)
Parse a Strike from its string representation, strStrike.