示例#1
0
        public virtual void test_zeroRate()
        {
            LegalEntitySurvivalProbabilities test = LegalEntitySurvivalProbabilities.of(LEGAL_ENTITY, DFS);
            double relativeYearFraction           = ACT_365F.relativeYearFraction(VALUATION, DATE_AFTER);
            double discountFactor = test.survivalProbability(DATE_AFTER);
            double zeroRate       = test.zeroRate(relativeYearFraction);

            assertEquals(Math.Exp(-zeroRate * relativeYearFraction), discountFactor);
        }
示例#2
0
        // computes protection leg pv per unit notional, without loss-given-default rate multiplied
        internal virtual double protectionFull(ResolvedCds cds, CreditDiscountFactors discountFactors, LegalEntitySurvivalProbabilities survivalProbabilities, LocalDate referenceDate, LocalDate effectiveStartDate)
        {
            DoubleArray integrationSchedule = DoublesScheduleGenerator.getIntegrationsPoints(discountFactors.relativeYearFraction(effectiveStartDate), discountFactors.relativeYearFraction(cds.ProtectionEndDate), discountFactors.ParameterKeys, survivalProbabilities.ParameterKeys);

            double pv  = 0d;
            double ht0 = survivalProbabilities.zeroRate(integrationSchedule.get(0)) * integrationSchedule.get(0);
            double rt0 = discountFactors.zeroRate(integrationSchedule.get(0)) * integrationSchedule.get(0);
            double b0  = Math.Exp(-ht0 - rt0);
            int    n   = integrationSchedule.size();

            for (int i = 1; i < n; ++i)
            {
                double ht1  = survivalProbabilities.zeroRate(integrationSchedule.get(i)) * integrationSchedule.get(i);
                double rt1  = discountFactors.zeroRate(integrationSchedule.get(i)) * integrationSchedule.get(i);
                double b1   = Math.Exp(-ht1 - rt1);
                double dht  = ht1 - ht0;
                double drt  = rt1 - rt0;
                double dhrt = dht + drt;
                // The formula has been modified from ISDA (but is equivalent) to avoid log(exp(x)) and explicitly
                // calculating the time step - it also handles the limit
                double dPV = 0d;
                if (Math.Abs(dhrt) < SMALL)
                {
                    dPV = dht * b0 * epsilon(-dhrt);
                }
                else
                {
                    dPV = (b0 - b1) * dht / dhrt;
                }
                pv += dPV;
                ht0 = ht1;
                rt0 = rt1;
                b0  = b1;
            }
            // roll to the cash settle date
            double df = discountFactors.discountFactor(referenceDate);

            return(pv / df);
        }
示例#3
0
        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));
        }
示例#4
0
        //-------------------------------------------------------------------------
        internal virtual PointSensitivityBuilder protectionLegSensitivity(ResolvedCds cds, CreditDiscountFactors discountFactors, LegalEntitySurvivalProbabilities survivalProbabilities, LocalDate referenceDate, LocalDate effectiveStartDate, double recoveryRate)
        {
            DoubleArray integrationSchedule = DoublesScheduleGenerator.getIntegrationsPoints(discountFactors.relativeYearFraction(effectiveStartDate), discountFactors.relativeYearFraction(cds.ProtectionEndDate), discountFactors.ParameterKeys, survivalProbabilities.ParameterKeys);
            int         n = integrationSchedule.size();

            double[] dht  = new double[n - 1];
            double[] drt  = new double[n - 1];
            double[] dhrt = new double[n - 1];
            double[] p    = new double[n];
            double[] q    = new double[n];
            // pv
            double pv  = 0d;
            double ht0 = survivalProbabilities.zeroRate(integrationSchedule.get(0)) * integrationSchedule.get(0);
            double rt0 = discountFactors.zeroRate(integrationSchedule.get(0)) * integrationSchedule.get(0);

            p[0] = Math.Exp(-rt0);
            q[0] = Math.Exp(-ht0);
            double b0 = p[0] * q[0];

            for (int i = 1; i < n; ++i)
            {
                double ht1 = survivalProbabilities.zeroRate(integrationSchedule.get(i)) * integrationSchedule.get(i);
                double rt1 = discountFactors.zeroRate(integrationSchedule.get(i)) * integrationSchedule.get(i);
                p[i] = Math.Exp(-rt1);
                q[i] = Math.Exp(-ht1);
                double b1 = p[i] * q[i];
                dht[i - 1]  = ht1 - ht0;
                drt[i - 1]  = rt1 - rt0;
                dhrt[i - 1] = dht[i - 1] + drt[i - 1];
                double dPv = 0d;
                if (Math.Abs(dhrt[i - 1]) < SMALL)
                {
                    double eps = epsilon(-dhrt[i - 1]);
                    dPv = dht[i - 1] * b0 * eps;
                }
                else
                {
                    dPv = (b0 - b1) * dht[i - 1] / dhrt[i - 1];
                }
                pv += dPv;
                ht0 = ht1;
                rt0 = rt1;
                b0  = b1;
            }
            double df = discountFactors.discountFactor(referenceDate);
            // pv sensitivity
            double factor = (1d - recoveryRate) / df;
            double eps0   = computeExtendedEpsilon(-dhrt[0], p[1], q[1], p[0], q[0]);
            PointSensitivityBuilder pvSensi = discountFactors.zeroRatePointSensitivity(integrationSchedule.get(0)).multipliedBy(-dht[0] * q[0] * eps0 * factor);

            pvSensi = pvSensi.combinedWith(survivalProbabilities.zeroRatePointSensitivity(integrationSchedule.get(0)).multipliedBy(factor * (drt[0] * p[0] * eps0 + p[0])));
            for (int i = 1; i < n - 1; ++i)
            {
                double epsp = computeExtendedEpsilon(-dhrt[i], p[i + 1], q[i + 1], p[i], q[i]);
                double epsm = computeExtendedEpsilon(dhrt[i - 1], p[i - 1], q[i - 1], p[i], q[i]);
                PointSensitivityBuilder pSensi = discountFactors.zeroRatePointSensitivity(integrationSchedule.get(i)).multipliedBy(factor * (-dht[i] * q[i] * epsp - dht[i - 1] * q[i] * epsm));
                PointSensitivityBuilder qSensi = survivalProbabilities.zeroRatePointSensitivity(integrationSchedule.get(i)).multipliedBy(factor * (drt[i - 1] * p[i] * epsm + drt[i] * p[i] * epsp));
                pvSensi = pvSensi.combinedWith(pSensi).combinedWith(qSensi);
            }
            if (n > 1)
            {
                double epsLast = computeExtendedEpsilon(dhrt[n - 2], p[n - 2], q[n - 2], p[n - 1], q[n - 1]);
                pvSensi = pvSensi.combinedWith(discountFactors.zeroRatePointSensitivity(integrationSchedule.get(n - 1)).multipliedBy(-dht[n - 2] * q[n - 1] * epsLast * factor));
                pvSensi = pvSensi.combinedWith(survivalProbabilities.zeroRatePointSensitivity(integrationSchedule.get(n - 1)).multipliedBy(factor * (drt[n - 2] * p[n - 1] * epsLast - p[n - 1])));
            }

            PointSensitivityBuilder dfSensi = discountFactors.zeroRatePointSensitivity(referenceDate).multipliedBy(-pv * factor / df);

            return(dfSensi.combinedWith(pvSensi));
        }
示例#5
0
        // 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);
        }