//-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the market quote sensitivities from parameter sensitivity.
        /// </summary>
        /// <param name="paramSensitivities">  the curve parameter sensitivities </param>
        /// <param name="provider">  the rates provider, containing Jacobian calibration information </param>
        /// <returns> the market quote sensitivities </returns>
        public virtual CurrencyParameterSensitivities sensitivity(CurrencyParameterSensitivities paramSensitivities, RatesProvider provider)
        {
            ArgChecker.notNull(paramSensitivities, "paramSensitivities");
            ArgChecker.notNull(provider, "provider");

            CurrencyParameterSensitivities result = CurrencyParameterSensitivities.empty();

            foreach (CurrencyParameterSensitivity paramSens in paramSensitivities.Sensitivities)
            {
                // find the matching calibration info
                Curve curve = provider.findData(paramSens.MarketDataName).filter(v => v is Curve).map(v => (Curve)v).orElseThrow(() => new System.ArgumentException("Market Quote sensitivity requires curve: " + paramSens.MarketDataName));
                JacobianCalibrationMatrix info = curve.Metadata.findInfo(CurveInfoType.JACOBIAN).orElseThrow(() => new System.ArgumentException("Market Quote sensitivity requires Jacobian calibration information"));

                // calculate the market quote sensitivity using the Jacobian
                DoubleMatrix jacobian              = info.JacobianMatrix;
                DoubleArray  paramSensMatrix       = paramSens.Sensitivity;
                DoubleArray  marketQuoteSensMatrix = (DoubleArray)MATRIX_ALGEBRA.multiply(paramSensMatrix, jacobian);
                DoubleArray  marketQuoteSens       = marketQuoteSensMatrix;

                // split between different curves
                IDictionary <CurveName, DoubleArray> split = info.splitValues(marketQuoteSens);
                foreach (KeyValuePair <CurveName, DoubleArray> entry in split.SetOfKeyValuePairs())
                {
                    CurveName curveName = entry.Key;
                    CurrencyParameterSensitivity maketQuoteSens = provider.findData(curveName).map(c => c.createParameterSensitivity(paramSens.Currency, entry.Value)).orElse(CurrencyParameterSensitivity.of(curveName, paramSens.Currency, entry.Value));
                    result = result.combinedWith(maketQuoteSens);
                }
            }
            return(result);
        }
コード例 #2
0
        /// <summary>
        /// get the k^th order penalty matrix, P. This is defined as P = (D^T)*D , where D is the k^th order difference
        /// matrix (see getDifferenceMatrix), so the scalar amount (x^T)*P*x = |Dx|^2  is greater the more k^th order
        /// differences there are in the vector, x. This can then act as a penalty on x in some optimisation routine where
        /// x is the vector of (fit) parameters. </summary>
        /// <param name="m"> Length of the  vector. </param>
        /// <param name="k"> Difference order. Require m > k </param>
        /// <returns> The k^th order penalty matrix, P </returns>
        public static DoubleMatrix getPenaltyMatrix(int m, int k)
        {
            ArgChecker.notNegativeOrZero(m, "m");
            ArgChecker.notNegative(k, "k");
            ArgChecker.isTrue(k < m, "Difference order too high, require m > k, but have: m = {} and k = {}", m, k);
            if (k == 0)
            {
                return(DoubleMatrix.identity(m));
            }
            DoubleMatrix d  = getDifferenceMatrix(m, k);
            DoubleMatrix dt = MA.getTranspose(d);

            return((DoubleMatrix)MA.multiply(dt, d));
        }
コード例 #3
0
        // jacobian indirect, merging groups
        private static DoubleMatrix jacobianIndirect(DoubleMatrix res, DoubleMatrix pDmCurrentMatrix, int nbTrades, int totalParamsGroup, int totalParamsPrevious, ImmutableList <CurveParameterSize> orderPrevious, ImmutableMap <CurveName, JacobianCalibrationMatrix> jacobiansPrevious)
        {
            if (totalParamsPrevious == 0)
            {
                return(DoubleMatrix.EMPTY);
            }
//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[][] nonDirect = new double[totalParamsGroup][totalParamsPrevious];
            double[][] nonDirect = RectangularArrays.ReturnRectangularDoubleArray(totalParamsGroup, totalParamsPrevious);
            for (int i = 0; i < nbTrades; i++)
            {
                Array.Copy(res.rowArray(i), 0, nonDirect[i], 0, totalParamsPrevious);
            }
            DoubleMatrix pDpPreviousMatrix = (DoubleMatrix)MATRIX_ALGEBRA.scale(MATRIX_ALGEBRA.multiply(pDmCurrentMatrix, DoubleMatrix.copyOf(nonDirect)), -1d);

            // all curves: order and size
            int[] startIndexBefore = new int[orderPrevious.size()];
            for (int i = 1; i < orderPrevious.size(); i++)
            {
                startIndexBefore[i] = startIndexBefore[i - 1] + orderPrevious.get(i - 1).ParameterCount;
            }
            // transition Matrix: all curves from previous groups
//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[][] transition = new double[totalParamsPrevious][totalParamsPrevious];
            double[][] transition = RectangularArrays.ReturnRectangularDoubleArray(totalParamsPrevious, totalParamsPrevious);
            for (int i = 0; i < orderPrevious.size(); i++)
            {
                int paramCountOuter = orderPrevious.get(i).ParameterCount;
                JacobianCalibrationMatrix thisInfo = jacobiansPrevious.get(orderPrevious.get(i).Name);
                DoubleMatrix thisMatrix            = thisInfo.JacobianMatrix;
                int          startIndexInner       = 0;
                for (int j = 0; j < orderPrevious.size(); j++)
                {
                    int paramCountInner = orderPrevious.get(j).ParameterCount;
                    if (thisInfo.containsCurve(orderPrevious.get(j).Name))
                    {     // If not, the matrix stay with 0
                        for (int k = 0; k < paramCountOuter; k++)
                        {
                            Array.Copy(thisMatrix.rowArray(k), startIndexInner, transition[startIndexBefore[i] + k], startIndexBefore[j], paramCountInner);
                        }
                    }
                    startIndexInner += paramCountInner;
                }
            }
            DoubleMatrix transitionMatrix = DoubleMatrix.copyOf(transition);

            return((DoubleMatrix)MATRIX_ALGEBRA.multiply(pDpPreviousMatrix, transitionMatrix));
        }
コード例 #4
0
        private DoubleMatrix getDiffMatrix(int m, int k)
        {
            ArgChecker.isTrue(k < m, "difference order too high");

//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[][] data = new double[m][m];
            double[][] data = RectangularArrays.ReturnRectangularDoubleArray(m, m);
            if (m == 0)
            {
                return(DoubleMatrix.copyOf(data));
            }

            int[] coeff = new int[k + 1];

            int sign = 1;

            for (int i = k; i >= 0; i--)
            {
                coeff[i] = (int)(sign * binomialCoefficient(k, i));
                sign    *= -1;
            }

            for (int i = k; i < m; i++)
            {
                for (int j = 0; j < k + 1; j++)
                {
                    data[i][j + i - k] = coeff[j];
                }
            }
            DoubleMatrix d = DoubleMatrix.copyOf(data);

            DoubleMatrix dt = _algebra.getTranspose(d);

            return((DoubleMatrix)_algebra.multiply(dt, d));
        }
        //-------------------------------------------------------------------------
        // 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));
        }
コード例 #6
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void differenceMatrix1DTest()
        public virtual void differenceMatrix1DTest()
        {
            int n = 7;

            DoubleMatrix d0 = PenaltyMatrixGenerator.getDifferenceMatrix(n, 0);     //zeroth order

            AssertMatrix.assertEqualsMatrix(DoubleMatrix.identity(n), d0, 1e-15);

            DoubleArray  zeroVector = DoubleArray.filled(n);
            DoubleMatrix d1         = PenaltyMatrixGenerator.getDifferenceMatrix(n, 1); //first order difference matrix

            assertEquals(n, d1.rowCount());
            assertEquals(n, d1.columnCount());
            AssertMatrix.assertEqualsVectors(zeroVector, d1.row(0), 1e-15);     //first row should be zero

            DoubleArray x   = DoubleArray.filled(n, 1.0);
            DoubleArray d1x = (DoubleArray)MA.multiply(d1, x);

            //a constant vector should have zero first order differences
            AssertMatrix.assertEqualsVectors(zeroVector, d1x, 1e-14);

            DoubleMatrix d2 = PenaltyMatrixGenerator.getDifferenceMatrix(n, 2);     //second order difference matrix

            assertEquals(n, d2.rowCount());
            assertEquals(n, d2.columnCount());
            AssertMatrix.assertEqualsVectors(zeroVector, d2.row(0), 1e-15);     //first two rows should be zero
            AssertMatrix.assertEqualsVectors(zeroVector, d2.row(1), 1e-15);

            DoubleArray x2 = DoubleArray.of(n, i => i);

            d1x = (DoubleArray)MA.multiply(d1, x2);
            //first element of the diff vector is set to zero
            DoubleArray ones = DoubleArray.filled(n, 1.0).with(0, 0);

            //vector with differences of one
            AssertMatrix.assertEqualsVectors(ones, d1x, 1e-14);

            DoubleArray d2x = (DoubleArray)MA.multiply(d2, x2);

            //a linear vector should have zero second order differences
            AssertMatrix.assertEqualsVectors(zeroVector, d2x, 1e-14);

            DoubleMatrix d3 = PenaltyMatrixGenerator.getDifferenceMatrix(n, 3);     //third order difference matrix

            assertEquals(n, d3.rowCount());
            assertEquals(n, d3.columnCount());
            AssertMatrix.assertEqualsVectors(zeroVector, d3.row(0), 1e-15);     //first three rows should be zero
            AssertMatrix.assertEqualsVectors(zeroVector, d3.row(1), 1e-15);
            AssertMatrix.assertEqualsVectors(zeroVector, d3.row(2), 1e-15);

            DoubleArray x3 = DoubleArray.of(n, i => 0.5 + i + 0.1 * i * i);

            d1x = (DoubleArray)MA.multiply(d1, x3);
            // expected first order diff, first element is zero
            DoubleArray exp = DoubleArray.of(n, i => 0.9 + 0.2 * i).with(0, 0);

            AssertMatrix.assertEqualsVectors(exp, d1x, 1e-14);

            // expected second order diff, first two elements are zero
            exp = DoubleArray.filled(n, 0.2).with(0, 0).with(1, 0);
            d2x = (DoubleArray)MA.multiply(d2, x3);
            AssertMatrix.assertEqualsVectors(exp, d2x, 1e-14);

            DoubleArray d3x = (DoubleArray)MA.multiply(d3, x3);

            //a quadratic vector should have zero third order differences
            AssertMatrix.assertEqualsVectors(zeroVector, d3x, 1e-14);
        }
        internal virtual LegalEntitySurvivalProbabilities calibrate(IList <CdsIsdaCreditCurveNode> curveNodes, CurveName name, MarketData marketData, ImmutableCreditRatesProvider ratesProvider, DayCount definitionDayCount, Currency definitionCurrency, bool computeJacobian, bool storeTrade, ReferenceData refData)
        {
//JAVA TO C# CONVERTER TODO TASK: Method reference arbitrary object instance method syntax is not converted by Java to C# Converter:
//JAVA TO C# CONVERTER TODO TASK: Most Java stream collectors are not converted by Java to C# Converter:
            IEnumerator <StandardId> legalEntities = curveNodes.Select(CdsIsdaCreditCurveNode::getLegalEntityId).collect(Collectors.toSet()).GetEnumerator();
//JAVA TO C# CONVERTER TODO TASK: Java iterators are only converted within the context of 'while' and 'for' loops:
            StandardId legalEntityId = legalEntities.next();

//JAVA TO C# CONVERTER TODO TASK: Java iterators are only converted within the context of 'while' and 'for' loops:
            ArgChecker.isFalse(legalEntities.hasNext(), "legal entity must be common to curve nodes");
//JAVA TO C# CONVERTER TODO TASK: Most Java stream collectors are not converted by Java to C# Converter:
            IEnumerator <Currency> currencies = curveNodes.Select(n => n.Template.Convention.Currency).collect(Collectors.toSet()).GetEnumerator();
//JAVA TO C# CONVERTER TODO TASK: Java iterators are only converted within the context of 'while' and 'for' loops:
            Currency currency = currencies.next();

//JAVA TO C# CONVERTER TODO TASK: Java iterators are only converted within the context of 'while' and 'for' loops:
            ArgChecker.isFalse(currencies.hasNext(), "currency must be common to curve nodes");
            ArgChecker.isTrue(definitionCurrency.Equals(currency), "curve definition currency must be the same as the currency of CDS");
//JAVA TO C# CONVERTER TODO TASK: Most Java stream collectors are not converted by Java to C# Converter:
            IEnumerator <CdsQuoteConvention> quoteConventions = curveNodes.Select(n => n.QuoteConvention).collect(Collectors.toSet()).GetEnumerator();
//JAVA TO C# CONVERTER TODO TASK: Java iterators are only converted within the context of 'while' and 'for' loops:
            CdsQuoteConvention quoteConvention = quoteConventions.next();

//JAVA TO C# CONVERTER TODO TASK: Java iterators are only converted within the context of 'while' and 'for' loops:
            ArgChecker.isFalse(quoteConventions.hasNext(), "quote convention must be common to curve nodes");
            LocalDate valuationDate = marketData.ValuationDate;

            ArgChecker.isTrue(valuationDate.Equals(marketData.ValuationDate), "ratesProvider and marketDate must be based on the same valuation date");
            CreditDiscountFactors discountFactors = ratesProvider.discountFactors(currency);

            ArgChecker.isTrue(definitionDayCount.Equals(discountFactors.DayCount), "credit curve and discount curve must be based on the same day count convention");
            RecoveryRates recoveryRates = ratesProvider.recoveryRates(legalEntityId);

            int nNodes = curveNodes.Count;

            double[] coupons = new double[nNodes];
            double[] pufs    = new double[nNodes];
//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[][] diag = new double[nNodes][nNodes];
            double[][] diag = RectangularArrays.ReturnRectangularDoubleArray(nNodes, nNodes);
            ImmutableList.Builder <ResolvedCdsTrade> tradesBuilder = ImmutableList.builder();
            for (int i = 0; i < nNodes; i++)
            {
                CdsCalibrationTrade tradeCalibration = curveNodes[i].trade(1d, marketData, refData);
                ResolvedCdsTrade    trade            = tradeCalibration.UnderlyingTrade.resolve(refData);
                tradesBuilder.add(trade);
                double[] temp = getStandardQuoteForm(trade, tradeCalibration.Quote, valuationDate, discountFactors, recoveryRates, computeJacobian, refData);
                coupons[i] = temp[0];
                pufs[i]    = temp[1];
                diag[i][i] = temp[2];
            }
            ImmutableList <ResolvedCdsTrade> trades = tradesBuilder.build();
            NodalCurve nodalCurve = calibrate(trades, DoubleArray.ofUnsafe(coupons), DoubleArray.ofUnsafe(pufs), name, valuationDate, discountFactors, recoveryRates, refData);

            if (computeJacobian)
            {
                LegalEntitySurvivalProbabilities            creditCurve      = LegalEntitySurvivalProbabilities.of(legalEntityId, IsdaCreditDiscountFactors.of(currency, valuationDate, nodalCurve));
                ImmutableCreditRatesProvider                ratesProviderNew = ratesProvider.toBuilder().creditCurves(ImmutableMap.of(Pair.of(legalEntityId, currency), creditCurve)).build();
                System.Func <ResolvedCdsTrade, DoubleArray> sensiFunc        = quoteConvention.Equals(CdsQuoteConvention.PAR_SPREAD) ? getParSpreadSensitivityFunction(ratesProviderNew, name, currency, refData) : getPointsUpfrontSensitivityFunction(ratesProviderNew, name, currency, refData);
                DoubleMatrix sensi = DoubleMatrix.ofArrayObjects(nNodes, nNodes, i => sensiFunc(trades.get(i)));
                sensi = (DoubleMatrix)MATRIX_ALGEBRA.multiply(DoubleMatrix.ofUnsafe(diag), sensi);
                JacobianCalibrationMatrix jacobian = JacobianCalibrationMatrix.of(ImmutableList.of(CurveParameterSize.of(name, nNodes)), MATRIX_ALGEBRA.getInverse(sensi));
                nodalCurve = nodalCurve.withMetadata(nodalCurve.Metadata.withInfo(CurveInfoType.JACOBIAN, jacobian));
            }

            ImmutableList <ParameterMetadata> parameterMetadata;

            if (storeTrade)
            {
                parameterMetadata = IntStream.range(0, nNodes).mapToObj(n => ResolvedTradeParameterMetadata.of(trades.get(n), curveNodes[n].Label)).collect(Guavate.toImmutableList());
            }
            else
            {
                parameterMetadata = IntStream.range(0, nNodes).mapToObj(n => curveNodes[n].metadata(trades.get(n).Product.ProtectionEndDate)).collect(Guavate.toImmutableList());
            }
            nodalCurve = nodalCurve.withMetadata(nodalCurve.Metadata.withParameterMetadata(parameterMetadata));

            return(LegalEntitySurvivalProbabilities.of(legalEntityId, IsdaCreditDiscountFactors.of(currency, valuationDate, nodalCurve)));
        }