Ejemplo n.º 1
0
        public override void FromXML(XmlNode node)
        {
            CheckNode(node, "YieldCurve");

            // Read in the mandatory nodes.
            _curveID          = GetChildValue(node, "CurveId", true);
            _curveDescription = GetChildValue(node, "CurveDescription", true);
            _currency         = GetChildValue(node, "Currency", true);
            _discountCurveID  = GetChildValue(node, "DiscountCurve", true);

            // Read in the segments.
            XmlNode segmentsNode = GetChildNode(node, "Segments");

            if (segmentsNode != null)
            {
                XmlNode child = GetChildNode(segmentsNode, "");
                while (child != null)
                {
                    YieldCurveSegment segment   = new YieldCurveSegment();
                    string            childName = GetNodeName(child);

                    if (childName == "Direct")
                    {
                        segment = new DirectYieldCurveSegment();
                    }
                    else if (childName == "Simple")
                    {
                        segment = new SimpleYieldCurveSegment();
                    }
                    else if (childName == "AverageOIS")
                    {
                        segment = new AverageOISYieldCurveSegment();
                    }
                    else if (childName == "TenorBasis")
                    {
                        segment = new TenorBasisYieldCurveSegment();
                    }
                    else if (childName == "CrossCurrency")
                    {
                        segment = new CrossCcyYieldCurveSegment();
                    }
                    else if (childName == "ZeroSpread")
                    {
                        segment = new ZeroSpreadedYieldCurveSegment();
                    }
                    else
                    {
                        Utils.QL_FAIL("Yield curve segment node name not recognized.");
                    }

                    if (segment != null)
                    {
                        try
                        {
                            segment.FromXML(child);
                        }
                        catch (Exception ex)
                        {
                            //ALOG("Exception parsing yield curve segment XML Node, name = " + childName + " and curveID = " + _curveID + " : " + ex.ToString();
                        }
                    }
                    else
                    {
                        //LOG("Unable to build yield curve segment for name = " << childName << " and curveID = " << curveID_);
                    }

                    _curveSegments.Add(segment);
                    child = GetNextSibling(child, "");
                }
            }
            else
            {
                Utils.QL_FAIL("No Segments node in XML doc for yield curve ID = " + _curveID);
            }

            // Read in the optional nodes.

            // Empty strings if not there (or if there and empty).
            _interpolationVariable = GetChildValue(node, "InterpolationVariable", false);
            _interpolationMethod   = GetChildValue(node, "InterpolationMethod", false);
            _zeroDayCounter        = GetChildValue(node, "YieldCurveDayCounter", false);

            // Add hardcoded defaults for now.
            if (_interpolationVariable == "")
            {
                _interpolationVariable = "Discount";
            }
            if (_interpolationMethod == "")
            {
                _interpolationMethod = _interpolationVariable == "Zero" ? "Linear" : "LogLinear";
            }
            if (_zeroDayCounter == "")
            {
                _zeroDayCounter = "A365";
            }
            XmlNode nodeToTest = GetChildNode(node, "Extrapolation");

            if (nodeToTest != null)
            {
                _extrapolation = GetChildValueAsBool(node, "Extrapolation", false);
            }
            else
            {
                _extrapolation = true;
            }
            nodeToTest = GetChildNode(node, "Tolerance");
            if (nodeToTest != null)
            {
                _tolerance = GetChildValueAsDouble(node, "Tolerance", false);
            }
            else
            {
                _tolerance = 1.0e-12;
            }

            PopulateRequiredYieldCurveIDs();
        }
Ejemplo n.º 2
0
        private void BuildDiscountCurve()
        {
            Utils.QL_REQUIRE(_curveSegments.Count <= 1, () => "More than one zero curve segment not supported yet.");
            Utils.QL_REQUIRE(_curveSegments[0].CurveSegmentType() == YieldCurveSegment.Type.Zero, () => "The curve segment is not of type Zero.");

            // Fill a vector of zero quotes.
            List <ZeroQuote>        zeroQuotes       = new List <ZeroQuote>();
            DirectYieldCurveSegment zeroCurveSegment = _curveSegments[0] as DirectYieldCurveSegment;

            List <string> zeroQuoteIDs = zeroCurveSegment.Quotes();

            for (int i = 0; i < zeroQuoteIDs.Count; ++i)
            {
                MarketDatum marketQuote = _loader.Get(zeroQuoteIDs[i], _asofDate);
                if (marketQuote != null)
                {
                    Utils.QL_REQUIRE(marketQuote.GetInstrumentType() == MarketDatum.InstrumentType.ZERO, () => "Market quote not of type zero.");
                    ZeroQuote zeroQuote = marketQuote as ZeroQuote;
                    zeroQuotes.Add(zeroQuote);
                }
                else
                {
                    Utils.QL_FAIL("Could not find quote for ID " + zeroQuoteIDs[i] + " with as of date " + _asofDate + ".");
                }
            }

            // Create the (date, zero) pairs.
            Dictionary <Date, double> data = new Dictionary <Date, double>();
            Convention convention          = _conventions.Get(_curveSegments[0].ConventionsID());

            Utils.QL_REQUIRE(convention != null, () => "No conventions found with ID: " + _curveSegments[0].ConventionsID());
            Utils.QL_REQUIRE(convention.ConventionType() == Convention.Type.Zero, () => "Conventions ID does not give zero rate conventions.");
            ZeroRateConvention zeroConvention  = convention as ZeroRateConvention;
            DayCounter         quoteDayCounter = zeroConvention.DayCounter();

            for (int i = 0; i < zeroQuotes.Count; ++i)
            {
                Utils.QL_REQUIRE(quoteDayCounter == zeroQuotes[i].DayCounter(), () => "The day counter should be the same between the conventions and the quote.");

                if (!zeroQuotes[i].TenorBased())
                {
                    data[zeroQuotes[i].Date()] = zeroQuotes[i].Quote().link.value();
                }
                else
                {
                    Utils.QL_REQUIRE(zeroConvention.TenorBased(), () => "Using tenor based zero rates without tenor based zero rate conventions.");


                    Date zeroDate = _asofDate;
                    if (zeroConvention.SpotLag() > 0)
                    {
                    }

                    zeroDate       = zeroConvention.SpotCalendar().advance(zeroDate, new Period(zeroConvention.SpotLag(), TimeUnit.Days));
                    zeroDate       = zeroConvention.TenorCalendar().advance(zeroDate, zeroQuotes[i].Tenor(), zeroConvention.RollConvention(), zeroConvention.Eom());
                    data[zeroDate] = zeroQuotes[i].Quote().link.value();
                }
            }

            Utils.QL_REQUIRE(data.Count > 0, () => "No market data found for curve spec " + _curveSpec.Name() + " with as of date " + _asofDate);


            // \todo review - more flexible (flat vs. linear extrap)?
            if (data.Keys.First() > _asofDate)
            {
                double rate = data.Values.First();
                data[_asofDate] = rate;
                //LOG("Insert zero curve point at time zero for " + curveSpec_.name() + ": "+ "date " + _asofDate + ", "+"zero " + data[_asofDate]);
            }

            Utils.QL_REQUIRE(data.Count > 1, () => "The single zero rate quote provided should be associated with a date greater than as of date.");

            // First build temporary curves
            List <Date>   dates     = new List <Date>();
            List <double> zeroes    = new List <double>();
            List <double> discounts = new List <double>();

            dates.Add(data.Keys.First());
            zeroes.Add(data.Values.First());
            discounts.Add(1.0);

            Compounding zeroCompounding     = zeroConvention.Compounding();
            Frequency   zeroCompoundingFreq = zeroConvention.CompoundingFrequency();
            Dictionary <Date, double> it;

            foreach (KeyValuePair <Date, double> kvp in data)
            {
                Date   d = kvp.Key;
                double r = kvp.Value;

                dates.Add(d);
                InterestRate tempRate = new InterestRate(r, quoteDayCounter, zeroCompounding, zeroCompoundingFreq);
                double       t        = quoteDayCounter.yearFraction(_asofDate, d);
                /* Convert zero rate to continuously compounded if necessary */
                if (zeroCompounding == Compounding.Continuous)
                {
                    zeroes.Add(r);
                }
                else
                {
                    zeroes.Add(tempRate.equivalentRate(Compounding.Continuous, Frequency.Annual, t).value());
                }
                discounts.Add(tempRate.discountFactor(t));
                //LOG("Add zero curve point for " + curveSpec_.name() + ": " + dates.Last() + " " + zeroes.Last() + " / " + discounts.Last());
            }

            Utils.QL_REQUIRE(dates.Count == zeroes.Count, () => "Date and zero vectors differ in size.");
            Utils.QL_REQUIRE(dates.Count == discounts.Count, () => "Date and discount vectors differ in size.");

            // Now build curve with requested conventions
            if (_interpolationVariable == YieldCurve.InterpolationVariable.Zero)
            {
                YieldTermStructure tempCurve = Zerocurve(dates, zeroes, quoteDayCounter);
                zeroes.Clear();
                for (int i = 0; i < dates.Count; ++i)
                {
                    double zero = tempCurve.zeroRate(dates[i], _zeroDayCounter, Compounding.Continuous).value();
                    zeroes.Add(zero);
                }

                _p = Zerocurve(dates, zeroes, _zeroDayCounter);
            }
            else if (_interpolationVariable == YieldCurve.InterpolationVariable.Discount)
            {
                YieldTermStructure tempCurve = Discountcurve(dates, discounts, quoteDayCounter);
                discounts.Clear();
                for (int i = 0; i < dates.Count; ++i)
                {
                    double discount = tempCurve.discount(dates[i]);
                    discounts.Add(discount);
                }
                _p = Discountcurve(dates, discounts, _zeroDayCounter);
            }
            else
            {
                Utils.QL_FAIL("Unknown yield curve interpolation variable.");
            }
        }