private double calculateSinglePeriodAccrualOnDefault(int paymentIndex, PiecewiseconstantHazardRate creditCurve) { double[] knots = _premLegIntPoints[paymentIndex]; if (knots == null) { return(0.0); } double[] df = _premDF[paymentIndex]; double[] deltaT = _premDt[paymentIndex]; double[] rt = _rt[paymentIndex]; double accRate = _accRate[paymentIndex]; double accStart = _offsetAccStart[paymentIndex]; double t = knots[0]; double ht0 = creditCurve.getRT_(t); double rt0 = rt[0]; double b0 = df[0] * Math.Exp(-ht0); double t0 = t - accStart + _omega; double pv = 0.0; int nItems = knots.Length; for (int j = 1; j < nItems; ++j) { t = knots[j]; double ht1 = creditCurve.getRT_(t); double rt1 = rt[j]; double b1 = df[j] * Math.Exp(-ht1); double dt = deltaT[j - 1]; double dht = ht1 - ht0; double drt = rt1 - rt0; double dhrt = dht + drt + 1e-50; // to keep consistent with ISDA c code double tPV; if (Math.Abs(dhrt) < 1e-5) { tPV = dht * dt * b0 * Epsilon.epsilonP(-dhrt); } else { tPV = dht * dt / dhrt * ((b0 - b1) / dhrt - b1); } } return(accRate * pv); }
// 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); }