com.opengamma.strata.pricer.curve.ImmutableRatesProviderGenerator Maven / Gradle / Ivy
/*
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.pricer.curve;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.SetMultimap;
import com.opengamma.strata.basics.ReferenceData;
import com.opengamma.strata.basics.currency.Currency;
import com.opengamma.strata.basics.index.Index;
import com.opengamma.strata.collect.ArgChecker;
import com.opengamma.strata.collect.array.DoubleArray;
import com.opengamma.strata.market.curve.Curve;
import com.opengamma.strata.market.curve.CurveDefinition;
import com.opengamma.strata.market.curve.CurveInfoType;
import com.opengamma.strata.market.curve.CurveMetadata;
import com.opengamma.strata.market.curve.CurveName;
import com.opengamma.strata.market.curve.JacobianCalibrationMatrix;
import com.opengamma.strata.market.curve.RatesCurveGroupDefinition;
import com.opengamma.strata.market.curve.RatesCurveGroupEntry;
import com.opengamma.strata.pricer.rate.ImmutableRatesProvider;
/**
* Generates a rates provider based on an existing provider.
*
* This takes a base {@link ImmutableRatesProvider} and list of curve definitions
* to generate a child provider.
*/
public final class ImmutableRatesProviderGenerator
implements RatesProviderGenerator {
/**
* The underlying known data.
* This includes curves and FX matrix.
*/
private final ImmutableRatesProvider knownProvider;
/**
* The curve definitions for the new curves to be generated.
*/
private final ImmutableList curveDefinitions;
/**
* The list of curve metadata associated with each definition.
* The size of this list must match the size of the definition list.
*/
private final ImmutableList curveMetadata;
/**
* The map between curve name and currencies for discounting.
* The map should contains all the curve in the definition list but may have more names
* than the curve definition list. Only the curves in the definitions list are created.
*/
private final ImmutableSetMultimap discountCurveNames;
/**
* The map between curve name and indices for forward rates and prices.
* The map should contains all the curve in the definition list but may have more names
* than the curve definition list. Only the curves in the definitions list are created
*/
private final ImmutableSetMultimap forwardCurveNames;
/**
* 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 curveDefns = new ArrayList<>();
List curveMetadata = new ArrayList<>();
SetMultimap discountNames = HashMultimap.create();
SetMultimap 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 ccy = entry.getDiscountCurrencies();
discountNames.putAll(curveName, ccy);
indexNames.putAll(curveName, entry.getIndices());
}
return new ImmutableRatesProviderGenerator(
knownProvider, curveDefns, curveMetadata, discountNames, indexNames);
}
/**
* Creates an instance.
*
* @param knownProvider the underlying known provider
* @param curveDefinitions the curve definitions
* @param curveMetadata the curve metadata
* @param discountCurveNames the map of discount curves
* @param forwardCurveNames the map of index forward curves
*/
private ImmutableRatesProviderGenerator(
ImmutableRatesProvider knownProvider,
List curveDefinitions,
List curveMetadata,
SetMultimap discountCurveNames,
SetMultimap forwardCurveNames) {
this.knownProvider = ArgChecker.notNull(knownProvider, "knownProvider");
this.curveDefinitions = ImmutableList.copyOf(ArgChecker.notNull(curveDefinitions, "curveDefinitions"));
this.curveMetadata = ImmutableList.copyOf(ArgChecker.notNull(curveMetadata, "curveMetadata"));
this.discountCurveNames = ImmutableSetMultimap.copyOf(ArgChecker.notNull(discountCurveNames, "discountCurveNames"));
this.forwardCurveNames = ImmutableSetMultimap.copyOf(ArgChecker.notNull(forwardCurveNames, "forwardCurveNames"));
}
//-------------------------------------------------------------------------
@Override
public ImmutableRatesProvider generate(
DoubleArray parameters,
Map jacobians,
Map sensitivitiesMarketQuote) {
// collect curves for child provider based on existing provider
Map discountCurves = new HashMap<>();
Map indexCurves = new HashMap<>();
discountCurves.putAll(knownProvider.getDiscountCurves());
indexCurves.putAll(knownProvider.getIndexCurves());
// generate curves from combined parameter array
int startIndex = 0;
for (int i = 0; i < curveDefinitions.size(); i++) {
CurveDefinition curveDefn = curveDefinitions.get(i);
CurveMetadata metadata = curveMetadata.get(i);
CurveName name = curveDefn.getName();
// extract parameters for the child curve
int paramCount = curveDefn.getParameterCount();
DoubleArray curveParams = parameters.subArray(startIndex, startIndex + paramCount);
startIndex += paramCount;
// create the child curve
CurveMetadata childMetadata = childMetadata(metadata, curveDefn, jacobians, sensitivitiesMarketQuote);
Curve curve = curveDefn.curve(knownProvider.getValuationDate(), childMetadata, curveParams);
// put child curve into maps
Set currencies = discountCurveNames.get(name);
for (Currency currency : currencies) {
discountCurves.put(currency, curve);
}
Set indices = forwardCurveNames.get(name);
for (Index index : indices) {
indexCurves.put(index, curve);
}
}
return knownProvider.toBuilder()
.discountCurves(discountCurves)
.indexCurves(indexCurves)
.build();
}
// build the map of additional info
private CurveMetadata childMetadata(
CurveMetadata metadata,
CurveDefinition curveDefn,
Map jacobians,
Map sensitivitiesMarketQuote) {
JacobianCalibrationMatrix jacobian = jacobians.get(curveDefn.getName());
CurveMetadata metadataResult = metadata;
if (jacobian != null) {
metadataResult = metadata.withInfo(CurveInfoType.JACOBIAN, jacobian);
}
DoubleArray sensitivity = sensitivitiesMarketQuote.get(curveDefn.getName());
if (sensitivity != null) {
metadataResult = metadataResult.withInfo(CurveInfoType.PV_SENSITIVITY_TO_MARKET_QUOTE, sensitivity);
}
return metadataResult;
}
}