예제 #1
0
파일: MakeCDS.cs 프로젝트: igitur/qlnet
        public CreditDefaultSwap value()
        {
            Date evaluation  = Settings.evaluationDate();
            Date start       = evaluation + 1;
            Date upfrontDate = new WeekendsOnly().advance(evaluation, new Period(3, TimeUnit.Days));
            Date end;

            if (tenor_ != null)
            {
                end = start + tenor_;
            }
            else
            {
                end = termDate_;
            }

            Schedule schedule = new Schedule(start, end, couponTenor_, new WeekendsOnly(),
                                             BusinessDayConvention.Following, BusinessDayConvention.Unadjusted, DateGeneration.Rule.CDS,
                                             false, null, null);

            CreditDefaultSwap cds = new CreditDefaultSwap(side_, nominal_, upfrontRate_, couponRate_, schedule,
                                                          BusinessDayConvention.Following, dayCounter_, true, true, start, upfrontDate, null, lastPeriodDayCounter_);

            cds.setPricingEngine(engine_);
            return(cds);
        }
예제 #2
0
        // calls parseDateOrPeriod and returns a Date (either the supplied date or asof+period)
        public static Date GetDateFromDateOrPeriod(string token, Date asof)
        {
            Period term       = new Period();                                  // gets populated by parseDateOrPeriod
            Date   expiryDate = new Date();                                    // gets populated by parseDateOrPeriod
            bool   tmpIsDate  = false;                                         // gets populated by parseDateOrPeriod

            Parsers.ParseDateOrPeriod(token, expiryDate, term, out tmpIsDate); // checks if the market string contains a date or a period
            if (!tmpIsDate)
            {
                expiryDate = new WeekendsOnly().adjust(asof + term);       // we have no calendar information here, so we use a generic calendar
            }

            return(expiryDate);
        }
예제 #3
0
        /* This test attempts to build a default curve from CDS spreads as of 1 Apr 2020. The spreads are real and from a
         * distressed reference entity with an inverted CDS spread curve. Using the default IterativeBootstrap with no
         * retries, the default curve building fails. Allowing retries, it expands the min survival probability bounds but
         * still fails. We set dontThrow to true in IterativeBootstrap to use a fall back curve.
         */
        public void testIterativeBootstrapRetries()
        {
            //Testing iterative bootstrap with retries...

            SavedSettings backup = new SavedSettings();

            Date asof = new Date(1, Month.Apr, 2020);

            Settings.Instance.setEvaluationDate(asof);
            Actual365Fixed tsDayCounter = new Actual365Fixed();

            // USD discount curve built out of FedFunds OIS swaps.
            List <Date> usdCurveDates = new List <Date>()
            {
                new Date(1, Month.Apr, 2020),
                new Date(2, Month.Apr, 2020),
                new Date(14, Month.Apr, 2020),
                new Date(21, Month.Apr, 2020),
                new Date(28, Month.Apr, 2020),
                new Date(6, Month.May, 2020),
                new Date(5, Month.Jun, 2020),
                new Date(7, Month.Jul, 2020),
                new Date(5, Month.Aug, 2020),
                new Date(8, Month.Sep, 2020),
                new Date(7, Month.Oct, 2020),
                new Date(5, Month.Nov, 2020),
                new Date(7, Month.Dec, 2020),
                new Date(6, Month.Jan, 2021),
                new Date(5, Month.Feb, 2021),
                new Date(5, Month.Mar, 2021),
                new Date(7, Month.Apr, 2021),
                new Date(4, Month.Apr, 2022),
                new Date(3, Month.Apr, 2023),
                new Date(3, Month.Apr, 2024),
                new Date(3, Month.Apr, 2025),
                new Date(5, Month.Apr, 2027),
                new Date(3, Month.Apr, 2030),
                new Date(3, Month.Apr, 2035),
                new Date(3, Month.Apr, 2040),
                new Date(4, Month.Apr, 2050)
            };

            List <double> usdCurveDfs = new List <double>()
            {
                1.000000000,
                0.999955835,
                0.999931070,
                0.999914629,
                0.999902799,
                0.999887990,
                0.999825782,
                0.999764392,
                0.999709076,
                0.999647785,
                0.999594638,
                0.999536198,
                0.999483093,
                0.999419291,
                0.999379417,
                0.999324981,
                0.999262356,
                0.999575101,
                0.996135441,
                0.995228348,
                0.989366687,
                0.979271200,
                0.961150726,
                0.926265361,
                0.891640651,
                0.839314063
            };

            Handle <YieldTermStructure> usdYts = new Handle <YieldTermStructure>(
                new InterpolatedDiscountCurve <LogLinear>(
                    usdCurveDates, usdCurveDfs, tsDayCounter));

            // CDS spreads
            Dictionary <Period, double> cdsSpreads = new Dictionary <Period, double>();

            cdsSpreads.Add(new Period(6, TimeUnit.Months), 2.957980250);
            cdsSpreads.Add(new Period(1, TimeUnit.Years), 3.076933100);
            cdsSpreads.Add(new Period(2, TimeUnit.Years), 2.944524520);
            cdsSpreads.Add(new Period(3, TimeUnit.Years), 2.844498960);
            cdsSpreads.Add(new Period(4, TimeUnit.Years), 2.769234420);
            cdsSpreads.Add(new Period(5, TimeUnit.Years), 2.713474100);
            double recoveryRate = 0.035;

            // Conventions
            int                   settlementDays    = 1;
            WeekendsOnly          calendar          = new WeekendsOnly();
            Frequency             frequency         = Frequency.Quarterly;
            BusinessDayConvention paymentConvention = BusinessDayConvention.Following;

            DateGeneration.Rule rule                 = DateGeneration.Rule.CDS2015;
            Actual360           dayCounter           = new Actual360();
            Actual360           lastPeriodDayCounter = new Actual360(true);

            // Create the CDS spread helpers.
            List <CdsHelper> instruments = new List <CdsHelper>();

            foreach (KeyValuePair <Period, double> it in cdsSpreads)
            {
                instruments.Add(
                    new SpreadCdsHelper(it.Value, it.Key, settlementDays, calendar,
                                        frequency, paymentConvention, rule, dayCounter, recoveryRate, usdYts, true, true, null,
                                        lastPeriodDayCounter));
            }

            // Create the default curve with the default IterativeBootstrap.
            DefaultProbabilityTermStructure dpts = new PiecewiseDefaultCurve <SurvivalProbability, LogLinear, IterativeBootstrapForCds>(asof, instruments, tsDayCounter);

            // Check that the default curve throws by requesting a default probability.
            Date testDate = new Date(21, Month.Dec, 2020);

            try
            {
                dpts.survivalProbability(testDate);
                throw new Exception();
            }
            catch {}

            // Create the default curve with an IterativeBootstrap allowing for 4 retries.
            // Use a maxFactor value of 1.0 so that we still use the previous survival probability at each pillar. In other
            // words, the survival probability cannot increase with time so best max at current pillar is the previous
            // pillar's value - there is no point increasing it on a retry.
            IterativeBootstrap <PiecewiseDefaultCurve, DefaultProbabilityTermStructure> ib =
                new IterativeBootstrap <PiecewiseDefaultCurve, DefaultProbabilityTermStructure>(null, null, null, 5, 1.0, 10.0);

            dpts = new PiecewiseDefaultCurve <SurvivalProbability, LogLinear>(asof, instruments, tsDayCounter, ib);

            // Check that the default curve still throws. It throws at the third pillar because the survival probability is
            // too low at the second pillar.
            try
            {
                dpts.survivalProbability(testDate);
                throw new Exception();
            }
            catch {}

            // Create the default curve with an IterativeBootstrap that allows for 4 retries and does not throw.
            IterativeBootstrap <PiecewiseDefaultCurve, DefaultProbabilityTermStructure> ibNoThrow =
                new IterativeBootstrap <PiecewiseDefaultCurve, DefaultProbabilityTermStructure>(null, null, null, 5, 1.0, 10.0, true, 2);

            dpts = new PiecewiseDefaultCurve <SurvivalProbability, LogLinear>(asof, instruments, tsDayCounter, ibNoThrow);

            try
            {
                dpts.survivalProbability(testDate);
            }
            catch
            {
                throw new Exception();
            }
        }
예제 #4
0
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(WeekendsOnly obj)
 {
     return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr);
 }
예제 #5
0
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(WeekendsOnly obj) {
   return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
 }
예제 #6
0
        public static MarketDatum ParseMarketDatum(Date asof, string datumName, double value)
        {
            List <string> tokens = datumName.Split('/').ToList();

            Utils.QL_REQUIRE(tokens.Count > 2, () => "more than 2 tokens expected in " + datumName);

            MarketDatum.InstrumentType instrumentType = ParseInstrumentType(tokens[0]);
            MarketDatum.QuoteType      quoteType      = ParseQuoteType(tokens[1]);

            switch (instrumentType)
            {
            case MarketDatum.InstrumentType.ZERO:
            {
                //ZERO / RATE / EUR / EUR1D / A365 / 1Y
                Utils.QL_REQUIRE(quoteType == MarketDatum.QuoteType.RATE || quoteType == MarketDatum.QuoteType.YIELD_SPREAD, () => "Invalid quote type for " + datumName);
                Utils.QL_REQUIRE(tokens.Count == 6, () => "6 tokens expected in " + datumName);
                string     ccy = tokens[2];
                DayCounter dc  = Parsers.ParseDayCounter(tokens[4]);
                // token 5 can be a date, or tenor
                Date   date   = new Date();
                Period tenor  = new Period();
                bool   isDate = false;
                Parsers.ParseDateOrPeriod(tokens[5], date, tenor, out isDate);
                return(new ZeroQuote(value, asof, datumName, quoteType, ccy, date, dc, tenor));
            }

            case MarketDatum.InstrumentType.DISCOUNT:
            {
                // DISCOUNT/RATE/EUR/EUR1D/1Y
                // DISCOUNT/RATE/EUR/EUR1D/2016-12-15
                Utils.QL_REQUIRE(tokens.Count == 5, () => "5 tokens expected in " + datumName);
                string ccy = tokens[2];
                // token 4 can be a date, or tenor
                Date   date   = new Date();
                Period tenor  = new Period();
                bool   isDate = false;
                Parsers.ParseDateOrPeriod(tokens[4], date, tenor, out isDate);
                if (!isDate)
                {
                    // we can't assume any calendar here, so we do the minimal adjustment with a weekend only calendar
                    Utils.QL_REQUIRE(tenor != null, () => "neither date nor tenor recognised");
                    date = new WeekendsOnly().adjust(asof + tenor);
                }
                return(new DiscountQuote(value, asof, datumName, quoteType, ccy, date));
            }

            //case MarketDatum.InstrumentType.MM:
            //    {
            //        QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName);
            //        const string&ccy = tokens[2];
            //        Period fwdStart = parsePeriod(tokens[3]);
            //        Period term = parsePeriod(tokens[4]);
            //        return boost::make_shared<MoneyMarketQuote>(value, asof, datumName, quoteType, ccy, fwdStart, term);
            //    }

            //case MarketDatum.InstrumentType.MM_FUTURE:
            //    {
            //        QL_REQUIRE(tokens.size() == 6, "6 tokens expected in " << datumName);
            //        const string&ccy = tokens[2];
            //        const string&expiry = tokens[3];
            //        const string&contract = tokens[4];
            //        Period term = parsePeriod(tokens[5]);
            //        return boost::make_shared<MMFutureQuote>(value, asof, datumName, quoteType, ccy, expiry, contract, term);
            //    }

            case MarketDatum.InstrumentType.FRA:
            {
                Utils.QL_REQUIRE(tokens.Count == 5, () => "5 tokens expected in " + datumName);
                string ccy      = tokens[2];
                Period fwdStart = Parsers.ParsePeriod(tokens[3]);
                Period term     = Parsers.ParsePeriod(tokens[4]);
                return(new FRAQuote(value, asof, datumName, quoteType, ccy, fwdStart, term));
            }

            //case MarketDatum.InstrumentType.IMM_FRA:
            //    {
            //        QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName);
            //        const string&ccy = tokens[2];
            //        string imm1 = tokens[3];
            //        string imm2 = tokens[4];
            //        unsigned int m1 = parseInteger(imm1);
            //        unsigned int m2 = parseInteger(imm2);
            //        QL_REQUIRE(m2 > m1, "Second IMM date must be after the first in " << datumName);
            //        return boost::make_shared<ImmFraQuote>(value, asof, datumName, quoteType, ccy, m1, m2);
            //    }

            case MarketDatum.InstrumentType.IR_SWAP:
            {
                Utils.QL_REQUIRE(tokens.Count == 6, () => "6 tokens expected in " + datumName);
                string ccy      = tokens[2];
                Period fwdStart = Parsers.ParsePeriod(tokens[3]);
                Period tenor    = Parsers.ParsePeriod(tokens[4]);
                Period term     = Parsers.ParsePeriod(tokens[5]);
                return(new SwapQuote(value, asof, datumName, quoteType, ccy, fwdStart, term, tenor));
            }

            //case MarketDatum.InstrumentType.BASIS_SWAP:
            //    {
            //        QL_REQUIRE(tokens.size() == 6, "6 tokens expected in " << datumName);
            //        Period flatTerm = parsePeriod(tokens[2]);
            //        Period term = parsePeriod(tokens[3]);
            //        const string&ccy = tokens[4];
            //        Period maturity = parsePeriod(tokens[5]);
            //        return boost::make_shared<BasisSwapQuote>(value, asof, datumName, quoteType, flatTerm, term, ccy, maturity);
            //    }

            case MarketDatum.InstrumentType.CC_BASIS_SWAP:
            {
                Utils.QL_REQUIRE(tokens.Count == 7, () => "7 tokens expected in " + datumName);
                string flatCcy  = tokens[2];
                Period flatTerm = Parsers.ParsePeriod(tokens[3]);
                string ccy      = tokens[4];
                Period term     = Parsers.ParsePeriod(tokens[5]);
                Period maturity = Parsers.ParsePeriod(tokens[6]);
                return(new CrossCcyBasisSwapQuote(value, asof, datumName, quoteType, flatCcy, flatTerm, ccy, term, maturity));
            }

            //case MarketDatum.InstrumentType.CDS:
            //    {
            //        QL_REQUIRE(tokens.size() == 6, "6 tokens expected in " << datumName);
            //        const string&underlyingName = tokens[2];
            //        const string&seniority = tokens[3];
            //        const string&ccy = tokens[4];
            //        Period term = parsePeriod(tokens[5]);
            //        return boost::make_shared<CdsSpreadQuote>(value, asof, datumName, underlyingName, seniority, ccy, term);
            //    }

            //case MarketDatum.InstrumentType.HAZARD_RATE:
            //    {
            //        QL_REQUIRE(tokens.size() == 6, "6 tokens expected in " << datumName);
            //        const string&underlyingName = tokens[2];
            //        const string&seniority = tokens[3];
            //        const string&ccy = tokens[4];
            //        Period term = parsePeriod(tokens[5]);
            //        return boost::make_shared<HazardRateQuote>(value, asof, datumName, underlyingName, seniority, ccy, term);
            //    }

            //case MarketDatum.InstrumentType.RECOVERY_RATE:
            //    {
            //        QL_REQUIRE(tokens.size() == 3 || tokens.size() == 5, "3 or 5 tokens expected in " << datumName);
            //        const string&underlyingName = tokens[2]; // issuer name for CDS, security ID for bond specific RRs
            //        string seniority = "";
            //        string ccy = "";
            //        if (tokens.size() == 5)
            //        {
            //            // CDS
            //            seniority = tokens[3];
            //            ccy = tokens[4];
            //        }
            //        return boost::make_shared<RecoveryRateQuote>(value, asof, datumName, underlyingName, seniority, ccy);
            //    }

            //case MarketDatum.InstrumentType.CAPFLOOR:
            //    {
            //        QL_REQUIRE(tokens.size() == 8 || tokens.size() == 4, "Either 4 or 8 tokens expected in " << datumName);
            //        const string&ccy = tokens[2];
            //        if (tokens.size() == 8)
            //        {
            //            Period term = parsePeriod(tokens[3]);
            //            Period tenor = parsePeriod(tokens[4]);
            //            bool atm = parseBool(tokens[5].c_str());
            //            bool relative = parseBool(tokens[6].c_str());
            //            Real strike = parseReal(tokens[7]);
            //            return boost::make_shared<CapFloorQuote>(value, asof, datumName, quoteType, ccy, term, tenor, atm, relative,
            //                                                     strike);
            //        }
            //        else
            //        {
            //            Period indexTenor = parsePeriod(tokens[3]);
            //            return boost::make_shared<CapFloorShiftQuote>(value, asof, datumName, quoteType, ccy, indexTenor);
            //        }
            //    }

            case MarketDatum.InstrumentType.SWAPTION:
            {
                Utils.QL_REQUIRE(tokens.Count == 4 || tokens.Count == 6 || tokens.Count == 7, () => "4, 6 or 7 tokens expected in " + datumName);

                string ccy    = tokens[2];
                Period expiry = tokens.Count >= 6 ? Parsers.ParsePeriod(tokens[3]) : new Period(0, TimeUnit.Days);
                Period term   = tokens.Count >= 6 ? Parsers.ParsePeriod(tokens[4]) : Parsers.ParsePeriod(tokens[3]);
                if (tokens.Count >= 6)
                {         // volatility
                    string dimension = tokens[5];
                    double strike    = 0.0;
                    if (dimension == "ATM")
                    {
                        Utils.QL_REQUIRE(tokens.Count == 6, () => "6 tokens expected in ATM quote " + datumName);
                    }
                    else if (dimension == "Smile")
                    {
                        Utils.QL_REQUIRE(tokens.Count == 7, () => "7 tokens expected in Smile quote " + datumName);
                        strike = Parsers.ParseDouble(tokens[6]);
                    }
                    else
                    {
                        Utils.QL_FAIL("Swaption vol quote dimension " + dimension + " not recognised");
                    }
                    return(new SwaptionQuote(value, asof, datumName, quoteType, ccy, expiry, term, dimension, strike));
                }
                else
                {         // SLN volatility shift
                    return(null);
                    //return new SwaptionShiftQuote(value, asof, datumName, quoteType, ccy, term);
                }
            }

            case MarketDatum.InstrumentType.FX_SPOT:
            {
                Utils.QL_REQUIRE(tokens.Count == 4, () => "4 tokens expected in " + datumName);
                string unitCcy = tokens[2];
                string ccy     = tokens[3];
                return(new FXSpotQuote(value, asof, datumName, quoteType, unitCcy, ccy));
            }

            case MarketDatum.InstrumentType.FX_FWD:
            {
                Utils.QL_REQUIRE(tokens.Count == 5, () => "5 tokens expected in " + datumName);
                string unitCcy = tokens[2];
                string ccy     = tokens[3];
                Period term    = Parsers.ParsePeriod(tokens[4]);
                return(new FXForwardQuote(value, asof, datumName, quoteType, unitCcy, ccy, term));
            }

            case MarketDatum.InstrumentType.FX_OPTION:
            {
                Utils.QL_REQUIRE(tokens.Count == 6, () => "6 tokens expected in " + datumName);
                string unitCcy = tokens[2];
                string ccy     = tokens[3];
                Period expiry  = Parsers.ParsePeriod(tokens[4]);
                string strike  = tokens[5];
                return(new FXOptionQuote(value, asof, datumName, quoteType, unitCcy, ccy, expiry, strike));
            }

            //case MarketDatum.InstrumentType.ZC_INFLATIONSWAP:
            //    {
            //        QL_REQUIRE(tokens.size() == 4, "4 tokens expected in " << datumName);
            //        const string&index = tokens[2];
            //        Period term = parsePeriod(tokens[3]);
            //        return boost::make_shared<ZcInflationSwapQuote>(value, asof, datumName, index, term);
            //    }

            //case MarketDatum.InstrumentType.YY_INFLATIONSWAP:
            //    {
            //        QL_REQUIRE(tokens.size() == 4, "4 tokens expected in " << datumName);
            //        const string&index = tokens[2];
            //        Period term = parsePeriod(tokens[3]);
            //        return boost::make_shared<YoYInflationSwapQuote>(value, asof, datumName, index, term);
            //    }

            //case MarketDatum.InstrumentType.ZC_INFLATIONCAPFLOOR:
            //    {
            //        QL_REQUIRE(tokens.size() == 6, "6 tokens expected in " << datumName);
            //        const string&index = tokens[2];
            //        Period term = parsePeriod(tokens[3]);
            //        QL_REQUIRE(tokens[4] == "C" || tokens[4] == "F",
            //                   "excepted C or F for Cap or Floor at position 5 in " << datumName);
            //        bool isCap = tokens[4] == "C";
            //        string strike = tokens[5];
            //        return boost::make_shared<ZcInflationCapFloorQuote>(value, asof, datumName, quoteType, index, term, isCap,
            //                                                            strike);
            //    }

            //case MarketDatum.InstrumentType.SEASONALITY:
            //    {
            //        QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName);
            //        const string&index = tokens[3];
            //        const string&type = tokens[2];
            //        const string&month = tokens[4];
            //        return boost::make_shared<SeasonalityQuote>(value, asof, datumName, index, type, month);
            //    }
            //case MarketDatum.InstrumentType.EQUITY_SPOT:
            //    {
            //        QL_REQUIRE(tokens.size() == 4, "4 tokens expected in " << datumName);
            //        QL_REQUIRE(quoteType == MarketDatum.QuoteType.PRICE, "Invalid quote type for " << datumName);
            //        const string&equityName = tokens[2];
            //        const string&ccy = tokens[3];
            //        return boost::make_shared<EquitySpotQuote>(value, asof, datumName, quoteType, equityName, ccy);
            //    }

            //case MarketDatum.InstrumentType.EQUITY_FWD:
            //    {
            //        QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName);
            //        QL_REQUIRE(quoteType == MarketDatum.QuoteType.PRICE, "Invalid quote type for " << datumName);
            //        const string&equityName = tokens[2];
            //        const string&ccy = tokens[3];
            //        Date expiryDate = getDateFromDateOrPeriod(tokens[4], asof);
            //        return boost::make_shared<EquityForwardQuote>(value, asof, datumName, quoteType, equityName, ccy, expiryDate);
            //    }

            //case MarketDatum.InstrumentType.EQUITY_DIVIDEND:
            //    {
            //        QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName);
            //        QL_REQUIRE(quoteType == MarketDatum.QuoteType.RATE, "Invalid quote type for " << datumName);
            //        const string&equityName = tokens[2];
            //        const string&ccy = tokens[3];
            //        Date tenorDate = getDateFromDateOrPeriod(tokens[4], asof);
            //        return boost::make_shared<EquityDividendYieldQuote>(value, asof, datumName, quoteType, equityName, ccy,
            //                                                            tenorDate);
            //    }

            //case MarketDatum.InstrumentType.EQUITY_OPTION:
            //    {
            //        QL_REQUIRE(tokens.size() == 6, "6 tokens expected in " << datumName);
            //        QL_REQUIRE(quoteType == MarketDatum.QuoteType.RATE_LNVOL, "Invalid quote type for " << datumName);
            //        const string&equityName = tokens[2];
            //        const string&ccy = tokens[3];
            //        string expiryString = tokens[4];
            //        const string&strike = tokens[5];
            //        // note how we only store the expiry string - to ensure we can support both Periods and Dates being specified in
            //        // the vol curve-config.
            //        return boost::make_shared<EquityOptionQuote>(value, asof, datumName, quoteType, equityName, ccy, expiryString,
            //                                                     strike);
            //    }

            //case MarketDatum.InstrumentType.BOND:
            //    {
            //        QL_REQUIRE(tokens.size() == 3, "3 tokens expected in " << datumName);
            //        const string&securityID = tokens[2];
            //        return boost::make_shared<SecuritySpreadQuote>(value, asof, datumName, securityID);
            //    }

            //case MarketDatum.InstrumentType.CDS_INDEX:
            //    {
            //        QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName);
            //        QL_REQUIRE(quoteType == MarketDatum.QuoteType.BASE_CORRELATION, "Invalid quote type for " << datumName);
            //        const string&cdsIndexName = tokens[2];
            //        Period term = parsePeriod(tokens[3]);
            //        Real detachmentPoint = parseReal(tokens[4]);
            //        return boost::make_shared<BaseCorrelationQuote>(value, asof, datumName, quoteType, cdsIndexName, term,
            //                                                        detachmentPoint);
            //    }

            //case MarketDatum.InstrumentType.INDEX_CDS_OPTION:
            //    {
            //        QL_REQUIRE(tokens.size() == 4, "4 tokens expected in " << datumName);
            //        QL_REQUIRE(quoteType == MarketDatum.QuoteType.RATE_LNVOL, "Invalid quote type for " << datumName);
            //        const string&indexName = tokens[2];
            //        const string&expiry = tokens[3];
            //        return boost::make_shared<IndexCDSOptionQuote>(value, asof, datumName, indexName, expiry);
            //    }

            default:
                //Utils.QL_FAIL("Cannot convert \"" + datumName + "\" to MarketDatum");
                return(null);
            }
        }