/** * Restricted copy constructor. * @param beanToCopy the bean to copy from, not null */ private Builder(RatesCurveGroupEntry beanToCopy) { this.curveName = beanToCopy.getCurveName(); this.discountCurrencies = beanToCopy.getDiscountCurrencies(); this.indices = beanToCopy.getIndices(); }
@Override public RatesCurveGroupEntry build() { return new RatesCurveGroupEntry( curveName, discountCurrencies, indices); }
private RatesCurveGroupDefinitionBuilder mergeEntry(RatesCurveGroupEntry newEntry) { CurveName curveName = newEntry.getCurveName(); RatesCurveGroupEntry existingEntry = entries.get(curveName); RatesCurveGroupEntry entry = existingEntry == null ? newEntry : existingEntry.merge(newEntry); entries.put(curveName, entry); return this; }
/** * Finds the forward curve name for the specified index. * <p> * If the curve name is not found, optional empty is returned. * * @param forwardIndex the index to find a forward curve name for * @return the curve name */ public Optional<CurveName> findForwardCurveName(Index forwardIndex) { return entries.stream() .filter(entry -> entry.getIndices().contains(forwardIndex)) .findFirst() .map(entry -> entry.getCurveName()); }
public void test_builder() { RatesCurveGroupEntry test = RatesCurveGroupEntry.builder() .curveName(CURVE_NAME1) .discountCurrencies(GBP) .indices(GBP_LIBOR_1M, GBP_LIBOR_3M, GBP_SONIA) .build(); assertEquals(test.getCurveName(), CURVE_NAME1); assertEquals(test.getDiscountCurrencies(), ImmutableSet.of(GBP)); assertEquals(test.getIndices(), ImmutableSet.of(GBP_LIBOR_1M, GBP_LIBOR_3M, GBP_SONIA)); assertEquals(test.getIndices(IborIndex.class), ImmutableSet.of(GBP_LIBOR_1M, GBP_LIBOR_3M)); assertEquals(test.getIndices(OvernightIndex.class), ImmutableSet.of(GBP_SONIA)); assertEquals(test.getIndices(PriceIndex.class), ImmutableSet.of()); }
/** * Obtains a generator from an existing provider and definition. * * @param knownProvider the underlying known provider * @param groupDefn the curve group definition * @param refData the reference data to use * @return the generator */ public static ImmutableRatesProviderGenerator of( ImmutableRatesProvider knownProvider, RatesCurveGroupDefinition groupDefn, ReferenceData refData) { List<CurveDefinition> curveDefns = new ArrayList<>(); List<CurveMetadata> curveMetadata = new ArrayList<>(); SetMultimap<CurveName, Currency> discountNames = HashMultimap.create(); SetMultimap<CurveName, Index> indexNames = HashMultimap.create(); for (CurveDefinition curveDefn : groupDefn.getCurveDefinitions()) { curveDefns.add(curveDefn); curveMetadata.add(curveDefn.metadata(knownProvider.getValuationDate(), refData)); CurveName curveName = curveDefn.getName(); // A curve group is guaranteed to include an entry for every definition RatesCurveGroupEntry entry = groupDefn.findEntry(curveName).get(); Set<Currency> ccy = entry.getDiscountCurrencies(); discountNames.putAll(curveName, ccy); indexNames.putAll(curveName, entry.getIndices()); } return new ImmutableRatesProviderGenerator( knownProvider, curveDefns, curveMetadata, discountNames, indexNames); }
/** * Creates a curve group entry for a curve from a list of keys from the same curve group. * * @param curveName the name of the curve * @param gars the group-reference pairs * @return a curve group entry built from the data in the IDs */ private static RatesCurveGroupEntry curveGroupEntry(CurveName curveName, List<GroupAndReference> gars) { Set<Currency> currencies = new LinkedHashSet<>(); Set<Index> indices = new LinkedHashSet<>(); for (GroupAndReference gar : gars) { if (gar.currency != null) { currencies.add(gar.currency); } else { indices.add(gar.index); } } return RatesCurveGroupEntry.builder() .curveName(curveName) .discountCurrencies(currencies) .indices(indices) .build(); }
/** * Finds the discount curve name for the specified currency. * <p> * If the curve name is not found, optional empty is returned. * * @param discountCurrency the currency to find a discount curve name for * @return the curve name */ public Optional<CurveName> findDiscountCurveName(Currency discountCurrency) { return entries.stream() .filter(entry -> entry.getDiscountCurrencies().contains(discountCurrency)) .findFirst() .map(entry -> entry.getCurveName()); }
/** * Returns a copy of this object containing the specified curve definitions. * <p> * Curves are ignored if there is no entry in this definition with the same curve name. * * @param curveDefinitions curve definitions * @return a copy of this object containing the specified curve definitions */ public RatesCurveGroupDefinition withCurveDefinitions(List<CurveDefinition> curveDefinitions) { Set<CurveName> curveNames = entries.stream().map(entry -> entry.getCurveName()).collect(toSet()); List<CurveDefinition> filteredDefinitions = curveDefinitions.stream().filter(def -> curveNames.contains(def.getName())).collect(toImmutableList()); return new RatesCurveGroupDefinition( name, entries, filteredDefinitions, seasonalityDefinitions, computeJacobian, computePvSensitivityToMarketQuote); }
/** * Finds the forward curve names for the specified floating rate name. * <p> * If the curve name is not found, optional empty is returned. * * @param forwardName the floating rate name to find a forward curve name for * @return the set of curve names */ public ImmutableSet<CurveName> findForwardCurveNames(FloatingRateName forwardName) { ImmutableSet.Builder<CurveName> result = ImmutableSet.builder(); FloatingRateName normalized = forwardName.normalized(); for (RatesCurveGroupEntry entry : entries) { for (Index index : entry.getIndices()) { if (index instanceof FloatingRateIndex) { FloatingRateName frName = ((FloatingRateIndex) index).getFloatingRateName(); if (frName.equals(normalized)) { result.add(entry.getCurveName()); break; } } } } return result.build(); }
List<Currency> ccyRequired = new ArrayList<>(); for (RatesCurveGroupEntry entry : group.getEntries()) { indicesRequired.addAll(entry.getIndices()); ccyRequired.addAll(entry.getDiscountCurrencies());
/** * Merges the specified entry with this entry, returning a new entry. * <p> * The two entries must have the same curve name. * * @param newEntry the new entry * @return the merged entry */ RatesCurveGroupEntry merge(RatesCurveGroupEntry newEntry) { if (!curveName.equals(newEntry.curveName)) { throw new IllegalArgumentException( Messages.format( "A CurveGroupEntry can only be merged with an entry with the same curve name. name: {}, other name: {}", curveName, newEntry.curveName)); } return RatesCurveGroupEntry.builder() .curveName(curveName) .discountCurrencies(Sets.union(discountCurrencies, newEntry.discountCurrencies)) .indices(Sets.union(indices, newEntry.indices)) .build(); }
/** * Returns a copy of this object containing the specified seasonality definitions. * <p> * Seasonality definitions are ignored if there is no entry in this definition with the same curve name. * * @param seasonalityDefinitions seasonality definitions * @return a copy of this object containing the specified seasonality definitions */ public RatesCurveGroupDefinition withSeasonalityDefinitions(Map<CurveName, SeasonalityDefinition> seasonalityDefinitions) { Set<CurveName> curveNames = entries.stream().map(entry -> entry.getCurveName()).collect(toSet()); Map<CurveName, SeasonalityDefinition> filteredDefinitions = MapStream.of(seasonalityDefinitions) .filterKeys(cn -> curveNames.contains(cn)).toMap(); return new RatesCurveGroupDefinition( name, entries, curveDefinitions, filteredDefinitions, computeJacobian, computePvSensitivityToMarketQuote); }
@Override protected Object propertyGet(Bean bean, String propertyName, boolean quiet) { switch (propertyName.hashCode()) { case 771153946: // curveName return ((RatesCurveGroupEntry) bean).getCurveName(); case -538086256: // discountCurrencies return ((RatesCurveGroupEntry) bean).getDiscountCurrencies(); case 1943391143: // indices return ((RatesCurveGroupEntry) bean).getIndices(); } return super.propertyGet(bean, propertyName, quiet); }
ImmutableList.Builder<CurveDefinition> boundCurveDefinitions = ImmutableList.builder(); for (RatesCurveGroupEntry entry : entries) { CurveName name = entry.getCurveName(); CurveDefinition curveDef = curveDefinitionsByName.get(name); Set<Index> indices = entry.getIndices(); boolean containsPriceIndex = indices.stream().anyMatch(i -> i instanceof PriceIndex); if (containsPriceIndex) {
/** * Adds a curve to the curve group definition which is used to provide discount rates and forward rates. * <p> * A curve added with this method cannot be calibrated by the market data system as it does not include * a curve definition. It is intended to be used with curves which are supplied by the user. * * @param curveName the name of the curve * @param currency the currency for which the curve provides discount rates * @param index the index for which the curve provides forward rates * @param otherIndices the additional indices for which the curve provides forward rates * @return this builder */ public RatesCurveGroupDefinitionBuilder addCurve( CurveName curveName, Currency currency, RateIndex index, RateIndex... otherIndices) { RatesCurveGroupEntry entry = RatesCurveGroupEntry.builder() .curveName(curveName) .discountCurrencies(ImmutableSet.of(currency)) .indices(indices(index, otherIndices)) .build(); return mergeEntry(entry); }
/** * Package-private constructor used by the builder. * * @param name the name of the curve group * @param entries details of the curves in the group * @param curveDefinitions definitions which specify how the curves are calibrated */ @ImmutableConstructor RatesCurveGroupDefinition( CurveGroupName name, Collection<RatesCurveGroupEntry> entries, Collection<? extends CurveDefinition> curveDefinitions, Map<CurveName, SeasonalityDefinition> seasonalityDefinitions, boolean computeJacobian, boolean computePvSensitivityToMarketQuote) { this.name = ArgChecker.notNull(name, "name"); this.entries = ImmutableList.copyOf(entries); this.curveDefinitions = ImmutableList.copyOf(curveDefinitions); this.entriesByName = entries.stream().collect(toImmutableMap(entry -> entry.getCurveName(), entry -> entry)); this.curveDefinitionsByName = curveDefinitions.stream().collect(toImmutableMap(def -> def.getName(), def -> def)); this.computeJacobian = computeJacobian; this.computePvSensitivityToMarketQuote = computePvSensitivityToMarketQuote; this.seasonalityDefinitions = ImmutableMap.copyOf(seasonalityDefinitions); validate(); }
RatesCurveGroupEntry thisEntry = this.entriesByName.get(otherEntry.getCurveName()); if (thisEntry == null) { combinedEntries.put(otherEntry.getCurveName(), otherEntry); } else { combinedEntries.put(otherEntry.getCurveName(), thisEntry.merge(otherEntry));
private static void writeCurveGroupDefinition(CsvOutput csv, RatesCurveGroupDefinition group) { String groupName = group.getName().getName(); for (RatesCurveGroupEntry entry : group.getEntries()) { for (Currency currency : entry.getDiscountCurrencies()) { csv.writeLine( ImmutableList.of(groupName, DISCOUNT, currency.toString(), entry.getCurveName().getName())); } for (Index index : entry.getIndices()) { csv.writeLine( ImmutableList.of(groupName, FORWARD, index.toString(), entry.getCurveName().getName())); } } }
public void test_loadCurveGroupDefinition() { List<RatesCurveGroupDefinition> defns = RatesCurveGroupDefinitionCsvLoader.loadCurveGroupDefinitions(ResourceLocator.of(GROUPS_1)); assertEquals(defns.size(), 1); RatesCurveGroupDefinition defn = defns.get(0); assertEquals(defn.getEntries().get(0), RatesCurveGroupEntry.builder() .curveName(CurveName.of("USD-Disc")) .discountCurrencies(USD) .build()); assertEquals(defn.getEntries().get(1), RatesCurveGroupEntry.builder() .curveName(CurveName.of("USD-3ML")) .indices(USD_LIBOR_3M) .build()); }