public virtual void getIntegrationsPointsTest()
        {
            double start = 0.1;
            double end   = 2.0;

            DoubleArray setA0 = DoubleArray.of(0.5, 0.9, 1.4);
            DoubleArray setB0 = DoubleArray.of(0.3, 0.4, 1.5, 1.6);
            DoubleArray exp0  = DoubleArray.of(0.1, 0.3, 0.4, 0.5, 0.9, 1.4, 1.5, 1.6, 2.0);
            DoubleArray res0  = DoublesScheduleGenerator.getIntegrationsPoints(start, end, setA0, setB0);

            assertTrue(DoubleArrayMath.fuzzyEquals(exp0.toArray(), res0.toArray(), 0d));

            DoubleArray setA1 = DoubleArray.of(0.5, 0.9, 1.4);
            DoubleArray setB1 = DoubleArray.of(0.3, 0.4, 0.5, 1.5, 1.6);
            DoubleArray exp1  = DoubleArray.of(0.1, 0.3, 0.4, 0.5, 0.9, 1.4, 1.5, 1.6, 2.0);
            DoubleArray res1  = DoublesScheduleGenerator.getIntegrationsPoints(start, end, setA1, setB1);

            assertTrue(DoubleArrayMath.fuzzyEquals(exp1.toArray(), res1.toArray(), 0d));

            /*
             * different(temp[pos], end) == false
             */
            DoubleArray setA2 = DoubleArray.of(0.2, 0.9, 1.4);
            DoubleArray setB2 = DoubleArray.of(0.3, 0.4, 0.5, 1.5, 2.0 - 1.e-3);
            DoubleArray exp2  = DoubleArray.of(0.1, 0.2, 0.3, 0.4, 0.5, 0.9, 1.4, 1.5, 2.0);
            DoubleArray res2  = DoublesScheduleGenerator.getIntegrationsPoints(start, end, setA2, setB2);

            assertTrue(DoubleArrayMath.fuzzyEquals(exp2.toArray(), res2.toArray(), 0d));

            DoubleArray setA3 = DoubleArray.of(0.05, 0.07);
            DoubleArray setB3 = DoubleArray.of(0.03, 0.04);
            DoubleArray exp3  = DoubleArray.of(0.1, 2.0);
            DoubleArray res3  = DoublesScheduleGenerator.getIntegrationsPoints(start, end, setA3, setB3);

            assertTrue(DoubleArrayMath.fuzzyEquals(exp3.toArray(), res3.toArray(), 0d));

            DoubleArray setA4 = DoubleArray.of(2.2, 2.7);
            DoubleArray setB4 = DoubleArray.of(2.3, 2.4);
            DoubleArray exp4  = DoubleArray.of(0.1, 2.0);
            DoubleArray res4  = DoublesScheduleGenerator.getIntegrationsPoints(start, end, setA4, setB4);

            assertTrue(DoubleArrayMath.fuzzyEquals(exp4.toArray(), res4.toArray(), 0d));

            DoubleArray setA5 = DoubleArray.of(-0.5, 0.0, 1.2);
            DoubleArray setB5 = DoubleArray.of(-0.2, -0.0, 1.2);
            DoubleArray exp5  = DoubleArray.of(-0.3, -0.2, 0.0, 1.2, 2.0);
            DoubleArray res5  = DoublesScheduleGenerator.getIntegrationsPoints(-0.3, end, setA5, setB5);

            assertTrue(DoubleArrayMath.fuzzyEquals(exp5.toArray(), res5.toArray(), 0d));
        }
Example #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);
        }
Example #3
0
        internal virtual PointSensitivityBuilder riskyAnnuitySensitivity(ResolvedCds cds, CreditDiscountFactors discountFactors, LegalEntitySurvivalProbabilities survivalProbabilities, LocalDate referenceDate, LocalDate stepinDate, LocalDate effectiveStartDate)
        {
            double pv = 0d;
            PointSensitivityBuilder pvSensi = PointSensitivityBuilder.none();

            foreach (CreditCouponPaymentPeriod coupon in cds.PaymentPeriods)
            {
                if (stepinDate.isBefore(coupon.EndDate))
                {
                    double q = survivalProbabilities.survivalProbability(coupon.EffectiveEndDate);
                    PointSensitivityBuilder qSensi = survivalProbabilities.zeroRatePointSensitivity(coupon.EffectiveEndDate);
                    double p = discountFactors.discountFactor(coupon.PaymentDate);
                    PointSensitivityBuilder pSensi = discountFactors.zeroRatePointSensitivity(coupon.PaymentDate);
                    pv     += coupon.YearFraction * p * q;
                    pvSensi = pvSensi.combinedWith(pSensi.multipliedBy(coupon.YearFraction * q).combinedWith(qSensi.multipliedBy(coupon.YearFraction * p)));
                }
            }

            if (cds.PaymentOnDefault.AccruedInterest)
            {
                // This is needed so that the code is consistent with ISDA C when the Markit `fix' is used.
                LocalDate   start = cds.PaymentPeriods.size() == 1 ? effectiveStartDate : cds.AccrualStartDate;
                DoubleArray integrationSchedule = DoublesScheduleGenerator.getIntegrationsPoints(discountFactors.relativeYearFraction(start), discountFactors.relativeYearFraction(cds.ProtectionEndDate), discountFactors.ParameterKeys, survivalProbabilities.ParameterKeys);
                foreach (CreditCouponPaymentPeriod coupon in cds.PaymentPeriods)
                {
                    Pair <double, PointSensitivityBuilder> pvAndSensi = singlePeriodAccrualOnDefaultSensitivity(coupon, effectiveStartDate, integrationSchedule, discountFactors, survivalProbabilities);
                    pv     += pvAndSensi.First;
                    pvSensi = pvSensi.combinedWith(pvAndSensi.Second);
                }
            }

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

            pvSensi = pvSensi.multipliedBy(1d / df);

            return(dfSensi.combinedWith(pvSensi));
        }
Example #4
0
        // computes risky annuity
        internal virtual double riskyAnnuity(ResolvedCds cds, CreditDiscountFactors discountFactors, LegalEntitySurvivalProbabilities survivalProbabilities, LocalDate referenceDate, LocalDate stepinDate, LocalDate effectiveStartDate, PriceType priceType)
        {
            double pv = 0d;

            foreach (CreditCouponPaymentPeriod coupon in cds.PaymentPeriods)
            {
                if (stepinDate.isBefore(coupon.EndDate))
                {
                    double q = survivalProbabilities.survivalProbability(coupon.EffectiveEndDate);
                    double p = discountFactors.discountFactor(coupon.PaymentDate);
                    pv += coupon.YearFraction * p * q;
                }
            }

            if (cds.PaymentOnDefault.AccruedInterest)
            {
                // This is needed so that the code is consistent with ISDA C when the Markit `fix' is used.
                LocalDate   start = cds.PaymentPeriods.size() == 1 ? effectiveStartDate : cds.AccrualStartDate;
                DoubleArray integrationSchedule = DoublesScheduleGenerator.getIntegrationsPoints(discountFactors.relativeYearFraction(start), discountFactors.relativeYearFraction(cds.ProtectionEndDate), discountFactors.ParameterKeys, survivalProbabilities.ParameterKeys);
                foreach (CreditCouponPaymentPeriod coupon in cds.PaymentPeriods)
                {
                    pv += singlePeriodAccrualOnDefault(coupon, effectiveStartDate, integrationSchedule, discountFactors, survivalProbabilities);
                }
            }
            // roll to the cash settle date
            double df = discountFactors.discountFactor(referenceDate);

            pv /= df;

            if (priceType.CleanPrice)
            {
                pv -= cds.accruedYearFraction(stepinDate);
            }

            return(pv);
        }
Example #5
0
            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;
                }
            }
Example #6
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));
        }