public override void FromXML(XmlNode node) { // TODO: Implement correctly //XmlNode conventionsNode = node.SelectSingleNode("Conventions"); CheckNode(node, "Conventions"); foreach (XmlNode child in node.ChildNodes) { if (child.NodeType == XmlNodeType.Comment) { continue; } Convention convention = new Convention(); string childName = child.Name; if (childName == "Zero") { convention = new ZeroRateConvention(); } else if (childName == "Deposit") { convention = new DepositConvention(); } else if (childName == "Future") { convention = new FutureConvention(); } else if (childName == "FRA") { convention = new FraConvention(); } else if (childName == "OIS") { convention = new OisConvention(); } else if (childName == "Swap") { convention = new IRSwapConvention(); } //else if (childName == "AverageOIS") //{ // convention.reset(new AverageOisConvention()); //} //else if (childName == "TenorBasisSwap") //{ // convention.reset(new TenorBasisSwapConvention()); //} //else if (childName == "TenorBasisTwoSwap") //{ // convention.reset(new TenorBasisTwoSwapConvention()); //} else if (childName == "FX") { convention = new FXConvention(); } //else if (childName == "CrossCurrencyBasis") //{ // convention.reset(new CrossCcyBasisSwapConvention()); //} //else if (childName == "CDS") //{ // convention.reset(new CdsConvention()); //} //else if (childName == "SwapIndex") //{ // convention.reset(new SwapIndexConvention()); //} //else if (childName == "InflationSwap") //{ // convention.reset(new InflationSwapConvention()); //} else { // Temporary before having implemented all conventions continue; //QLNet.Utils.QL_FAIL("Convention name, " + childName + ", not recognized."); } string id = child.SelectSingleNode("Id").FirstChild.Value; try { //DLOG("Loading Convention " << id); convention.FromXML(child); Add(convention); } catch (Exception ex) { //Utils.QL_FAIL("Exception parsing convention XML Node (id = " + id + ") : " + ex.ToString()); //WLOG("Exception parsing convention " "XML Node (id = " << id << ") : " << e.what()); } } }
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."); } }