Пример #1
0
        //-------------------------------------------------------------------------
        public override NodalCurve calibrate(IList <ResolvedCdsTrade> calibrationCDSs, DoubleArray premiums, DoubleArray pointsUpfront, CurveName name, LocalDate valuationDate, CreditDiscountFactors discountFactors, RecoveryRates recoveryRates, ReferenceData refData)
        {
            int n = calibrationCDSs.Count;

            double[] guess = new double[n];
            double[] t     = new double[n];
            double[] lgd   = new double[n];
            for (int i = 0; i < n; i++)
            {
                LocalDate endDate = calibrationCDSs[i].Product.ProtectionEndDate;
                t[i]     = discountFactors.relativeYearFraction(endDate);
                lgd[i]   = 1d - recoveryRates.recoveryRate(endDate);
                guess[i] = (premiums.get(i) + pointsUpfront.get(i) / t[i]) / lgd[i];
            }
            DoubleArray   times        = DoubleArray.ofUnsafe(t);
            CurveMetadata baseMetadata = DefaultCurveMetadata.builder().xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.ZERO_RATE).curveName(name).dayCount(discountFactors.DayCount).build();
            NodalCurve    creditCurve  = n == 1 ? ConstantNodalCurve.of(baseMetadata, t[0], guess[0]) : InterpolatedNodalCurve.of(baseMetadata, times, DoubleArray.ofUnsafe(guess), CurveInterpolators.PRODUCT_LINEAR, CurveExtrapolators.FLAT, CurveExtrapolators.PRODUCT_LINEAR);

            for (int i = 0; i < n; i++)
            {
                System.Func <double, double> func = getPriceFunction(i, calibrationCDSs[i], premiums.get(i), pointsUpfront.get(i), valuationDate, creditCurve, discountFactors, recoveryRates, refData);
                double[] bracket  = BRACKER.getBracketedPoints(func, 0.8 * guess[i], 1.25 * guess[i], 0.0, double.PositiveInfinity);
                double   zeroRate = bracket[0] > bracket[1] ? ROOTFINDER.getRoot(func, bracket[1], bracket[0]) : ROOTFINDER.getRoot(func, bracket[0], bracket[1]); //Negative guess handled
                creditCurve = creditCurve.withParameter(i, zeroRate);
            }

            return(creditCurve);
        }
Пример #2
0
        public virtual void test_bondDiscountingProvider()
        {
            LocalDate valDate = LocalDate.of(2015, 6, 30);
            Curve     ccAUsd  = ConstantNodalCurve.of(Curves.zeroRates(CC_A_USD.CurveName, ACT_365F), 0.5d, 1.5d);
            Curve     ccBGbp  = ConstantNodalCurve.of(Curves.zeroRates(CC_B_GBP.CurveName, ACT_365F), 0.5d, 2d);
            Curve     ccAGbp  = ConstantNodalCurve.of(Curves.zeroRates(CC_A_GBP.CurveName, ACT_365F), 0.5d, 3d);
            Curve     dcGbp   = ConstantNodalCurve.of(Curves.zeroRates(DC_GBP.CurveName, ACT_365F), 0.5d, 0.1d);
            Curve     dcUsd   = ConstantNodalCurve.of(Curves.zeroRates(DC_USD.CurveName, ACT_365F), 0.5d, 0.05d);
            Curve     rcA     = ConstantCurve.of(Curves.recoveryRates(RC_A.CurveName, ACT_365F), 0.5d);
            Curve     rcB     = ConstantCurve.of(Curves.recoveryRates(RC_B.CurveName, ACT_365F), 0.4234d);
            IDictionary <CurveId, Curve> curveMap = new Dictionary <CurveId, Curve>();

            curveMap[CC_A_USD] = ccAUsd;
            curveMap[CC_B_GBP] = ccBGbp;
            curveMap[CC_A_GBP] = ccAGbp;
            curveMap[DC_USD]   = dcUsd;
            curveMap[DC_GBP]   = dcGbp;
            curveMap[RC_A]     = rcA;
            curveMap[RC_B]     = rcB;
            MarketData          md       = ImmutableMarketData.of(valDate, ImmutableMap.copyOf(curveMap));
            CreditRatesProvider provider = LOOKUP_WITH_SOURCE.creditRatesProvider(md);

            assertEquals(provider.ValuationDate, valDate);
            assertEquals(provider.findData(CC_A_USD.CurveName), ccAUsd);
            assertEquals(provider.findData(DC_USD.CurveName), dcUsd);
            assertEquals(provider.findData(RC_B.CurveName), rcB);
            assertEquals(provider.findData(CurveName.of("Rubbish")), null);
            // check credit curve
            LegalEntitySurvivalProbabilities cc      = provider.survivalProbabilities(ISSUER_A, GBP);
            IsdaCreditDiscountFactors        ccUnder = (IsdaCreditDiscountFactors)cc.SurvivalProbabilities;

            assertEquals(ccUnder.Curve.Name, ccAGbp.Name);
            assertThrowsRuntime(() => provider.survivalProbabilities(ISSUER_B, USD));
            assertThrowsRuntime(() => provider.survivalProbabilities(ISSUER_C, USD));
            // check discount curve
            IsdaCreditDiscountFactors dc = (IsdaCreditDiscountFactors)provider.discountFactors(USD);

            assertEquals(dc.Curve.Name, dcUsd.Name);
            assertThrowsRuntime(() => provider.discountFactors(EUR));
            // check recovery rate curve
            ConstantRecoveryRates rc = (ConstantRecoveryRates)provider.recoveryRates(ISSUER_B);

            assertEquals(rc.RecoveryRate, rcB.getParameter(0));
            assertThrowsRuntime(() => provider.recoveryRates(ISSUER_C));
        }
        public virtual void test_createSabrParameterCurve()
        {
            DoubleArray nuKnots = DoubleArray.of(5.0);
            SabrIborCapletFloorletVolatilityCalibrationDefinition fixedBeta = SabrIborCapletFloorletVolatilityCalibrationDefinition.ofFixedBeta(NAME, USD_LIBOR_3M, ACT_365F, BETA_RHO, ALPHA_KNOTS, BETA_RHO_KNOTS, nuKnots, DOUBLE_QUADRATIC, FLAT, LINEAR, HAGAN);
            SabrIborCapletFloorletVolatilityCalibrationDefinition fixedRho  = SabrIborCapletFloorletVolatilityCalibrationDefinition.ofFixedRho(NAME, USD_LIBOR_3M, ACT_365F, BETA_RHO, ALPHA_KNOTS, BETA_RHO_KNOTS, nuKnots, DOUBLE_QUADRATIC, FLAT, LINEAR, HAGAN);
            ImmutableList <CurveMetadata> metadata = fixedBeta.createSabrParameterMetadata();
            DoubleArray   newValues         = DoubleArray.of(0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.02, 0.02, 0.02, 0.05);
            DoubleArray   newValues1        = DoubleArray.of(0.01, 0.01, 0.01, 0.01, 0.01, 0.01);
            DoubleArray   newValues2        = DoubleArray.of(0.02, 0.02, 0.02);
            DoubleArray   newValues3        = DoubleArray.of(0.05);
            IList <Curve> computedFixedBeta = fixedBeta.createSabrParameterCurve(metadata, newValues);
            IList <Curve> computedFixedRho  = fixedRho.createSabrParameterCurve(metadata, newValues);
            Curve         curveAlpha        = InterpolatedNodalCurve.of(metadata.get(0), ALPHA_KNOTS, newValues1, DOUBLE_QUADRATIC, FLAT, LINEAR);
            Curve         curveBeta         = InterpolatedNodalCurve.of(metadata.get(1), BETA_RHO_KNOTS, newValues2, DOUBLE_QUADRATIC, FLAT, LINEAR);
            Curve         curveRho          = InterpolatedNodalCurve.of(metadata.get(2), BETA_RHO_KNOTS, newValues2, DOUBLE_QUADRATIC, FLAT, LINEAR);
            Curve         curveNu           = ConstantNodalCurve.of(metadata.get(3), nuKnots.get(0), newValues3.get(0));

            assertEquals(computedFixedBeta, ImmutableList.of(curveAlpha, fixedBeta.BetaCurve.get(), curveRho, curveNu));
            assertEquals(computedFixedRho, ImmutableList.of(curveAlpha, curveBeta, fixedRho.RhoCurve.get(), curveNu));
        }
        //-------------------------------------------------------------------------
        // shift the curve
        private NodalCurve withShift(InterpolatedNodalCurve curve, IList <ParameterMetadata> parameterMetadata, DoubleMatrix sensitivity, bool computeJacobian, double shift)
        {
            int nNode = curve.ParameterCount;

            if (shift < curve.XValues.get(0))
            {
                //offset less than t value of 1st knot, so no knots are not removed
                double        eta      = curve.YValues.get(0) * shift;
                DoubleArray   time     = DoubleArray.of(nNode, i => curve.XValues.get(i) - shift);
                DoubleArray   rate     = DoubleArray.of(nNode, i => (curve.YValues.get(i) * curve.XValues.get(i) - eta) / time.get(i));
                CurveMetadata metadata = curve.Metadata.withParameterMetadata(parameterMetadata);
                if (computeJacobian)
                {
//JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java:
//ORIGINAL LINE: double[][] transf = new double[nNode][nNode];
                    double[][] transf = RectangularArrays.ReturnRectangularDoubleArray(nNode, nNode);
                    for (int i = 0; i < nNode; ++i)
                    {
                        transf[i][0]  = -shift / time.get(i);
                        transf[i][i] += curve.XValues.get(i) / time.get(i);
                    }
                    DoubleMatrix jacobianMatrix        = (DoubleMatrix)MATRIX_ALGEBRA.multiply(DoubleMatrix.ofUnsafe(transf), MATRIX_ALGEBRA.getInverse(sensitivity));
                    JacobianCalibrationMatrix jacobian = JacobianCalibrationMatrix.of(ImmutableList.of(CurveParameterSize.of(curve.Name, nNode)), jacobianMatrix);
                    return(curve.withValues(time, rate).withMetadata(metadata.withInfo(CurveInfoType.JACOBIAN, jacobian)));
                }
                return(curve.withValues(time, rate).withMetadata(metadata));
            }
            if (shift >= curve.XValues.get(nNode - 1))
            {
                //new base after last knot. The new 'curve' has a constant zero rate which we represent with a nominal knot at 1.0
                double time     = 1d;
                double interval = curve.XValues.get(nNode - 1) - curve.XValues.get(nNode - 2);
                double rate     = (curve.YValues.get(nNode - 1) * curve.XValues.get(nNode - 1) - curve.YValues.get(nNode - 2) * curve.XValues.get(nNode - 2)) / interval;
                if (computeJacobian)
                {
//JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java:
//ORIGINAL LINE: double[][] transf = new double[1][nNode];
                    double[][] transf = RectangularArrays.ReturnRectangularDoubleArray(1, nNode);
                    transf[0][nNode - 2] = -curve.XValues.get(nNode - 2) / interval;
                    transf[0][nNode - 1] = curve.XValues.get(nNode - 1) / interval;
                    DoubleMatrix jacobianMatrix        = (DoubleMatrix)MATRIX_ALGEBRA.multiply(DoubleMatrix.ofUnsafe(transf), MATRIX_ALGEBRA.getInverse(sensitivity));
                    JacobianCalibrationMatrix jacobian = JacobianCalibrationMatrix.of(ImmutableList.of(CurveParameterSize.of(curve.Name, nNode)), jacobianMatrix);
                    return(ConstantNodalCurve.of(curve.Metadata.withInfo(CurveInfoType.JACOBIAN, jacobian), time, rate));
                }
                return(ConstantNodalCurve.of(curve.Metadata, time, rate));
            }
            //offset greater than (or equal to) t value of 1st knot, so at least one knot must be removed
            int index = Arrays.binarySearch(curve.XValues.toArray(), shift);

            if (index < 0)
            {
                index = -(index + 1);
            }
            else
            {
                index++;
            }
            double        interval = curve.XValues.get(index) - curve.XValues.get(index - 1);
            double        tt1      = curve.XValues.get(index - 1) * (curve.XValues.get(index) - shift);
            double        tt2      = curve.XValues.get(index) * (shift - curve.XValues.get(index - 1));
            double        eta      = (curve.YValues.get(index - 1) * tt1 + curve.YValues.get(index) * tt2) / interval;
            int           m        = nNode - index;
            CurveMetadata metadata = curve.Metadata.withParameterMetadata(parameterMetadata.subList(index, nNode));
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final int indexFinal = index;
            int         indexFinal = index;
            DoubleArray time       = DoubleArray.of(m, i => curve.XValues.get(i + indexFinal) - shift);
            DoubleArray rate       = DoubleArray.of(m, i => (curve.YValues.get(i + indexFinal) * curve.XValues.get(i + indexFinal) - eta) / time.get(i));

            if (computeJacobian)
            {
//JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java:
//ORIGINAL LINE: double[][] transf = new double[m][nNode];
                double[][] transf = RectangularArrays.ReturnRectangularDoubleArray(m, nNode);
                for (int i = 0; i < m; ++i)
                {
                    transf[i][index - 1] -= tt1 / (time.get(i) * interval);
                    transf[i][index]     -= tt2 / (time.get(i) * interval);
                    transf[i][i + index] += curve.XValues.get(i + index) / time.get(i);
                }
                DoubleMatrix jacobianMatrix        = (DoubleMatrix)MATRIX_ALGEBRA.multiply(DoubleMatrix.ofUnsafe(transf), MATRIX_ALGEBRA.getInverse(sensitivity));
                JacobianCalibrationMatrix jacobian = JacobianCalibrationMatrix.of(ImmutableList.of(CurveParameterSize.of(curve.Name, nNode)), jacobianMatrix);
                return(curve.withValues(time, rate).withMetadata(metadata.withInfo(CurveInfoType.JACOBIAN, jacobian)));
            }
            return(curve.withValues(time, rate).withMetadata(metadata));
        }
Пример #5
0
        /// <summary>
        /// Creates an instance from year fraction and zero rate values.
        /// </summary>
        /// <param name="currency">  the currency </param>
        /// <param name="valuationDate">  the valuation date </param>
        /// <param name="curveName">  the curve name </param>
        /// <param name="yearFractions">  the year fractions </param>
        /// <param name="zeroRates">  the zero rates </param>
        /// <param name="dayCount">  the day count </param>
        /// <returns> the instance </returns>
        public static IsdaCreditDiscountFactors of(Currency currency, LocalDate valuationDate, CurveName curveName, DoubleArray yearFractions, DoubleArray zeroRates, DayCount dayCount)
        {
            ArgChecker.notNull(yearFractions, "yearFractions");
            ArgChecker.notNull(zeroRates, "zeroRates");
            DefaultCurveMetadata metadata = DefaultCurveMetadata.builder().xValueType(YEAR_FRACTION).yValueType(ZERO_RATE).curveName(curveName).dayCount(dayCount).build();
            NodalCurve           curve    = (yearFractions.size() == 1 && zeroRates.size() == 1) ? ConstantNodalCurve.of(metadata, yearFractions.get(0), zeroRates.get(0)) : InterpolatedNodalCurve.of(metadata, yearFractions, zeroRates, CurveInterpolators.PRODUCT_LINEAR, CurveExtrapolators.FLAT, CurveExtrapolators.PRODUCT_LINEAR);

            return(new IsdaCreditDiscountFactors(currency, valuationDate, curve));
        }
Пример #6
0
        //-------------------------------------------------------------------------
        public override NodalCurve calibrate(IList <ResolvedCdsTrade> calibrationCDSs, DoubleArray flactionalSpreads, DoubleArray pointsUpfront, CurveName name, LocalDate valuationDate, CreditDiscountFactors discountFactors, RecoveryRates recoveryRates, ReferenceData refData)
        {
            int n = calibrationCDSs.Count;

            double[] guess = new double[n];
            double[] t     = new double[n];
            double[] lgd   = new double[n];
            for (int i = 0; i < n; i++)
            {
                LocalDate endDate = calibrationCDSs[i].Product.ProtectionEndDate;
                t[i]     = discountFactors.relativeYearFraction(endDate);
                lgd[i]   = 1d - recoveryRates.recoveryRate(endDate);
                guess[i] = (flactionalSpreads.get(i) + pointsUpfront.get(i) / t[i]) / lgd[i];
            }
            DoubleArray   times        = DoubleArray.ofUnsafe(t);
            CurveMetadata baseMetadata = DefaultCurveMetadata.builder().xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.ZERO_RATE).curveName(name).dayCount(discountFactors.DayCount).build();
            NodalCurve    creditCurve  = n == 1 ? ConstantNodalCurve.of(baseMetadata, t[0], guess[0]) : InterpolatedNodalCurve.of(baseMetadata, times, DoubleArray.ofUnsafe(guess), CurveInterpolators.PRODUCT_LINEAR, CurveExtrapolators.FLAT, CurveExtrapolators.PRODUCT_LINEAR);

            for (int i = 0; i < n; i++)
            {
                ResolvedCds cds                = calibrationCDSs[i].Product;
                LocalDate   stepinDate         = cds.StepinDateOffset.adjust(valuationDate, refData);
                LocalDate   effectiveStartDate = cds.calculateEffectiveStartDate(stepinDate);
                LocalDate   settlementDate     = calibrationCDSs[i].Info.SettlementDate.orElse(cds.SettlementDateOffset.adjust(valuationDate, refData));
                double      accrued            = cds.accruedYearFraction(stepinDate);

                Pricer pricer = new Pricer(this, cds, discountFactors, times, flactionalSpreads.get(i), pointsUpfront.get(i), lgd[i], stepinDate, effectiveStartDate, settlementDate, accrued);
                System.Func <double, double> func = pricer.getPointFunction(i, creditCurve);

                switch (ArbitrageHandling)
                {
                case IGNORE:
                {
                    try
                    {
                        double[] bracket  = BRACKETER.getBracketedPoints(func, 0.8 * guess[i], 1.25 * guess[i], double.NegativeInfinity, double.PositiveInfinity);
                        double   zeroRate = bracket[0] > bracket[1] ? ROOTFINDER.getRoot(func, bracket[1], bracket[0]) : ROOTFINDER.getRoot(func, bracket[0], bracket[1]);       //Negative guess handled
                        creditCurve = creditCurve.withParameter(i, zeroRate);
                    }
//JAVA TO C# CONVERTER WARNING: 'final' catch parameters are not available in C#:
//ORIGINAL LINE: catch (final com.opengamma.strata.math.MathException e)
                    catch (MathException e)
                    {       //handling bracketing failure due to small survival probability
                        if (Math.Abs(func(creditCurve.YValues.get(i - 1))) < 1.e-12)
                        {
                            creditCurve = creditCurve.withParameter(i, creditCurve.YValues.get(i - 1));
                        }
                        else
                        {
                            throw new MathException(e);
                        }
                    }
                    break;
                }

                case FAIL:
                {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double minValue = i == 0 ? 0d : creditCurve.getYValues().get(i - 1) * creditCurve.getXValues().get(i - 1) / creditCurve.getXValues().get(i);
                    double minValue = i == 0 ? 0d : creditCurve.YValues.get(i - 1) * creditCurve.XValues.get(i - 1) / creditCurve.XValues.get(i);
                    if (i > 0 && func(minValue) > 0.0)
                    {       //can never fail on the first spread
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final StringBuilder msg = new StringBuilder();
                        StringBuilder msg = new StringBuilder();
                        if (pointsUpfront.get(i) == 0.0)
                        {
                            msg.Append("The par spread of " + flactionalSpreads.get(i) + " at index " + i);
                        }
                        else
                        {
                            msg.Append("The premium of " + flactionalSpreads.get(i) + "and points up-front of " + pointsUpfront.get(i) + " at index " + i);
                        }
                        msg.Append(" is an arbitrage; cannot fit a curve with positive forward hazard rate. ");
                        throw new System.ArgumentException(msg.ToString());
                    }
                    guess[i] = Math.Max(minValue, guess[i]);
                    double[] bracket  = BRACKETER.getBracketedPoints(func, guess[i], 1.2 * guess[i], minValue, double.PositiveInfinity);
                    double   zeroRate = ROOTFINDER.getRoot(func, bracket[0], bracket[1]).Value;
                    creditCurve = creditCurve.withParameter(i, zeroRate);
                    break;
                }

                case ZERO_HAZARD_RATE:
                {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double minValue = i == 0 ? 0.0 : creditCurve.getYValues().get(i - 1) * creditCurve.getXValues().get(i - 1) / creditCurve.getXValues().get(i);
                    double minValue = i == 0 ? 0.0 : creditCurve.YValues.get(i - 1) * creditCurve.XValues.get(i - 1) / creditCurve.XValues.get(i);
                    if (i > 0 && func(minValue) > 0.0)
                    {       //can never fail on the first spread
                        creditCurve = creditCurve.withParameter(i, minValue);
                    }
                    else
                    {
                        guess[i] = Math.Max(minValue, guess[i]);
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double[] bracket = BRACKETER.getBracketedPoints(func, guess[i], 1.2 * guess[i], minValue, Double.POSITIVE_INFINITY);
                        double[] bracket = BRACKETER.getBracketedPoints(func, guess[i], 1.2 * guess[i], minValue, double.PositiveInfinity);
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double zeroRate = ROOTFINDER.getRoot(func, bracket[0], bracket[1]);
                        double zeroRate = ROOTFINDER.getRoot(func, bracket[0], bracket[1]).Value;
                        creditCurve = creditCurve.withParameter(i, zeroRate);
                    }
                    break;
                }

                default:
                    throw new System.ArgumentException("unknown case " + ArbitrageHandling);
                }
            }
            return(creditCurve);
        }