/// <summary> /// Make a set of CDSCouponDes. /// </summary> /// <param name="leg"> the schedule of the accrual periods </param> /// <param name="accrualDCC"> the day count used for the accrual </param> /// <returns> a set of CDSCouponDes </returns> public static CdsCouponDes[] makeCoupons(IsdaPremiumLegSchedule leg, Enums.DayCount accrualDCC) { int n = leg.NumPayments; CdsCouponDes[] coupons = new CdsCouponDes[n]; for (int i = 0; i < n; i++) { coupons[i] = new CdsCouponDes(leg.getAccStartDate(i), leg.getAccEndDate(i), leg.getPaymentDate(i), accrualDCC); } return coupons; }
/// <summary> /// Make a set of CDSCoupon used by <seealso cref="CdsAnalytic"/> given a trade date and a set of <seealso cref="CdsCouponDes"/>. /// </summary> /// <param name="tradeDate"> The trade date </param> /// <param name="couponsDes"> Description of CDS accrual periods with DateTime </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> /// <returns> A set of CDSCoupon </returns> public static CdsCoupon[] makeCoupons(DateTime tradeDate, CdsCouponDes[] couponsDes, bool protectionFromStartOfDay, Enums.DayCount curveDCC) { int n = couponsDes.Length; int count = 0; while (DateTime.Compare(tradeDate, couponsDes[count].getPaymentDate()) > 0) { count++; } int nCoupons = n - count; CdsCoupon[] coupons = new CdsCoupon[nCoupons]; for (int i = 0; i < nCoupons; i++) { coupons[i] = new CdsCoupon(tradeDate, couponsDes[i + count], protectionFromStartOfDay, curveDCC); } return(coupons); }
/// <summary> /// Make a set of CDSCoupon used by <seealso cref="CdsAnalytic"/> given a trade date and the schedule of the accrual periods. /// </summary> /// <param name="tradeDate"> The trade date </param> /// <param name="leg"> schedule of the accrual periods </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 has one day /// added (if protectionFromStartOfDay = true) in ISDAPremiumLegSchedule 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="accrualDCC"> The day count used to compute accrual periods </param> /// <param name="curveDCC"> Day count used on curve (NOTE ISDA uses ACT/365 (fixed) and it is not recommended to change this) </param> /// <seealso cref= CdsAnalytic </seealso> /// <returns> A set of CDSCoupon </returns> public static CdsCoupon[] makeCoupons(DateTime tradeDate, IsdaPremiumLegSchedule leg, bool protectionFromStartOfDay, Enums.DayCount accrualDCC, Enums.DayCount curveDCC) { int n = leg.NumPayments; CdsCoupon[] res = new CdsCoupon[n]; for (int i = 0; i < n; i++) { DateTime[] dates = leg.getAccPaymentDateTriplet(i); res[i] = new CdsCoupon(tradeDate, dates[0], dates[1], dates[2], protectionFromStartOfDay, accrualDCC, curveDCC); } return(res); }
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); }
/// <summary> /// Setup a analytic description (i.e. involving only doubles) of a single CDS premium payment period /// seen from a particular trade date. /// </summary> /// <param name="tradeDate"> The trade date (this is the base date that discount factors and survival probabilities are measured from) </param> /// <param name="accStart"> The start of the accrual period </param> /// <param name="accEnd"> The end of the accrual period </param> /// <param name="paymentDate"> The date of the premium payment </param> /// <param name="protectionFromStartOfDay"> true if protection is from the start of day (true for standard CDS) </param> /// <param name="accrualDCC"> The day-count-convention used for calculation the accrual period (ACT/360 for standard CDS) </param> /// <param name="curveDCC"> The day-count-convention used for converting dates to time intervals along curves - this should be ACT/365F </param> public CdsCoupon(DateTime tradeDate, DateTime accStart, DateTime accEnd, DateTime paymentDate, bool protectionFromStartOfDay, Enums.DayCount accrualDCC, Enums.DayCount curveDCC) : this(toDoubles(tradeDate, protectionFromStartOfDay, accrualDCC, curveDCC, accStart, accEnd, paymentDate)) { }
/// <summary> /// Setup a analytic description (i.e. involving only doubles) of a single CDS premium payment period /// seen from a particular trade date. /// </summary> /// <param name="tradeDate"> The trade date (this is the base date that discount factors and survival probabilities are measured from) </param> /// <param name="premiumDateTriplet"> The three dates: start and end of the accrual period and the payment time </param> /// <param name="protectionFromStartOfDay"> true if protection is from the start of day (true for standard CDS) </param> /// <param name="accrualDCC"> The day-count-convention used for calculation the accrual period (ACT/360 for standard CDS) </param> /// <param name="curveDCC"> The day-count-convention used for converting dates to time intervals along curves - this should be ACT/365F </param> public CdsCoupon(DateTime tradeDate, DateTime[] premiumDateTriplet, bool protectionFromStartOfDay, Enums.DayCount accrualDCC, Enums.DayCount curveDCC) : this(toDoubles(tradeDate, protectionFromStartOfDay, accrualDCC, curveDCC, premiumDateTriplet)) { }
/// <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()); }
/// <summary> /// Turn a date based description of a CDS accrual period (<seealso cref="CdsCouponDes"/>) into an analytic description /// (<seealso cref="CdsCoupon"/>). This has protection from start of day and 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="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, Enums.DayCount curveDCC) : this(tradeDate, coupon, PROTECTION_FROM_START, curveDCC) { }
/** * Set up a strip of increasing maturity CDSs that have some coupons in common. The trade date, step-in date and valuation date and * accrual start date are all common, as is the payment frequency. The maturities are expressed as integer multiples of the * payment interval from a reference date (the next IMM date after the trade date for standard CDSs) - this guarantees that premiums * will be the same across several CDSs. * @param tradeDate The trade date * @param stepinDate (aka Protection Effective sate or assignment date). Date when party assumes ownership. This is usually T+1. This is when protection * (and risk) starts in terms of the model. Note, this is sometimes just called the Effective Date, however this can cause * confusion with the legal effective date which is T-60 or T-90. * @param cashSettlementDate The cash settlement date. The date that values are PVed to. Is is normally today + 3 business days. * @param accStartDate Accrual Start Date. This is when the CDS nominally starts in terms of premium payments. i.e. the number * of days in the first period (and thus the amount of the first premium payment) is counted from this date. * @param maturityReferanceDate A reference date that maturities are measured from. For standard CDSSs, this is the next IMM date after * the trade date, so the actually maturities will be some fixed periods after this. * @param maturityIndexes The maturities are fixed integer multiples of the payment interval, so for 6M, 1Y and 2Y tenors with a 3M * payment interval, would require 2, 4, and 8 as the indices * @param payAccOnDefault Is the accrued premium paid in the event of a default * @param paymentInterval The nominal step between premium payments (e.g. 3 months, 6 months). * @param stubType the stub convention * @param protectStart If protectStart = true, then protections starts at the beginning of the day, otherwise it is at the end. * @param recoveryRate The recovery rate * @param businessdayAdjustmentConvention How are adjustments for non-business days made * @param calendar HolidayCalendar defining what is a non-business day * @param accrualDayCount Day count used for accrual * @param curveDayCount Day count used on curve (NOTE ISDA uses ACT/365 and it is not recommended to change this) */ public MultiCdsAnalytic( DateTime tradeDate, DateTime stepinDate, DateTime cashSettlementDate, DateTime accStartDate, DateTime maturityReferanceDate, int[] maturityIndexes, Boolean payAccOnDefault, int paymentInterval, StubConvention stubType, Boolean protectStart, double recoveryRate, QLNet.BusinessDayConvention businessdayAdjustmentConvention, QLNet.Calendar calendar, Enums.DayCount accrualDayCount, Enums.DayCount curveDayCount) { OMLib.Conventions.DayCount.Thirty360 swapDCC = new OMLib.Conventions.DayCount.Thirty360(); OMLib.Conventions.DayCount.Actual360 moneyMarketDCC = new OMLib.Conventions.DayCount.Actual360(); OMLib.Conventions.DayCount.Actual365 curveDCC = new OMLib.Conventions.DayCount.Actual365(); _nMaturities = maturityIndexes.Length; _payAccOnDefault = payAccOnDefault; _accStart = DateTime.Compare(accStartDate, tradeDate) < 0 ? -curveDCC.YearFraction(accStartDate, tradeDate) : curveDCC.YearFraction(tradeDate, accStartDate); DateTime temp = DateTime.Compare(stepinDate, accStartDate) > 0 ? stepinDate : accStartDate; DateTime effectiveStartDate = protectStart ? temp.AddDays(-1) : temp; _cashSettlementTime = curveDCC.YearFraction(tradeDate, cashSettlementDate); _effectiveProtectionStart = curveDCC.YearFraction(tradeDate, effectiveStartDate); _lgd = 1 - recoveryRate; DateTime[] maturities = new DateTime[_nMaturities]; _protectionEnd = new double[_nMaturities]; int period = paymentInterval; for (int i = 0; i < _nMaturities; i++) { int tStep = period * maturityIndexes[i]; maturities[i] = maturityReferanceDate.AddMonths(tStep); _protectionEnd[i] = curveDCC.YearFraction(tradeDate, maturities[i]); } IsdaPremiumLegSchedule fullPaymentSchedule = new IsdaPremiumLegSchedule(accStartDate, maturities[_nMaturities - 1], period, stubType, businessdayAdjustmentConvention, calendar, protectStart); //remove already expired coupons IsdaPremiumLegSchedule paymentSchedule = fullPaymentSchedule.truncateSchedule(stepinDate); int couponOffset = fullPaymentSchedule.getNumPayments() - paymentSchedule.getNumPayments(); _totalPayments = paymentSchedule.getNumPayments(); _standardCoupons = new CdsCoupon[_totalPayments - 1]; for (int i = 0; i < (_totalPayments - 1); i++) { //The last coupon is actually a terminal coupon, so not included here _standardCoupons[i] = new CdsCoupon( tradeDate, paymentSchedule.getAccPaymentDateTriplet(i), protectStart, accrualDayCount, curveDayCount); } //find the terminal coupons _terminalCoupons = new CdsCoupon[_nMaturities]; _matIndexToPayments = new int[_nMaturities]; _accruedDays = new int[_nMaturities]; _accrued = new double[_nMaturities]; long secondJulianDate = stepinDate.Ticks; for (int i = 0; i < _nMaturities; i++) { int index = fullPaymentSchedule.getNominalPaymentDateIndex(maturities[i]); //maturity is unadjusted, but if protectionStart=true (i.e. standard CDS) there is effectively an extra day of accrued interest DateTime accEnd = protectStart ? maturities[i].AddDays(1) : maturities[i]; _terminalCoupons[i] = new CdsCoupon( tradeDate, fullPaymentSchedule.getAccStartDate(index), accEnd, fullPaymentSchedule.getPaymentDate(index), protectStart); _matIndexToPayments[i] = index - couponOffset; //This will only matter for the edge case when the trade date is 1 day before maturity DateTime tDate2 = _matIndexToPayments[i] < 0 ? fullPaymentSchedule.getAccStartDate(couponOffset - 1) : paymentSchedule.getAccStartDate(0); long firstJulianDate = tDate2.Ticks; _accruedDays[i] = secondJulianDate > firstJulianDate ? (int)(secondJulianDate - firstJulianDate) : 0; _accrued[i] = DateTime.Compare(tDate2, stepinDate) < 0 ? swapDCC.YearFraction(tDate2, stepinDate) : 0.0; } }
/// <summary> /// A date based description of a CDS accrual period. /// </summary> /// <param name="accStart"> the start date of the period </param> /// <param name="accEnd"> the end date of the period </param> /// <param name="paymentDate"> the payment date for the period </param> /// <param name="accrualDCC"> the day count used for the accrual </param> public CdsCouponDes(DateTime accStart, DateTime accEnd, DateTime paymentDate, Enums.DayCount accrualDCC) { _accStart = accStart; _accEnd = accEnd; _paymentDate = paymentDate; OMLib.Conventions.DayCount.Actual360 accDCC = new OMLib.Conventions.DayCount.Actual360(); _yearFrac = accDCC.YearFraction(accStart, accEnd); }