public double protectionLeg(IsdaCompliantCreditCurve creditCurve) { double ht0 = creditCurve.getRT(_proLegIntPoints[0]); double rt0 = _proYieldCurveRT[0]; double b0 = _proDF[0] * Math.exp(-ht0); double pv = 0.0; for (int i = 1; i < _nProPoints; ++i) { double ht1 = creditCurve.getRT(_proLegIntPoints[i]); double rt1 = _proYieldCurveRT[i]; double b1 = _proDF[i] * Math.exp(-ht1); double dht = ht1 - ht0; double drt = rt1 - rt0; double dhrt = dht + drt; // this is equivalent to the ISDA code without explicitly calculating the time step - it // also handles the limit double dPV; if (Math.abs(dhrt) < 1e-5) { dPV = dht * b0 * epsilon(-dhrt); } else { dPV = (b0 - b1) * dht / dhrt; } pv += dPV; ht0 = ht1; rt0 = rt1; b0 = b1; } pv *= _lgdDF; // multiply by LGD and adjust to valuation date return pv; }
private double calculateSinglePeriodAccrualOnDefault( int paymentIndex, IsdaCompliantCreditCurve 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 (getAccOnDefaultFormula() == AccrualOnDefaultFormulae.MARKIT_FIX) { if (Math.abs(dhrt) < 1e-5) { tPV = dht * dt * b0 * epsilonP(-dhrt); } else { tPV = dht * dt / dhrt * ((b0 - b1) / dhrt - b1); } } else { double t1 = t - accStart + _omega; if (Math.abs(dhrt) < 1e-5) { tPV = dht * b0 * (t0 * epsilon(-dhrt) + dt * epsilonP(-dhrt)); } else { tPV = dht / dhrt * (t0 * b0 - t1 * b1 + dt / dhrt * (b0 - b1)); } t0 = t1; } pv += tPV; ht0 = ht1; rt0 = rt1; b0 = b1; } return accRate * pv; }