Example #1
0
        private CurrencyParameterSensitivities sensitivityCreidtCurve <T>(ImmutableCreditRatesProvider provider, System.Func <ImmutableCreditRatesProvider, CurrencyAmount> valueFn, MetaProperty <ImmutableMap <T, LegalEntitySurvivalProbabilities> > metaProperty, CurrencyAmount valueInit)
        {
            ImmutableMap <T, LegalEntitySurvivalProbabilities> baseCurves = metaProperty.get(provider);
            CurrencyParameterSensitivities result = CurrencyParameterSensitivities.empty();

            foreach (T key in baseCurves.Keys)
            {
                LegalEntitySurvivalProbabilities credit = baseCurves.get(key);
                CreditDiscountFactors            creditDiscountFactors = credit.SurvivalProbabilities;
                DiscountFactors discountFactors = creditDiscountFactors.toDiscountFactors();
                Curve           curve           = checkDiscountFactors(discountFactors);
                int             paramCount      = curve.ParameterCount;
                double[]        sensitivity     = new double[paramCount];
                for (int i = 0; i < paramCount; i++)
                {
                    Curve dscBumped = curve.withParameter(i, curve.getParameter(i) + shift);
                    IDictionary <T, LegalEntitySurvivalProbabilities> mapBumped = new Dictionary <T, LegalEntitySurvivalProbabilities>(baseCurves);
                    mapBumped[key] = LegalEntitySurvivalProbabilities.of(credit.LegalEntityId, createCreditDiscountFactors(creditDiscountFactors, dscBumped));
                    ImmutableCreditRatesProvider providerDscBumped = provider.toBuilder().set(metaProperty, mapBumped).build();
                    sensitivity[i] = (valueFn(providerDscBumped).Amount - valueInit.Amount) / shift;
                }
                result = result.combinedWith(curve.createParameterSensitivity(valueInit.Currency, DoubleArray.copyOf(sensitivity)));
            }
            return(result);
        }
Example #2
0
 private LegalEntitySurvivalProbabilities(StandardId legalEntityId, CreditDiscountFactors survivalProbabilities)
 {
     JodaBeanUtils.notNull(legalEntityId, "legalEntityId");
     JodaBeanUtils.notNull(survivalProbabilities, "survivalProbabilities");
     this.legalEntityId         = legalEntityId;
     this.survivalProbabilities = survivalProbabilities;
 }
Example #3
0
        //-------------------------------------------------------------------------
        private static CreditRatesProvider createCreditRatesProviderSingle(LocalDate valuationDate, bool isSingle)
        {
            IsdaCreditDiscountFactors yc = IsdaCreditDiscountFactors.of(USD, valuationDate, NODAL_YC);
            CreditDiscountFactors     cc = isSingle ? IsdaCreditDiscountFactors.of(USD, valuationDate, NODAL_CC_SINGLE) : IsdaCreditDiscountFactors.of(USD, valuationDate, NODAL_CC);
            ConstantRecoveryRates     rr = ConstantRecoveryRates.of(INDEX_ID, valuationDate, RECOVERY_RATE);

            return(ImmutableCreditRatesProvider.builder().valuationDate(valuationDate).creditCurves(ImmutableMap.of(Pair.of(INDEX_ID, USD), LegalEntitySurvivalProbabilities.of(INDEX_ID, cc))).discountCurves(ImmutableMap.of(USD, yc)).recoveryRateCurves(ImmutableMap.of(INDEX_ID, rr)).build());
        }
Example #4
0
 // return correct instance of CreditDiscountFactors
 private CreditDiscountFactors createCreditDiscountFactors(CreditDiscountFactors originalDsc, Curve bumpedCurve)
 {
     if (originalDsc is IsdaCreditDiscountFactors && bumpedCurve is NodalCurve)
     {
         IsdaCreditDiscountFactors isdaDsc = (IsdaCreditDiscountFactors)originalDsc;
         return(isdaDsc.withCurve((NodalCurve)bumpedCurve));
     }
     throw new System.ArgumentException("Not supported");
 }
Example #5
0
        public CreditDiscountFactors discountFactors(Currency currency)
        {
            CreditDiscountFactors discountFactors = discountCurves.get(currency);

            if (discountFactors == null)
            {
                throw new System.ArgumentException("Unable to find discount curve: " + currency);
            }
            return(discountFactors);
        }
        public CreditDiscountFactors discountFactors(Currency currency)
        {
            CurveId curveId = lookup.DiscountCurveIds.get(currency);

            if (curveId == null)
            {
                throw new MarketDataNotFoundException("Unable to find discount curve: " + currency);
            }
            Curve curve = marketData.getValue(curveId);

            return(CreditDiscountFactors.of(currency, ValuationDate, curve));
        }
Example #7
0
        private Pair <CreditDiscountFactors, LegalEntitySurvivalProbabilities> reduceDiscountFactors(ResolvedCds cds, CreditRatesProvider ratesProvider)
        {
            Currency currency = cds.Currency;
            CreditDiscountFactors discountFactors = ratesProvider.discountFactors(currency);

            ArgChecker.isTrue(discountFactors.IsdaCompliant, "discount factors must be IsdaCompliantZeroRateDiscountFactors");
            LegalEntitySurvivalProbabilities survivalProbabilities = ratesProvider.survivalProbabilities(cds.LegalEntityId, currency);

            ArgChecker.isTrue(survivalProbabilities.SurvivalProbabilities.IsdaCompliant, "survival probabilities must be IsdaCompliantZeroRateDiscountFactors");
            ArgChecker.isTrue(discountFactors.DayCount.Equals(survivalProbabilities.SurvivalProbabilities.DayCount), "day count conventions of discounting curve and credit curve must be the same");
            return(Pair.of(discountFactors, survivalProbabilities));
        }
        //-------------------------------------------------------------------------
        public LegalEntitySurvivalProbabilities survivalProbabilities(StandardId legalEntityId, Currency currency)
        {
            CurveId curveId = lookup.CreditCurveIds.get(Pair.of(legalEntityId, currency));

            if (curveId == null)
            {
                throw new MarketDataNotFoundException("Unable to find credit curve: " + legalEntityId + ", " + currency);
            }
            Curve curve = marketData.getValue(curveId);
            CreditDiscountFactors survivalProbabilities = CreditDiscountFactors.of(currency, ValuationDate, curve);

            return(LegalEntitySurvivalProbabilities.of(legalEntityId, survivalProbabilities));
        }
        internal virtual Triple <CreditDiscountFactors, LegalEntitySurvivalProbabilities, double> reduceDiscountFactors(ResolvedCds cds, CreditRatesProvider ratesProvider)
        {
            Currency currency = cds.Currency;
            CreditDiscountFactors discountFactors = ratesProvider.discountFactors(currency);

            ArgChecker.isTrue(discountFactors.IsdaCompliant, "discount factors must be IsdaCompliantZeroRateDiscountFactors");
            LegalEntitySurvivalProbabilities survivalProbabilities = ratesProvider.survivalProbabilities(cds.LegalEntityId, currency);

            ArgChecker.isTrue(survivalProbabilities.SurvivalProbabilities.IsdaCompliant, "survival probabilities must be IsdaCompliantZeroRateDiscountFactors");
            ArgChecker.isTrue(discountFactors.DayCount.Equals(survivalProbabilities.SurvivalProbabilities.DayCount), "day count conventions of discounting curve and credit curve must be the same");
            double indexFactor = ((IsdaCreditDiscountFactors)survivalProbabilities.SurvivalProbabilities).Curve.Metadata.getInfo(CurveInfoType.CDS_INDEX_FACTOR);

            return(Triple.of(discountFactors, survivalProbabilities, indexFactor));
        }
Example #10
0
            public override Builder set(string propertyName, object newValue)
            {
                switch (propertyName.GetHashCode())
                {
                case 866287159:         // legalEntityId
                    this.legalEntityId = (StandardId)newValue;
                    break;

                case -2020275979:         // survivalProbabilities
                    this.survivalProbabilities = (CreditDiscountFactors)newValue;
                    break;

                default:
                    throw new NoSuchElementException("Unknown property: " + propertyName);
                }
                return(this);
            }
Example #11
0
        public virtual void test_of_constant_interface()
        {
            IsdaCreditDiscountFactors test = (IsdaCreditDiscountFactors)CreditDiscountFactors.of(USD, VALUATION, CONST_CURVE);

            assertEquals(test.Currency, USD);
            assertEquals(test.Curve, CONST_CURVE);
            assertEquals(test.DayCount, ACT_365L);
            assertEquals(test.ParameterCount, 1);
            assertEquals(test.getParameter(0), RATE_SINGLE);
            assertEquals(test.ParameterKeys, DoubleArray.of(TIME_SINGLE));
            assertEquals(test.getParameterMetadata(0), SimpleCurveParameterMetadata.of(METADATA.XValueType, TIME_SINGLE));
            assertEquals(test.ValuationDate, VALUATION);
            assertEquals(test.findData(CONST_CURVE.Name), CONST_CURVE);
            assertEquals(test.findData(CurveName.of("Rubbish")), null);
            assertEquals(test.toDiscountFactors(), ZeroRateDiscountFactors.of(USD, VALUATION, CONST_CURVE));
            assertEquals(test.IsdaCompliant, true);
        }
Example #12
0
        // extract CDS index trades from credit curve
        private ImmutableList <ResolvedCdsIndexTrade> getBucketCdsIndex(ResolvedCdsIndex product, CreditRatesProvider ratesProvider)
        {
            CreditDiscountFactors creditCurve = ratesProvider.survivalProbabilities(product.CdsIndexId, product.Currency).SurvivalProbabilities;
            int nNodes = creditCurve.ParameterCount;

            ImmutableList.Builder <ResolvedCdsIndexTrade> builder = ImmutableList.builder();
            for (int i = 0; i < nNodes; ++i)
            {
                ParameterMetadata metadata = creditCurve.getParameterMetadata(i);
                ArgChecker.isTrue(metadata is ResolvedTradeParameterMetadata, "ParameterMetadata of credit curve must be ResolvedTradeParameterMetadata");
                ResolvedTradeParameterMetadata tradeMetadata = (ResolvedTradeParameterMetadata)metadata;
                ResolvedTrade trade = tradeMetadata.Trade;
                ArgChecker.isTrue(trade is ResolvedCdsIndexTrade, "ResolvedTrade must be ResolvedCdsIndexTrade");
                builder.add((ResolvedCdsIndexTrade)trade);
            }
            return(builder.build());
        }
        //-------------------------------------------------------------------------
        public ImmutableCreditRatesProvider toImmutableCreditRatesProvider()
        {
            LocalDate valuationDate = ValuationDate;
            // credit curves
            IDictionary <Pair <StandardId, Currency>, LegalEntitySurvivalProbabilities> creditCurves = new Dictionary <Pair <StandardId, Currency>, LegalEntitySurvivalProbabilities>();

            foreach (Pair <StandardId, Currency> pair in lookup.CreditCurveIds.Keys)
            {
                CurveId curveId = lookup.CreditCurveIds.get(pair);
                if (marketData.containsValue(curveId))
                {
                    Curve curve = marketData.getValue(curveId);
                    CreditDiscountFactors survivalProbabilities = CreditDiscountFactors.of(pair.Second, valuationDate, curve);
                    creditCurves[pair] = LegalEntitySurvivalProbabilities.of(pair.First, survivalProbabilities);
                }
            }
            // discount curves
            IDictionary <Currency, CreditDiscountFactors> discountCurves = new Dictionary <Currency, CreditDiscountFactors>();

            foreach (Currency currency in lookup.DiscountCurveIds.Keys)
            {
                CurveId curveId = lookup.DiscountCurveIds.get(currency);
                if (marketData.containsValue(curveId))
                {
                    Curve curve = marketData.getValue(curveId);
                    discountCurves[currency] = CreditDiscountFactors.of(currency, valuationDate, curve);
                }
            }
            // recovery rate curves
            IDictionary <StandardId, RecoveryRates> recoveryRateCurves = new Dictionary <StandardId, RecoveryRates>();

            foreach (StandardId legalEntityId in lookup.RecoveryRateCurveIds.Keys)
            {
                CurveId curveId = lookup.RecoveryRateCurveIds.get(legalEntityId);
                if (marketData.containsValue(curveId))
                {
                    Curve         curve        = marketData.getValue(curveId);
                    RecoveryRates recoveryRate = RecoveryRates.of(legalEntityId, valuationDate, curve);
                    recoveryRateCurves[legalEntityId] = recoveryRate;
                }
            }
            // build result
            return(ImmutableCreditRatesProvider.builder().valuationDate(valuationDate).creditCurves(creditCurves).discountCurves(discountCurves).recoveryRateCurves(recoveryRateCurves).build());
        }
        public CurrencyParameterSensitivity singleDiscountCurveParameterSensitivity(PointSensitivities pointSensitivities, Currency currency)
        {
            CurrencyParameterSensitivities sens = CurrencyParameterSensitivities.empty();

            foreach (PointSensitivity point in pointSensitivities.Sensitivities)
            {
                if (point is ZeroRateSensitivity)
                {
                    ZeroRateSensitivity pt = (ZeroRateSensitivity)point;
                    if (pt.Currency.Equals(currency))
                    {
                        CreditDiscountFactors factors = discountFactors(pt.CurveCurrency);
                        sens = sens.combinedWith(factors.parameterSensitivity(pt));
                    }
                }
            }
            ArgChecker.isTrue(sens.size() == 1, "sensitivity must be unique");
            return(sens.Sensitivities.get(0));
        }
Example #15
0
        public virtual void test_of_interface()
        {
            IsdaCreditDiscountFactors test = (IsdaCreditDiscountFactors)CreditDiscountFactors.of(USD, VALUATION, CURVE);

            assertEquals(test.Currency, USD);
            assertEquals(test.Curve, CURVE);
            assertEquals(test.DayCount, ACT_365F);
            assertEquals(test.ParameterCount, RATE.size());
            assertEquals(test.getParameter(3), RATE.get(3));
            assertEquals(test.getParameter(1), RATE.get(1));
            assertEquals(test.ParameterKeys, TIME);
            assertEquals(test.getParameterMetadata(4), SimpleCurveParameterMetadata.of(METADATA.XValueType, TIME.get(4)));
            assertEquals(test.getParameterMetadata(6), SimpleCurveParameterMetadata.of(METADATA.XValueType, TIME.get(6)));
            assertEquals(test.ValuationDate, VALUATION);
            assertEquals(test.findData(CURVE.Name), CURVE);
            assertEquals(test.findData(CurveName.of("Rubbish")), null);
            assertEquals(test.toDiscountFactors(), ZeroRateDiscountFactors.of(USD, VALUATION, CURVE));
            assertEquals(test.IsdaCompliant, true);
        }
        //-------------------------------------------------------------------------
        public CurrencyParameterSensitivities parameterSensitivity(PointSensitivities pointSensitivities)
        {
            CurrencyParameterSensitivities sens = CurrencyParameterSensitivities.empty();

            foreach (PointSensitivity point in pointSensitivities.Sensitivities)
            {
                if (point is CreditCurveZeroRateSensitivity)
                {
                    CreditCurveZeroRateSensitivity   pt      = (CreditCurveZeroRateSensitivity)point;
                    LegalEntitySurvivalProbabilities factors = survivalProbabilities(pt.LegalEntityId, pt.CurveCurrency);
                    sens = sens.combinedWith(factors.parameterSensitivity(pt));
                }
                else if (point is ZeroRateSensitivity)
                {
                    ZeroRateSensitivity   pt      = (ZeroRateSensitivity)point;
                    CreditDiscountFactors factors = discountFactors(pt.CurveCurrency);
                    sens = sens.combinedWith(factors.parameterSensitivity(pt));
                }
            }
            return(sens);
        }
Example #17
0
        /// <summary>
        /// The par spread quotes are converted to points upfronts or quoted spreads.
        /// <para>
        /// The relevant discount curve and recovery rate curve must be stored in {@code ratesProvider}.
        /// The credit curve is internally calibrated to par spread values.
        /// </para>
        /// <para>
        /// {@code trades} must be sorted in ascending order in maturity and coherent to {@code quotes}.
        /// </para>
        /// <para>
        /// The resultant quote is specified by {@code targetConvention}.
        ///
        /// </para>
        /// </summary>
        /// <param name="trades">  the trades </param>
        /// <param name="quotes">  the quotes </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="targetConvention">  the target convention </param>
        /// <param name="refData">  the reference data </param>
        /// <returns> the quotes </returns>
        public virtual IList <CdsQuote> quotesFromParSpread(IList <ResolvedCdsTrade> trades, IList <CdsQuote> quotes, CreditRatesProvider ratesProvider, CdsQuoteConvention targetConvention, ReferenceData refData)
        {
            ArgChecker.noNulls(trades, "trades");
            ArgChecker.noNulls(quotes, "quotes");
            ArgChecker.notNull(ratesProvider, "ratesProvider");
            ArgChecker.notNull(targetConvention, "targetConvention");
            ArgChecker.notNull(refData, "refData");

            int nNodes = trades.Count;

            ArgChecker.isTrue(quotes.Count == nNodes, "trades and quotes must be the same size");
            quotes.ForEach(q => ArgChecker.isTrue(q.QuoteConvention.Equals(CdsQuoteConvention.PAR_SPREAD), "quote must be par spread"));
//JAVA TO C# CONVERTER TODO TASK: Most Java stream collectors are not converted by Java to C# Converter:
            IEnumerator <StandardId> legalEntities = trades.Select(t => t.Product.LegalEntityId).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 trades");
//JAVA TO C# CONVERTER TODO TASK: Most Java stream collectors are not converted by Java to C# Converter:
            IEnumerator <Currency> currencies = trades.Select(t => t.Product.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 trades");

            LocalDate             valuationDate    = ratesProvider.ValuationDate;
            CreditDiscountFactors discountFactors  = ratesProvider.discountFactors(currency);
            RecoveryRates         recoveryRates    = ratesProvider.recoveryRates(legalEntityId);
            NodalCurve            creditCurve      = calibrator.calibrate(trades, DoubleArray.of(nNodes, q => quotes[q].QuotedValue), DoubleArray.filled(nNodes), CurveName.of("temp"), valuationDate, discountFactors, recoveryRates, refData);
            CreditRatesProvider   ratesProviderNew = ratesProvider.toImmutableCreditRatesProvider().toBuilder().creditCurves(ImmutableMap.of(Pair.of(legalEntityId, currency), LegalEntitySurvivalProbabilities.of(legalEntityId, IsdaCreditDiscountFactors.of(currency, valuationDate, creditCurve)))).build();

            System.Func <ResolvedCdsTrade, CdsQuote> quoteValueFunction = createQuoteValueFunction(ratesProviderNew, targetConvention, refData);
//JAVA TO C# CONVERTER TODO TASK: Most Java stream collectors are not converted by Java to C# Converter:
            ImmutableList <CdsQuote> result = trades.Select(c => quoteValueFunction(c)).collect(Collectors.collectingAndThen(Collectors.toList(), ImmutableList.copyOf));

            return(result);
        }
Example #18
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 #19
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 #20
0
 //-------------------------------------------------------------------------
 /// <summary>
 /// Creates an instance.
 /// </summary>
 /// <param name="legalEntityId">  the legal entity ID </param>
 /// <param name="survivalProbabilities">  the survival probabilities </param>
 /// <returns> the instance </returns>
 public static LegalEntitySurvivalProbabilities of(StandardId legalEntityId, CreditDiscountFactors survivalProbabilities)
 {
     return(new LegalEntitySurvivalProbabilities(legalEntityId, survivalProbabilities));
 }
Example #21
0
        //-------------------------------------------------------------------------
        // computes protection leg pv per unit notional
        private double protectionLeg(ResolvedCds cds, CreditDiscountFactors discountFactors, LegalEntitySurvivalProbabilities survivalProbabilities, LocalDate referenceDate, LocalDate effectiveStartDate, double recoveryRate)
        {
            double protectionFull = this.protectionFull(cds, discountFactors, survivalProbabilities, referenceDate, effectiveStartDate);

            return((1d - recoveryRate) * protectionFull);
        }
Example #22
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 #23
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);
        }
Example #24
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));
        }
Example #25
0
        private System.Func <double, double> getPriceFunction(int index, ResolvedCdsTrade cds, double flactionalSpread, double pointsUpfront, LocalDate valuationDate, NodalCurve creditCurve, CreditDiscountFactors discountFactors, RecoveryRates recoveryRates, ReferenceData refData)
        {
            ResolvedCds cdsProduct                 = cds.Product;
            Currency    currency                   = cdsProduct.Currency;
            StandardId  legalEntityId              = cdsProduct.LegalEntityId;
            Pair <StandardId, Currency>  pair      = Pair.of(legalEntityId, currency);
            ImmutableCreditRatesProvider ratesbase = ImmutableCreditRatesProvider.builder().valuationDate(valuationDate).discountCurves(ImmutableMap.of(currency, discountFactors)).recoveryRateCurves(ImmutableMap.of(legalEntityId, recoveryRates)).build();

            System.Func <double, double> func = (double?x) =>
            {
                NodalCurve tempCreditCurve         = creditCurve.withParameter(index, x.Value);
                ImmutableCreditRatesProvider rates = ratesbase.toBuilder().creditCurves(ImmutableMap.of(pair, LegalEntitySurvivalProbabilities.of(legalEntityId, IsdaCreditDiscountFactors.of(currency, valuationDate, tempCreditCurve)))).build();
                double price = TradePricer.price(cds, rates, flactionalSpread, PriceType.CLEAN, refData);
                return(price - pointsUpfront);
            };
            return(func);
        }
Example #26
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);
        }
Example #27
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 #28
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));
        }
Example #29
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);
        }
 private double[] getStandardQuoteForm(ResolvedCdsTrade calibrationCds, CdsQuote marketQuote, LocalDate valuationDate, CreditDiscountFactors discountFactors, RecoveryRates recoveryRates, bool computeJacobian, ReferenceData refData)
 {
     double[] res = new double[3];
     res[2] = 1d;
     if (marketQuote.QuoteConvention.Equals(CdsQuoteConvention.PAR_SPREAD))
     {
         res[0] = marketQuote.QuotedValue;
     }
     else if (marketQuote.QuoteConvention.Equals(CdsQuoteConvention.QUOTED_SPREAD))
     {
         double     qSpread                 = marketQuote.QuotedValue;
         CurveName  curveName               = CurveName.of("quoteConvertCurve");
         NodalCurve tempCreditCurve         = calibrate(ImmutableList.of(calibrationCds), DoubleArray.of(qSpread), DoubleArray.of(0d), curveName, valuationDate, discountFactors, recoveryRates, refData);
         Currency   currency                = calibrationCds.Product.Currency;
         StandardId legalEntityId           = calibrationCds.Product.LegalEntityId;
         ImmutableCreditRatesProvider rates = ImmutableCreditRatesProvider.builder().valuationDate(valuationDate).discountCurves(ImmutableMap.of(currency, discountFactors)).recoveryRateCurves(ImmutableMap.of(legalEntityId, recoveryRates)).creditCurves(ImmutableMap.of(Pair.of(legalEntityId, currency), LegalEntitySurvivalProbabilities.of(legalEntityId, IsdaCreditDiscountFactors.of(currency, valuationDate, tempCreditCurve)))).build();
         res[0] = calibrationCds.Product.FixedRate;
         res[1] = tradePricer.price(calibrationCds, rates, PriceType.CLEAN, refData);
         if (computeJacobian)
         {
             CurrencyParameterSensitivities pufSensi = rates.parameterSensitivity(tradePricer.priceSensitivity(calibrationCds, rates, refData));
             CurrencyParameterSensitivities spSensi  = rates.parameterSensitivity(tradePricer.parSpreadSensitivity(calibrationCds, rates, refData));
             res[2] = spSensi.getSensitivity(curveName, currency).Sensitivity.get(0) / pufSensi.getSensitivity(curveName, currency).Sensitivity.get(0);
         }
     }
     else if (marketQuote.QuoteConvention.Equals(CdsQuoteConvention.POINTS_UPFRONT))
     {
         res[0] = calibrationCds.Product.FixedRate;
         res[1] = marketQuote.QuotedValue;
     }
     else
     {
         throw new System.ArgumentException("Unknown CDSQuoteConvention type " + marketQuote.GetType());
     }
     return(res);
 }