public ImmutableLegalEntityDiscountingProvider toImmutableLegalEntityDiscountingProvider() { // repo curves IDictionary <Pair <RepoGroup, Currency>, DiscountFactors> repoCurves = new Dictionary <Pair <RepoGroup, Currency>, DiscountFactors>(); foreach (Pair <RepoGroup, Currency> pair in lookup.RepoCurves.Keys) { CurveId curveId = lookup.RepoCurves.get(pair); if (marketData.containsValue(curveId)) { Curve curve = marketData.getValue(curveId); repoCurves[pair] = DiscountFactors.of(pair.Second, ValuationDate, curve); } } // issuer curves IDictionary <Pair <LegalEntityGroup, Currency>, DiscountFactors> issuerCurves = new Dictionary <Pair <LegalEntityGroup, Currency>, DiscountFactors>(); foreach (Pair <LegalEntityGroup, Currency> pair in lookup.IssuerCurves.Keys) { CurveId curveId = lookup.IssuerCurves.get(pair); if (marketData.containsValue(curveId)) { Curve curve = marketData.getValue(curveId); issuerCurves[pair] = DiscountFactors.of(pair.Second, ValuationDate, curve); } } // build result return(ImmutableLegalEntityDiscountingProvider.builder().valuationDate(ValuationDate).repoCurveSecurityGroups(lookup.RepoCurveSecurityGroups).repoCurveGroups(lookup.RepoCurveGroups).repoCurves(repoCurves).issuerCurveGroups(lookup.IssuerCurveGroups).issuerCurves(issuerCurves).build()); }
// modified sensitivity function - CombinedCurve involved private CurrencyParameterSensitivities sensiCombinedFnBond(ImmutableLegalEntityDiscountingProvider provider) { CurrencyParameterSensitivities sensi = CurrencyParameterSensitivities.empty(); double sum = sumCombine(provider); // repo curves ImmutableMap <Pair <RepoGroup, Currency>, DiscountFactors> mapCurrency = provider.RepoCurves; foreach (KeyValuePair <Pair <RepoGroup, Currency>, DiscountFactors> entry in mapCurrency.entrySet()) { CombinedCurve curveComb = (CombinedCurve)getCurve(entry.Value); InterpolatedNodalCurve baseCurveInt = checkInterpolated(curveComb.BaseCurve); InterpolatedNodalCurve spreadCurveInt = checkInterpolated(curveComb.SpreadCurve); sensi = sensi.combinedWith(CurrencyParameterSensitivity.of(baseCurveInt.Name, USD, DoubleArray.of(baseCurveInt.ParameterCount, i => 2d * sum * baseCurveInt.XValues.get(i)))); sensi = sensi.combinedWith(CurrencyParameterSensitivity.of(spreadCurveInt.Name, USD, DoubleArray.of(spreadCurveInt.ParameterCount, i => 2d * sum * spreadCurveInt.XValues.get(i)))); } // issuer curves ImmutableMap <Pair <LegalEntityGroup, Currency>, DiscountFactors> mapIndex = provider.IssuerCurves; foreach (KeyValuePair <Pair <LegalEntityGroup, Currency>, DiscountFactors> entry in mapIndex.entrySet()) { CombinedCurve curveComb = (CombinedCurve)getCurve(entry.Value); InterpolatedNodalCurve baseCurveInt = checkInterpolated(curveComb.BaseCurve); InterpolatedNodalCurve spreadCurveInt = checkInterpolated(curveComb.SpreadCurve); sensi = sensi.combinedWith(CurrencyParameterSensitivity.of(baseCurveInt.Name, USD, DoubleArray.of(baseCurveInt.ParameterCount, i => 2d * sum * baseCurveInt.XValues.get(i)))); sensi = sensi.combinedWith(CurrencyParameterSensitivity.of(spreadCurveInt.Name, USD, DoubleArray.of(spreadCurveInt.ParameterCount, i => 2d * sum * spreadCurveInt.XValues.get(i)))); } return(sensi); }
static BondFuturesJpyEnd2EndTest() { for (int i = 0; i < NB_UND_BONDS; ++i) { PeriodicSchedule periodSchedule = PeriodicSchedule.of(START_DATE[i], MATURITY_DATE[i], Frequency.P6M, BUSINESS_ADJUST, StubConvention.SHORT_INITIAL, false); FixedCouponBond product = FixedCouponBond.builder().securityId(SecurityId.of(BOND_SECURITY_ID[i])).dayCount(DAY_COUNT).fixedRate(UND_RATES[i] * ONE_PERCENT).legalEntityId(ISSUER_ID).currency(JPY).notional(NOTIONAL).accrualSchedule(periodSchedule).settlementDateOffset(SETTLEMENT_DAYS).yieldConvention(YIELD_CONVENTION).build(); UND_BOND[i] = product; } UND_BOND_SEP = new FixedCouponBond[NB_UND_BONDS - 2]; Array.Copy(UND_BOND, 2, UND_BOND_SEP, 0, NB_UND_BONDS - 2); UND_BOND_JUN = new FixedCouponBond[NB_UND_BONDS - 1]; Array.Copy(UND_BOND, 1, UND_BOND_JUN, 0, NB_UND_BONDS - 1); double[] timeIssuer = new double[] { 0.25136612021857924, 0.4972677595628415, 1.0139980537465378, 2.013998053746538, 2.857833670184894, 3.857833670184894, 4.860655737704918, 5.857833670184894, 7.104409012650647, 7.857833670184894, 8.857923497267759, 9.863313122239688, 14.857833670184894, 19.857833670184895, 29.857833670184895, 39.11262819073284 }; double[] rateIssuer = new double[] { -0.0013117084834668065, -0.0010851901424876163, -0.0020906775838723216, -0.0022137102045172784, -0.0022695678374162888, -0.0023424568490920798, -0.0021603059162879916, -0.0021667343131861225, -0.0018285921969274823, -0.001355094018965514, -6.763044056712535E-4, 1.9555294306801752E-4, 0.003944125562941363, 0.008054233458390252, 0.012276105941434846, 0.013537766297065804 }; double[] timeRepo = new double[] { 0.00273224043715847, 0.01912568306010929, 0.040983606557377046, 0.05737704918032787, 0.07923497267759563, 0.2459016393442623, 0.4972677595628415, 1.0002994236095515 }; double[] rateRepo = new double[] { 2.599662058772748E-4, -8.403529976927196E-4, -0.0010105103936934236, -0.0011506617573950931, -0.0012708071334455143, -0.00146106683851595, -0.0014710815100096722, -0.001481096281798276 }; CurveMetadata metaIssuer = Curves.zeroRates(ISSUER_CURVE_NAME, ACT_ACT_ISDA); InterpolatedNodalCurve curveIssuer = InterpolatedNodalCurve.of(metaIssuer, DoubleArray.copyOf(timeIssuer), DoubleArray.copyOf(rateIssuer), INTERPOLATOR); DiscountFactors dscIssuer = ZeroRateDiscountFactors.of(JPY, VALUATION, curveIssuer); CurveMetadata metaRepo = Curves.zeroRates(REPO_CURVE_NAME, ACT_ACT_ISDA); InterpolatedNodalCurve curve = InterpolatedNodalCurve.of(metaRepo, DoubleArray.copyOf(timeRepo), DoubleArray.copyOf(rateRepo), INTERPOLATOR); DiscountFactors dscRepo = ZeroRateDiscountFactors.of(JPY, VALUATION, curve); LED_PROVIDER = ImmutableLegalEntityDiscountingProvider.builder().issuerCurves(ImmutableMap.of(Pair.of(GROUP_ISSUER, JPY), dscIssuer)).issuerCurveGroups(ImmutableMap.of(ISSUER_ID, GROUP_ISSUER)).repoCurves(ImmutableMap.of(Pair.of(GROUP_REPO, JPY), dscRepo)).repoCurveGroups(ImmutableMap.of(ISSUER_ID, GROUP_REPO)).build(); }
//------------------------------------------------------------------------- /// <summary> /// Computes the first order sensitivities of a function of a LegalEntityDiscountingProvider 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 LegalEntityDiscountingProvider. /// /// </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(LegalEntityDiscountingProvider provider, System.Func <ImmutableLegalEntityDiscountingProvider, CurrencyAmount> valueFn) { ImmutableLegalEntityDiscountingProvider immProv = provider.toImmutableLegalEntityDiscountingProvider(); CurrencyAmount valueInit = valueFn(immProv); CurrencyParameterSensitivities discounting = sensitivity(immProv, valueFn, ImmutableLegalEntityDiscountingProvider.meta().repoCurves(), valueInit); CurrencyParameterSensitivities forward = sensitivity(immProv, valueFn, ImmutableLegalEntityDiscountingProvider.meta().issuerCurves(), valueInit); return(discounting.combinedWith(forward)); }
private ImmutableLegalEntityDiscountingProvider replaceRepoCurve(ImmutableLegalEntityDiscountingProvider ratesProvider, Pair <RepoGroup, Currency> rgCcy, DiscountFactors discountFactors) { IDictionary <Pair <RepoGroup, Currency>, DiscountFactors> curves = new Dictionary <Pair <RepoGroup, Currency>, DiscountFactors>(); //JAVA TO C# CONVERTER TODO TASK: There is no .NET Dictionary equivalent to the Java 'putAll' method: curves.putAll(ratesProvider.RepoCurves); curves[rgCcy] = discountFactors; return(ratesProvider.toBuilder().repoCurves(curves).build()); }
public static ImmutableLegalEntityDiscountingProvider multiBondCombined(LocalDate valDate) { ImmutableMap <Pair <RepoGroup, Currency>, DiscountFactors> repoCurves = ImmutableMap.of(Pair.of(US_REPO_GROUP, USD), DiscountFactors.of(USD, valDate, CombinedCurve.of(USD_L3_BASE, US_REPO_CURVE))); ImmutableMap <Pair <LegalEntityGroup, Currency>, DiscountFactors> issuerCurves = ImmutableMap.of(Pair.of(US_ISSUER_1_GROUP, USD), DiscountFactors.of(USD, valDate, CombinedCurve.of(USD_L3_BASE, US_ISSUER_CURVE_1)), Pair.of(US_ISSUER_2_GROUP, USD), DiscountFactors.of(USD, valDate, CombinedCurve.of(USD_L3_BASE, US_ISSUER_CURVE_2))); ImmutableMap <LegalEntityId, RepoGroup> repoGroups = ImmutableMap.of(US_ISSUER_1_ID, US_REPO_GROUP, US_ISSUER_2_ID, US_REPO_GROUP, US_ISSUER_3_ID, US_REPO_GROUP); ImmutableMap <LegalEntityId, LegalEntityGroup> legalEntityGroups = ImmutableMap.of(US_ISSUER_1_ID, US_ISSUER_1_GROUP, US_ISSUER_2_ID, US_ISSUER_2_GROUP, US_ISSUER_3_ID, US_ISSUER_2_GROUP); return(ImmutableLegalEntityDiscountingProvider.builder().valuationDate(valDate).repoCurves(repoCurves).repoCurveGroups(repoGroups).issuerCurves(issuerCurves).issuerCurveGroups(legalEntityGroups).build()); }
private CrossGammaParameterSensitivity computeGammaForCurve(CurveName curveName, Curve curve, Currency sensitivityCurrency, System.Func <Curve, ImmutableLegalEntityDiscountingProvider> ratesProviderFn, System.Func <ImmutableLegalEntityDiscountingProvider, CurrencyParameterSensitivities> sensitivitiesFn) { System.Func <DoubleArray, DoubleArray> function = (DoubleArray t) => { Curve newCurve = curve.withPerturbation((i, v, m) => t.get(i)); ImmutableLegalEntityDiscountingProvider newRates = ratesProviderFn(newCurve); CurrencyParameterSensitivities sensiMulti = sensitivitiesFn(newRates); return(sensiMulti.getSensitivity(curveName, sensitivityCurrency).Sensitivity); }; int nParams = curve.ParameterCount; DoubleMatrix sensi = fd.differentiate(function).apply(DoubleArray.of(nParams, n => curve.getParameter(n))); IList <ParameterMetadata> metadata = IntStream.range(0, nParams).mapToObj(i => curve.getParameterMetadata(i)).collect(toImmutableList()); return(CrossGammaParameterSensitivity.of(curveName, metadata, sensitivityCurrency, sensi)); }
private double sum(ImmutableLegalEntityDiscountingProvider provider) { double result = 0d; // repo curves ImmutableMap <Pair <RepoGroup, Currency>, DiscountFactors> mapIndex = provider.RepoCurves; foreach (KeyValuePair <Pair <RepoGroup, Currency>, DiscountFactors> entry in mapIndex.entrySet()) { InterpolatedNodalCurve curve = (InterpolatedNodalCurve)getCurve(entry.Value); result += sumSingle(curve); } // issuer curves ImmutableMap <Pair <LegalEntityGroup, Currency>, DiscountFactors> mapCurrency = provider.IssuerCurves; foreach (KeyValuePair <Pair <LegalEntityGroup, Currency>, DiscountFactors> entry in mapCurrency.entrySet()) { InterpolatedNodalCurve curve = (InterpolatedNodalCurve)getCurve(entry.Value); result += sumSingle(curve); } return(result); }
// private function for testing. Returns the sum of rates multiplied by time private CurrencyAmount fn(ImmutableLegalEntityDiscountingProvider provider) { double result = 0.0; // issuer curve ImmutableMap <Pair <LegalEntityGroup, Currency>, DiscountFactors> mapLegal = provider.metaBean().issuerCurves().get(provider); foreach (KeyValuePair <Pair <LegalEntityGroup, Currency>, DiscountFactors> entry in mapLegal.entrySet()) { InterpolatedNodalCurve curveInt = checkInterpolated(checkDiscountFactors(entry.Value)); result += sumProduct(curveInt); } // repo curve ImmutableMap <Pair <RepoGroup, Currency>, DiscountFactors> mapRepo = provider.metaBean().repoCurves().get(provider); foreach (KeyValuePair <Pair <RepoGroup, Currency>, DiscountFactors> entry in mapRepo.entrySet()) { InterpolatedNodalCurve curveInt = checkInterpolated(checkDiscountFactors(entry.Value)); result += sumProduct(curveInt); } return(CurrencyAmount.of(USD, result)); }
private CurrencyParameterSensitivities sensitivity <T>(ImmutableLegalEntityDiscountingProvider provider, System.Func <ImmutableLegalEntityDiscountingProvider, CurrencyAmount> valueFn, MetaProperty <ImmutableMap <Pair <T, Currency>, DiscountFactors> > metaProperty, CurrencyAmount valueInit) { ImmutableMap <Pair <T, Currency>, DiscountFactors> baseCurves = metaProperty.get(provider); CurrencyParameterSensitivities result = CurrencyParameterSensitivities.empty(); foreach (Pair <T, Currency> key in baseCurves.Keys) { DiscountFactors discountFactors = baseCurves.get(key); 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 <Pair <T, Currency>, DiscountFactors> mapBumped = new Dictionary <Pair <T, Currency>, DiscountFactors>(baseCurves); mapBumped[key] = createDiscountFactors(discountFactors, dscBumped); ImmutableLegalEntityDiscountingProvider 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); }
//------------------------------------------------------------------------- private CurrencyParameterSensitivities sensiFnBond(ImmutableLegalEntityDiscountingProvider provider) { CurrencyParameterSensitivities sensi = CurrencyParameterSensitivities.empty(); double sum = this.sum(provider); // repo curves ImmutableMap <Pair <RepoGroup, Currency>, DiscountFactors> mapRepoCurves = provider.RepoCurves; foreach (KeyValuePair <Pair <RepoGroup, Currency>, DiscountFactors> entry in mapRepoCurves.entrySet()) { DiscountFactors discountFactors = entry.Value; InterpolatedNodalCurve curve = (InterpolatedNodalCurve)getCurve(discountFactors); sensi = sensi.combinedWith(CurrencyParameterSensitivity.of(curve.Name, discountFactors.Currency, DoubleArray.of(discountFactors.ParameterCount, i => 2d * curve.XValues.get(i) * sum))); } // issuer curves ImmutableMap <Pair <LegalEntityGroup, Currency>, DiscountFactors> mapIssuerCurves = provider.IssuerCurves; foreach (KeyValuePair <Pair <LegalEntityGroup, Currency>, DiscountFactors> entry in mapIssuerCurves.entrySet()) { DiscountFactors discountFactors = entry.Value; InterpolatedNodalCurve curve = (InterpolatedNodalCurve)getCurve(discountFactors); sensi = sensi.combinedWith(CurrencyParameterSensitivity.of(curve.Name, discountFactors.Currency, DoubleArray.of(discountFactors.ParameterCount, i => 2d * curve.XValues.get(i) * sum))); } return(sensi); }
//------------------------------------------------------------------------- /// <summary> /// Computes intra-curve cross gamma for bond curves by applying finite difference method to curve delta. /// <para> /// This computes the intra-curve cross gamma, i.e., the second order sensitivities to individual curves. /// Thus the sensitivity of a curve delta to another curve is not produced. /// </para> /// <para> /// The underlying instruments must be single-currency, i.e., the curve currency must be the same as the sensitivity currency. /// /// </para> /// </summary> /// <param name="ratesProvider"> the rates provider </param> /// <param name="sensitivitiesFn"> the sensitivity function </param> /// <returns> the cross gamma </returns> public CrossGammaParameterSensitivities calculateCrossGammaIntraCurve(LegalEntityDiscountingProvider ratesProvider, System.Func <ImmutableLegalEntityDiscountingProvider, CurrencyParameterSensitivities> sensitivitiesFn) { LocalDate valuationDate = ratesProvider.ValuationDate; ImmutableLegalEntityDiscountingProvider immProv = ratesProvider.toImmutableLegalEntityDiscountingProvider(); CurrencyParameterSensitivities baseDelta = sensitivitiesFn(immProv); // used to check target sensitivity exits CrossGammaParameterSensitivities result = CrossGammaParameterSensitivities.empty(); // issuer curve foreach (KeyValuePair <Pair <LegalEntityGroup, Currency>, DiscountFactors> entry in immProv.IssuerCurves.entrySet()) { Pair <LegalEntityGroup, Currency> legCcy = entry.Key; Currency currency = legCcy.Second; Curve curve = getCurve(entry.Value); CurveName curveName = curve.Name; if (baseDelta.findSensitivity(curveName, currency).Present) { CrossGammaParameterSensitivity gammaSingle = computeGammaForCurve(curveName, curve, currency, c => replaceIssuerCurve(immProv, legCcy, DiscountFactors.of(currency, valuationDate, c)), sensitivitiesFn); result = result.combinedWith(gammaSingle); } else { ImmutableList <Curve> curves = curve.split(); int nCurves = curves.size(); if (nCurves > 1) { for (int i = 0; i < nCurves; ++i) { int currentIndex = i; Curve underlyingCurve = curves.get(currentIndex); CurveName underlyingCurveName = underlyingCurve.Name; if (baseDelta.findSensitivity(underlyingCurveName, currency).Present) { CrossGammaParameterSensitivity gammaSingle = computeGammaForCurve(underlyingCurveName, underlyingCurve, currency, c => replaceIssuerCurve(immProv, legCcy, DiscountFactors.of(currency, valuationDate, curve.withUnderlyingCurve(currentIndex, c))), sensitivitiesFn); result = result.combinedWith(gammaSingle); } } } } } // repo curve foreach (KeyValuePair <Pair <RepoGroup, Currency>, DiscountFactors> entry in immProv.RepoCurves.entrySet()) { Pair <RepoGroup, Currency> rgCcy = entry.Key; Currency currency = rgCcy.Second; Curve curve = getCurve(entry.Value); CurveName curveName = curve.Name; if (baseDelta.findSensitivity(curveName, currency).Present) { CrossGammaParameterSensitivity gammaSingle = computeGammaForCurve(curveName, curve, currency, c => replaceRepoCurve(immProv, rgCcy, DiscountFactors.of(currency, valuationDate, c)), sensitivitiesFn); result = result.combinedWith(gammaSingle); } else { ImmutableList <Curve> curves = curve.split(); int nCurves = curves.size(); if (nCurves > 1) { for (int i = 0; i < nCurves; ++i) { int currentIndex = i; Curve underlyingCurve = curves.get(currentIndex); CurveName underlyingCurveName = underlyingCurve.Name; if (baseDelta.findSensitivity(underlyingCurveName, rgCcy.Second).Present) { CrossGammaParameterSensitivity gammaSingle = computeGammaForCurve(underlyingCurveName, underlyingCurve, currency, c => replaceRepoCurve(immProv, rgCcy, DiscountFactors.of(currency, valuationDate, curve.withUnderlyingCurve(currentIndex, c))), sensitivitiesFn); result = result.combinedWith(gammaSingle); } } } } } return(result); }