/// <summary> /// Bootstraps the specified priceable assets, where the assets /// are simple commodity asset with single cash flows on a /// single index observation. /// </summary> /// <param name="priceableAssets">The priceable assets.</param> /// <param name="referenceCurve">The reference curve.</param> /// <param name="baseDate">The base date.</param> /// <param name="extrapolationPermitted">The extrapolationPermitted flag.</param> /// <param name="tolerance">The tolerance for the solver</param> /// <param name="spreadXArray">THe spread interpolator produced in the bootstrapper</param> /// <param name="spreadYArray">THe spread interpolator produced in the bootstrapper</param> /// <returns></returns> public static TermPoint[] Bootstrap(IEnumerable <IPriceableCommoditySpreadAssetController> priceableAssets, ICommodityCurve referenceCurve, DateTime baseDate, bool extrapolationPermitted, double tolerance, ref IList <double> spreadXArray, ref IList <double> spreadYArray) { //only works for linear on zero. //InterpolationMethod interp = InterpolationMethodHelper.Parse("LinearInterpolation"); // Add the first element (date : discount factor) to the list var points = new Dictionary <DateTime, double>(); var items = new SortedDictionary <DateTime, Pair <string, decimal> >(); var dayCounter = new Actual365(); foreach (var priceableAsset in priceableAssets) { DateTime assetMaturityDate = priceableAsset.GetRiskMaturityDate(); if (points.Keys.Contains(assetMaturityDate)) { continue; } //This now should automatically extrapolate the required discount factor on a flat rate basis. if (IsSpreadAsset(priceableAsset)) { //These are simple assts so the solver is unnecessary. var value = (double)priceableAsset.CalculateImpliedQuoteWithSpread(referenceCurve); var dayCount = dayCounter.YearFraction(baseDate, assetMaturityDate); spreadXArray.Add(dayCount); spreadYArray.Add((double)priceableAsset.MarketQuote.value); //TODO Get the marketquote points.Add(assetMaturityDate, value); items.Add(assetMaturityDate, new Pair <string, decimal>(priceableAsset.Id, (decimal)points[assetMaturityDate])); } } if (spreadXArray.Count > 2) { var spreadCurveInterpolator = new LinearInterpolation(spreadXArray.ToArray(), spreadYArray.ToArray()); var index = 0; foreach (var assetMaturityDate in referenceCurve.GetTermCurve().GetListTermDates()) { if (points.Keys.Contains(assetMaturityDate)) { continue; } var dayCount = dayCounter.YearFraction(baseDate, assetMaturityDate); double spreadValue = spreadCurveInterpolator.ValueAt(dayCount, true); var value = referenceCurve.GetForward(baseDate, assetMaturityDate); points.Add(assetMaturityDate, value + spreadValue); items.Add(assetMaturityDate, new Pair <string, decimal>("RefCurvePillar_" + index, (decimal)points[assetMaturityDate])); index++; } return(TermPointsFactory.Create(items)); } return(null); }
/// <summary> /// Turn a date based description of a CDS accrual period (<seealso cref="CdsCouponDes"/>) into an analytic description /// (<seealso cref="CdsCoupon"/>). This uses ACT/360 for the accrual day count. /// </summary> /// <param name="tradeDate"> The trade date </param> /// <param name="coupon"> A date based description of a CDS accrual period </param> /// <param name="protectionFromStartOfDay"> If true the protection is from the start of day and the effective accrual /// start and end dates are one day less. The exception is the accrual end date which should have one day /// added (if protectionFromStartOfDay = true) in the CDSCouponDes to compensate for this, so the /// accrual end date is just the CDS maturity. /// The effect of having protectionFromStartOfDay = true is to add an extra day of protection. </param> /// <param name="curveDCC"> Day count used on curve (NOTE ISDA uses ACT/365 (fixed) and it is not recommended to change this) </param> public CdsCoupon(DateTime tradeDate, CdsCouponDes coupon, bool protectionFromStartOfDay, Enums.DayCount curveDCC) { DateTime effStart = protectionFromStartOfDay ? coupon.getAccStart().AddDays(1) : coupon.getAccStart(); DateTime effEnd = protectionFromStartOfDay ? coupon.getAccEnd().AddDays(-1) : coupon.getAccEnd(); Actual365 dc = new Actual365(); _effStart = DateTime.Compare(effStart, tradeDate) < 0 ? -dc.YearFraction(effStart, tradeDate) : dc.YearFraction(tradeDate, effStart); _effEnd = dc.YearFraction(tradeDate, effEnd); _paymentTime = dc.YearFraction(tradeDate, coupon.getPaymentDate()); _yearFrac = coupon.getYearFrac(); _ycRatio = _yearFrac / dc.YearFraction(coupon.getAccStart(), coupon.getAccEnd()); }
private static double[] toDoubles(DateTime tradeDate, bool protectionFromStartOfDay, Enums.DayCount accrualDCC, Enums.DayCount curveDCC, params DateTime[] premDates) { DateTime accStart = premDates[0]; DateTime accEnd = premDates[1]; DateTime paymentDate = premDates[2]; DateTime effStart = protectionFromStartOfDay ? accStart.AddDays(-1) : accStart; DateTime effEnd = protectionFromStartOfDay ? accEnd.AddDays(-1) : accEnd; double[] res = new double[5]; // *@param protectionFromStartOfDay true if protection is from the start of day (true for standard CDS) // *@param accrualDCC The day - count - convention used for calculation the accrual period(ACT / 360 for standard CDS) // *@param curveDCC The day - count - convention used for converting dates to time intervals along curves - this should be ACT / 365F Actual365 dc = new Actual365(); Actual360 accrualDCC_ = new Actual360(); res[0] = DateTime.Compare(effStart, tradeDate) < 0 ? -dc.YearFraction(effStart, tradeDate) : dc.YearFraction(tradeDate, effStart); res[1] = dc.YearFraction(tradeDate, effEnd); res[2] = dc.YearFraction(tradeDate, paymentDate); res[3] = accrualDCC_.YearFraction(accStart, accEnd); res[4] = res[3] / dc.YearFraction(accStart, accEnd); return(res); }