public virtual void test_resolve() { BusinessDayAdjustment bussAdj = BusinessDayAdjustment.of(FOLLOWING, SAT_SUN); ResolvedCds test = PRODUCT_STD.resolve(REF_DATA); int nDates = 44; LocalDate[] dates = new LocalDate[nDates]; for (int i = 0; i < nDates; ++i) { dates[i] = START_DATE.plusMonths(3 * i); } IList <CreditCouponPaymentPeriod> payments = new List <CreditCouponPaymentPeriod>(nDates - 1); for (int i = 0; i < nDates - 2; ++i) { LocalDate start = i == 0 ? dates[i] : bussAdj.adjust(dates[i], REF_DATA); LocalDate end = bussAdj.adjust(dates[i + 1], REF_DATA); payments.Add(CreditCouponPaymentPeriod.builder().startDate(start).endDate(end).unadjustedStartDate(dates[i]).unadjustedEndDate(dates[i + 1]).effectiveStartDate(start.minusDays(1)).effectiveEndDate(end.minusDays(1)).paymentDate(end).currency(USD).notional(NOTIONAL).fixedRate(COUPON).yearFraction(ACT_360.relativeYearFraction(start, end)).build()); } LocalDate start = bussAdj.adjust(dates[nDates - 2], REF_DATA); LocalDate end = dates[nDates - 1]; payments.Add(CreditCouponPaymentPeriod.builder().startDate(start).endDate(end.plusDays(1)).unadjustedStartDate(dates[nDates - 2]).unadjustedEndDate(end).effectiveStartDate(start.minusDays(1)).effectiveEndDate(end).paymentDate(bussAdj.adjust(end, REF_DATA)).currency(USD).notional(NOTIONAL).fixedRate(COUPON).yearFraction(ACT_360.relativeYearFraction(start, end.plusDays(1))).build()); ResolvedCds expected = ResolvedCds.builder().buySell(BUY).legalEntityId(LEGAL_ENTITY).dayCount(ACT_360).paymentOnDefault(ACCRUED_PREMIUM).paymentPeriods(payments).protectionStart(BEGINNING).protectionEndDate(END_DATE).settlementDateOffset(SETTLE_DAY_ADJ).stepinDateOffset(STEPIN_DAY_ADJ).build(); assertEquals(test, expected); }
//------------------------------------------------------------------------- public virtual void coverage() { CreditCouponPaymentPeriod test1 = CreditCouponPaymentPeriod.builder().currency(USD).notional(NOTIONAL).startDate(START_DATE).endDate(END_DATE).effectiveStartDate(EFF_START_DATE).effectiveEndDate(EFF_END_DATE).paymentDate(END_DATE).fixedRate(COUPON).yearFraction(YEAR_FRACTION).build(); coverImmutableBean(test1); CreditCouponPaymentPeriod test2 = CreditCouponPaymentPeriod.builder().currency(Currency.JPY).notional(5.0e6).startDate(START_DATE.minusDays(7)).endDate(END_DATE.minusDays(7)).effectiveStartDate(EFF_START_DATE.minusDays(7)).effectiveEndDate(EFF_END_DATE.minusDays(7)).paymentDate(END_DATE.minusDays(7)).fixedRate(0.01).yearFraction(0.25).build(); coverBeanEquals(test1, test2); }
public double rpv01(NodalCurve creditCurve, PriceType cleanOrDirty) { double pv = 0.0; for (int i = startPeriodIndex; i < nPayments; i++) { CreditCouponPaymentPeriod coupon = cds.PaymentPeriods.get(i); double yc = offsetAccEnd[i]; double q = Math.Exp(-creditCurve.yValue(yc) * yc); pv += coupon.YearFraction * paymentDF[i] * q; } if (cds.PaymentOnDefault.AccruedInterest) { double accPV = 0.0; for (int i = startPeriodIndex; i < nPayments; i++) { accPV += calculateSinglePeriodAccrualOnDefault(i, creditCurve); } pv += accPV; } pv /= valuationDF; if (cleanOrDirty == PriceType.CLEAN) { pv -= accYearFraction; } return(pv); }
public virtual void test_contains() { CreditCouponPaymentPeriod test = CreditCouponPaymentPeriod.builder().currency(USD).notional(NOTIONAL).startDate(START_DATE).endDate(END_DATE).effectiveStartDate(EFF_START_DATE).effectiveEndDate(EFF_END_DATE).paymentDate(END_DATE).fixedRate(COUPON).yearFraction(YEAR_FRACTION).build(); assertTrue(test.contains(START_DATE)); assertTrue(test.contains(START_DATE.plusMonths(1))); assertFalse(test.contains(END_DATE)); assertFalse(test.contains(START_DATE.minusDays(1))); }
public virtual void test_builder() { CreditCouponPaymentPeriod test = CreditCouponPaymentPeriod.builder().currency(USD).notional(NOTIONAL).startDate(START_DATE).endDate(END_DATE).effectiveStartDate(EFF_START_DATE).effectiveEndDate(EFF_END_DATE).paymentDate(END_DATE).fixedRate(COUPON).yearFraction(YEAR_FRACTION).build(); assertEquals(test.Currency, USD); assertEquals(test.EffectiveStartDate, EFF_START_DATE); assertEquals(test.EffectiveEndDate, EFF_END_DATE); assertEquals(test.StartDate, START_DATE); assertEquals(test.EndDate, END_DATE); assertEquals(test.FixedRate, COUPON); assertEquals(test.Notional, NOTIONAL); assertEquals(test.PaymentDate, END_DATE); assertEquals(test.YearFraction, YEAR_FRACTION); }
/// <summary> /// Calculates the accrued premium per fractional spread for unit notional. /// </summary> /// <param name="stepinDate"> the step-in date </param> /// <returns> the accrued year fraction </returns> public double accruedYearFraction(LocalDate stepinDate) { if (stepinDate.isBefore(AccrualStartDate)) { return(0d); } if (stepinDate.isEqual(AccrualEndDate)) { return(paymentPeriods.get(paymentPeriods.size() - 1).YearFraction); } CreditCouponPaymentPeriod period = findPeriod(stepinDate).orElseThrow(() => new System.ArgumentException("Date outside range")); return(dayCount.relativeYearFraction(period.StartDate, stepinDate)); }
static ResolvedCdsIndexTest() { int nDates = 44; LocalDate[] dates = new LocalDate[nDates]; for (int i = 0; i < nDates; ++i) { dates[i] = START_DATE.plusMonths(3 * i); } for (int i = 0; i < nDates - 2; ++i) { LocalDate start = i == 0 ? dates[i] : BUSS_ADJ.adjust(dates[i], REF_DATA); LocalDate end = BUSS_ADJ.adjust(dates[i + 1], REF_DATA); PAYMENTS.Add(CreditCouponPaymentPeriod.builder().startDate(start).endDate(end).effectiveStartDate(start.minusDays(1)).effectiveEndDate(end.minusDays(1)).paymentDate(end).currency(USD).notional(NOTIONAL).fixedRate(COUPON).yearFraction(ACT_360.relativeYearFraction(start, end)).build()); } LocalDate start = BUSS_ADJ.adjust(dates[nDates - 2], REF_DATA); LocalDate end = dates[nDates - 1]; PAYMENTS.Add(CreditCouponPaymentPeriod.builder().startDate(start).endDate(end.plusDays(1)).effectiveStartDate(start.minusDays(1)).effectiveEndDate(end).paymentDate(BUSS_ADJ.adjust(end, REF_DATA)).currency(USD).notional(NOTIONAL).fixedRate(COUPON).yearFraction(ACT_360.relativeYearFraction(start, end.plusDays(1))).build()); }
public virtual void test_serialization() { CreditCouponPaymentPeriod test = CreditCouponPaymentPeriod.builder().currency(USD).notional(NOTIONAL).startDate(START_DATE).endDate(END_DATE).effectiveStartDate(EFF_START_DATE).effectiveEndDate(EFF_END_DATE).paymentDate(END_DATE).fixedRate(COUPON).yearFraction(YEAR_FRACTION).build(); assertSerialization(test); }
public Pricer(FastCreditCurveCalibrator outerInstance, ResolvedCds nodeCds, CreditDiscountFactors yieldCurve, DoubleArray creditCurveKnots, double fractionalSpread, double pointsUpfront, double lgd, LocalDate stepinDate, LocalDate effectiveStartDate, LocalDate settlementDate, double accruedYearFraction) { this.outerInstance = outerInstance; accYearFraction = accruedYearFraction; cds = nodeCds; fracSpread = fractionalSpread; puf = pointsUpfront; productEffectiveStart = yieldCurve.relativeYearFraction(effectiveStartDate); double protectionEnd = yieldCurve.relativeYearFraction(cds.ProtectionEndDate); // protection leg proLegIntPoints = DoublesScheduleGenerator.getIntegrationsPoints(productEffectiveStart, protectionEnd, yieldCurve.ParameterKeys, creditCurveKnots).toArray(); nProPoints = proLegIntPoints.Length; valuationDF = yieldCurve.discountFactor(settlementDate); lgdDF = lgd / valuationDF; proYieldCurveRT = new double[nProPoints]; proDF = new double[nProPoints]; for (int i = 0; i < nProPoints; i++) { proYieldCurveRT[i] = yieldCurve.zeroRate(proLegIntPoints[i]) * proLegIntPoints[i]; proDF[i] = Math.Exp(-proYieldCurveRT[i]); } // premium leg nPayments = cds.PaymentPeriods.size(); paymentDF = new double[nPayments]; int indexTmp = -1; for (int i = 0; i < nPayments; i++) { if (stepinDate.isBefore(cds.PaymentPeriods.get(i).EndDate)) { paymentDF[i] = yieldCurve.discountFactor(cds.PaymentPeriods.get(i).PaymentDate); } else { indexTmp = i; } } startPeriodIndex = indexTmp + 1; // accrual on default if (cds.PaymentOnDefault.AccruedInterest) { LocalDate tmp = nPayments == 1 ? effectiveStartDate : cds.AccrualStartDate; DoubleArray integrationSchedule = DoublesScheduleGenerator.getIntegrationsPoints(yieldCurve.relativeYearFraction(tmp), protectionEnd, yieldCurve.ParameterKeys, creditCurveKnots); accRate = new double[nPayments]; offsetAccStart = new double[nPayments]; offsetAccEnd = new double[nPayments]; premLegIntPoints = new double[nPayments][]; premDF = new double[nPayments][]; rt = new double[nPayments][]; premDt = new double[nPayments][]; for (int i = startPeriodIndex; i < nPayments; i++) { CreditCouponPaymentPeriod coupon = cds.PaymentPeriods.get(i); offsetAccStart[i] = yieldCurve.relativeYearFraction(coupon.EffectiveStartDate); offsetAccEnd[i] = yieldCurve.relativeYearFraction(coupon.EffectiveEndDate); accRate[i] = coupon.YearFraction / yieldCurve.DayCount.relativeYearFraction(coupon.StartDate, coupon.EndDate); double start = Math.Max(productEffectiveStart, offsetAccStart[i]); if (start >= offsetAccEnd[i]) { continue; } premLegIntPoints[i] = DoublesScheduleGenerator.truncateSetInclusive(start, offsetAccEnd[i], integrationSchedule).toArray(); int n = premLegIntPoints[i].Length; rt[i] = new double[n]; premDF[i] = new double[n]; for (int k = 0; k < n; k++) { rt[i][k] = yieldCurve.zeroRate(premLegIntPoints[i][k]) * premLegIntPoints[i][k]; premDF[i][k] = Math.Exp(-rt[i][k]); } premDt[i] = new double[n - 1]; for (int k = 1; k < n; k++) { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double dt = premLegIntPoints[i][k] - premLegIntPoints[i][k - 1]; double dt = premLegIntPoints[i][k] - premLegIntPoints[i][k - 1]; premDt[i][k - 1] = dt; } } } else { accRate = null; offsetAccStart = null; offsetAccEnd = null; premDF = null; premDt = null; rt = null; premLegIntPoints = null; } }
private Pair <double, PointSensitivityBuilder> singlePeriodAccrualOnDefaultSensitivity(CreditCouponPaymentPeriod coupon, LocalDate effectiveStartDate, DoubleArray integrationSchedule, CreditDiscountFactors discountFactors, LegalEntitySurvivalProbabilities survivalProbabilities) { LocalDate start = coupon.EffectiveStartDate.isBefore(effectiveStartDate) ? effectiveStartDate : coupon.EffectiveStartDate; if (!start.isBefore(coupon.EffectiveEndDate)) { return(Pair.of(0d, PointSensitivityBuilder.none())); //this coupon has already expired } DoubleArray knots = DoublesScheduleGenerator.truncateSetInclusive(discountFactors.relativeYearFraction(start), discountFactors.relativeYearFraction(coupon.EffectiveEndDate), integrationSchedule); // pv double pv = 0d; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final int nItems = knots.size(); int nItems = knots.size(); double[] dhrtBar = new double[nItems - 1]; double[] dhtBar = new double[nItems - 1]; double[] bBar = new double[nItems]; double[] p = new double[nItems]; double[] q = new double[nItems]; double t = knots.get(0); double ht0 = survivalProbabilities.zeroRate(t) * t; double rt0 = discountFactors.zeroRate(t) * t; q[0] = Math.Exp(-ht0); p[0] = Math.Exp(-rt0); double b0 = q[0] * p[0]; double effStart = discountFactors.relativeYearFraction(coupon.EffectiveStartDate); double t0 = t - effStart + omega; for (int i = 1; i < nItems; ++i) { t = knots.get(i); double ht1 = survivalProbabilities.zeroRate(t) * t; double rt1 = discountFactors.zeroRate(t) * t; q[i] = Math.Exp(-ht1); p[i] = Math.Exp(-rt1); double b1 = q[i] * p[i]; double dt = knots.get(i) - knots.get(i - 1); double dht = ht1 - ht0; double drt = rt1 - rt0; double dhrt = dht + drt; double tPv; if (formula == AccrualOnDefaultFormula.MARKIT_FIX) { if (Math.Abs(dhrt) < SMALL) { double eps = epsilonP(-dhrt); tPv = dht * dt * b0 * eps; dhtBar[i - 1] = dt * b0 * eps; dhrtBar[i - 1] = -dht *dt *b0 *epsilonPP(-dhrt); bBar[i - 1] += dht * eps; } else { tPv = dht * dt / dhrt * ((b0 - b1) / dhrt - b1); dhtBar[i - 1] = dt / dhrt * ((b0 - b1) / dhrt - b1); dhrtBar[i - 1] = dht * dt / (dhrt * dhrt) * (b1 - 2d * (b0 - b1) / dhrt); bBar[i - 1] += dht * dt / (dhrt * dhrt); bBar[i] += -dht * dt / dhrt * (1d + 1d / dhrt); } } else { double t1 = t - effStart + omega; if (Math.Abs(dhrt) < SMALL) { double eps = epsilon(-dhrt); double epsp = epsilonP(-dhrt); tPv = dht * b0 * (t0 * eps + dt * epsp); dhtBar[i - 1] = b0 * (t0 * eps + dt * epsp); dhrtBar[i - 1] = -dht * b0 * (t0 * epsp + dt * epsilonPP(-dhrt)); bBar[i - 1] += dht * (t0 * eps + dt * epsp); } else { tPv = dht / dhrt * (t0 * b0 - t1 * b1 + dt / dhrt * (b0 - b1)); dhtBar[i - 1] = (t0 * b0 - t1 * b1 + dt / dhrt * (b0 - b1)) / dhrt; dhrtBar[i - 1] = dht / (dhrt * dhrt) * (-2d * dt / dhrt * (b0 - b1) - t0 * b0 + t1 * b1); bBar[i - 1] += dht / dhrt * (t0 + dt / dhrt); bBar[i] += dht / dhrt * (-t1 - dt / dhrt); } t0 = t1; } pv += tPv; ht0 = ht1; rt0 = rt1; b0 = b1; } double yfRatio = coupon.YearFraction / discountFactors.DayCount.relativeYearFraction(coupon.StartDate, coupon.EndDate); // pv sensitivity PointSensitivityBuilder qSensiFirst = survivalProbabilities.zeroRatePointSensitivity(knots.get(0)).multipliedBy(yfRatio * ((dhrtBar[0] + dhtBar[0]) / q[0] + bBar[0] * p[0])); PointSensitivityBuilder pSensiFirst = discountFactors.zeroRatePointSensitivity(knots.get(0)).multipliedBy(yfRatio * (dhrtBar[0] / p[0] + bBar[0] * q[0])); PointSensitivityBuilder pvSensi = pSensiFirst.combinedWith(qSensiFirst); for (int i = 1; i < nItems - 1; ++i) { PointSensitivityBuilder qSensi = survivalProbabilities.zeroRatePointSensitivity(knots.get(i)).multipliedBy(yfRatio * (-(dhrtBar[i - 1] + dhtBar[i - 1]) / q[i] + (dhrtBar[i] + dhtBar[i]) / q[i] + bBar[i] * p[i])); PointSensitivityBuilder pSensi = discountFactors.zeroRatePointSensitivity(knots.get(i)).multipliedBy(yfRatio * (-dhrtBar[i - 1] / p[i] + dhrtBar[i] / p[i] + bBar[i] * q[i])); pvSensi = pvSensi.combinedWith(pSensi).combinedWith(qSensi); } if (nItems > 1) { PointSensitivityBuilder qSensiLast = survivalProbabilities.zeroRatePointSensitivity(knots.get(nItems - 1)).multipliedBy(yfRatio * (-(dhrtBar[nItems - 2] + dhtBar[nItems - 2]) / q[nItems - 1] + bBar[nItems - 1] * p[nItems - 1])); PointSensitivityBuilder pSensiLast = discountFactors.zeroRatePointSensitivity(knots.get(nItems - 1)).multipliedBy(yfRatio * (-dhrtBar[nItems - 2] / p[nItems - 1] + bBar[nItems - 1] * q[nItems - 1])); pvSensi = pvSensi.combinedWith(pSensiLast).combinedWith(qSensiLast); } return(Pair.of(yfRatio * pv, pvSensi)); }
// computes accrual-on-default pv per unit notional for a single payment period private double singlePeriodAccrualOnDefault(CreditCouponPaymentPeriod coupon, LocalDate effectiveStartDate, DoubleArray integrationSchedule, CreditDiscountFactors discountFactors, LegalEntitySurvivalProbabilities survivalProbabilities) { LocalDate start = coupon.EffectiveStartDate.isBefore(effectiveStartDate) ? effectiveStartDate : coupon.EffectiveStartDate; if (!start.isBefore(coupon.EffectiveEndDate)) { return(0d); // this coupon has already expired } DoubleArray knots = DoublesScheduleGenerator.truncateSetInclusive(discountFactors.relativeYearFraction(start), discountFactors.relativeYearFraction(coupon.EffectiveEndDate), integrationSchedule); double t0Knot = knots.get(0); double ht0 = survivalProbabilities.zeroRate(t0Knot) * t0Knot; double rt0 = discountFactors.zeroRate(t0Knot) * t0Knot; double b0 = Math.Exp(-rt0 - ht0); double effStart = discountFactors.relativeYearFraction(coupon.EffectiveStartDate); double t0 = t0Knot - effStart + omega; double pv = 0d; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final int nItems = knots.size(); int nItems = knots.size(); for (int j = 1; j < nItems; ++j) { double t = knots.get(j); double ht1 = survivalProbabilities.zeroRate(t) * t; double rt1 = discountFactors.zeroRate(t) * t; double b1 = Math.Exp(-rt1 - ht1); double dt = knots.get(j) - knots.get(j - 1); double dht = ht1 - ht0; double drt = rt1 - rt0; double dhrt = dht + drt; double tPV; if (formula == AccrualOnDefaultFormula.MARKIT_FIX) { if (Math.Abs(dhrt) < SMALL) { tPV = dht * dt * b0 * Epsilon.epsilonP(-dhrt); } else { tPV = dht * dt / dhrt * ((b0 - b1) / dhrt - b1); } } else { double t1 = t - effStart + omega; if (Math.Abs(dhrt) < SMALL) { tPV = dht * b0 * (t0 * epsilon(-dhrt) + dt * Epsilon.epsilonP(-dhrt)); } else { tPV = dht / dhrt * (t0 * b0 - t1 * b1 + dt / dhrt * (b0 - b1)); } t0 = t1; } pv += tPV; ht0 = ht1; rt0 = rt1; b0 = b1; } double yearFractionCurve = discountFactors.DayCount.relativeYearFraction(coupon.StartDate, coupon.EndDate); return(coupon.YearFraction * pv / yearFractionCurve); }