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); }
//------------------------------------------------------------------------- /// <summary> /// Computes the first order sensitivities of a function of a {@code CreditRatesProvider} to a double by finite difference. /// <para> /// The finite difference is computed by forward type. /// The function should return a value in the same currency for any rates provider of {@code CreditRatesProvider}. /// /// </para> /// </summary> /// <param name="provider"> the rates provider </param> /// <param name="valueFn"> the function from a rate provider to a currency amount for which the sensitivity should be computed </param> /// <returns> the curve sensitivity </returns> public virtual CurrencyParameterSensitivities sensitivity(CreditRatesProvider provider, System.Func <ImmutableCreditRatesProvider, CurrencyAmount> valueFn) { ImmutableCreditRatesProvider immutableProvider = provider.toImmutableCreditRatesProvider(); CurrencyAmount valueInit = valueFn(immutableProvider); CurrencyParameterSensitivities discounting = sensitivityDiscountCurve(immutableProvider, valueFn, ImmutableCreditRatesProvider.meta().discountCurves(), valueInit); CurrencyParameterSensitivities credit = sensitivityCreidtCurve(immutableProvider, valueFn, ImmutableCreditRatesProvider.meta().creditCurves(), valueInit); return(discounting.combinedWith(credit)); }
//------------------------------------------------------------------------- /// <summary> /// Creates credit rates provider with valuation date specified. /// </summary> /// <param name="valuationDate"> the valuation date </param> /// <returns> the rates provider </returns> public static ImmutableCreditRatesProvider createCreditRatesProvider(LocalDate valuationDate) { IsdaCreditDiscountFactors ycUsd = IsdaCreditDiscountFactors.of(USD, valuationDate, NODAL_YC_USD); IsdaCreditDiscountFactors ycJpy = IsdaCreditDiscountFactors.of(JPY, valuationDate, NODAL_YC_JPY); IsdaCreditDiscountFactors ccUs = IsdaCreditDiscountFactors.of(USD, valuationDate, NODAL_CC_US); IsdaCreditDiscountFactors ccJp = IsdaCreditDiscountFactors.of(JPY, valuationDate, NODAL_CC_JP); ConstantRecoveryRates rrUs = ConstantRecoveryRates.of(LEGAL_ENTITY_US, valuationDate, RECOVERY_RATE_US); ConstantRecoveryRates rrJp = ConstantRecoveryRates.of(LEGAL_ENTITY_JP, valuationDate, RECOVERY_RATE_JP); return(ImmutableCreditRatesProvider.builder().valuationDate(valuationDate).creditCurves(ImmutableMap.of(Pair.of(LEGAL_ENTITY_US, USD), LegalEntitySurvivalProbabilities.of(LEGAL_ENTITY_US, ccUs), Pair.of(LEGAL_ENTITY_JP, JPY), LegalEntitySurvivalProbabilities.of(LEGAL_ENTITY_JP, ccJp))).discountCurves(ImmutableMap.of(USD, ycUsd, JPY, ycJpy)).recoveryRateCurves(ImmutableMap.of(LEGAL_ENTITY_US, rrUs, LEGAL_ENTITY_JP, rrJp)).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()); }
// private function for testing. Returns the sum of rates multiplied by time private CurrencyAmount creditFunction(ImmutableCreditRatesProvider provider) { double result = 0.0; // credit curve ImmutableMap <Pair <StandardId, Currency>, LegalEntitySurvivalProbabilities> mapCredit = provider.metaBean().creditCurves().get(provider); foreach (KeyValuePair <Pair <StandardId, Currency>, LegalEntitySurvivalProbabilities> entry in mapCredit.entrySet()) { InterpolatedNodalCurve curveInt = checkInterpolated(checkDiscountFactors(entry.Value.SurvivalProbabilities.toDiscountFactors())); result += sumProduct(curveInt); } // repo curve ImmutableMap <Currency, CreditDiscountFactors> mapDiscount = provider.metaBean().discountCurves().get(provider); foreach (KeyValuePair <Currency, CreditDiscountFactors> entry in mapDiscount.entrySet()) { InterpolatedNodalCurve curveInt = checkInterpolated(checkDiscountFactors(entry.Value.toDiscountFactors())); result += sumProduct(curveInt); } return(CurrencyAmount.of(USD, result)); }