/**
* Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.provider.curve;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import org.threeten.bp.Period;
import org.threeten.bp.ZonedDateTime;
import com.google.common.collect.LinkedListMultimap;
import com.opengamma.analytics.financial.curve.interestrate.generator.GeneratorCurve;
import com.opengamma.analytics.financial.curve.interestrate.generator.GeneratorYDCurve;
import com.opengamma.analytics.financial.instrument.InstrumentDefinition;
import com.opengamma.analytics.financial.instrument.cash.CashDefinition;
import com.opengamma.analytics.financial.instrument.fra.ForwardRateAgreementDefinition;
import com.opengamma.analytics.financial.instrument.future.InterestRateFutureTransactionDefinition;
import com.opengamma.analytics.financial.instrument.future.SwapFuturesPriceDeliverableTransactionDefinition;
import com.opengamma.analytics.financial.instrument.index.GeneratorAttribute;
import com.opengamma.analytics.financial.instrument.index.GeneratorInstrument;
import com.opengamma.analytics.financial.instrument.index.IborIndex;
import com.opengamma.analytics.financial.instrument.index.IndexON;
import com.opengamma.analytics.financial.instrument.index.IndexPrice;
import com.opengamma.analytics.financial.instrument.inflation.CouponInflationDefinition;
import com.opengamma.analytics.financial.instrument.payment.CouponFixedCompoundingDefinition;
import com.opengamma.analytics.financial.instrument.payment.CouponIborDefinition;
import com.opengamma.analytics.financial.instrument.payment.CouponIborSpreadDefinition;
import com.opengamma.analytics.financial.instrument.payment.CouponONDefinition;
import com.opengamma.analytics.financial.instrument.payment.PaymentDefinition;
import com.opengamma.analytics.financial.instrument.swap.SwapDefinition;
import com.opengamma.analytics.financial.instrument.swap.SwapFixedIborDefinition;
import com.opengamma.analytics.financial.instrument.swap.SwapFixedInflationZeroCouponDefinition;
import com.opengamma.analytics.financial.instrument.swap.SwapFixedONDefinition;
import com.opengamma.analytics.financial.interestrate.InstrumentDerivative;
import com.opengamma.analytics.financial.interestrate.InstrumentDerivativeVisitor;
import com.opengamma.analytics.financial.legalentity.LegalEntity;
import com.opengamma.analytics.financial.legalentity.LegalEntityFilter;
import com.opengamma.analytics.financial.provider.curve.hullwhite.HullWhiteProviderDiscountBuildingRepository;
import com.opengamma.analytics.financial.provider.curve.inflation.InflationDiscountBuildingRepository;
import com.opengamma.analytics.financial.provider.curve.inflationissuer.InflationIssuerDiscountBuildingRepository;
import com.opengamma.analytics.financial.provider.curve.issuer.IssuerDiscountBuildingRepository;
import com.opengamma.analytics.financial.provider.curve.multicurve.MulticurveDiscountBuildingRepository;
import com.opengamma.analytics.financial.provider.description.inflation.InflationIssuerProviderDiscount;
import com.opengamma.analytics.financial.provider.description.inflation.InflationProviderDiscount;
import com.opengamma.analytics.financial.provider.description.inflation.ParameterInflationIssuerProviderInterface;
import com.opengamma.analytics.financial.provider.description.inflation.ParameterInflationProviderInterface;
import com.opengamma.analytics.financial.provider.description.interestrate.HullWhiteOneFactorProviderDiscount;
import com.opengamma.analytics.financial.provider.description.interestrate.HullWhiteOneFactorProviderInterface;
import com.opengamma.analytics.financial.provider.description.interestrate.IssuerProviderDiscount;
import com.opengamma.analytics.financial.provider.description.interestrate.MulticurveProviderDiscount;
import com.opengamma.analytics.financial.provider.description.interestrate.MulticurveProviderInterface;
import com.opengamma.analytics.financial.provider.description.interestrate.ParameterIssuerProviderInterface;
import com.opengamma.analytics.financial.provider.description.interestrate.ParameterProviderInterface;
import com.opengamma.analytics.financial.provider.sensitivity.inflation.InflationSensitivity;
import com.opengamma.analytics.financial.provider.sensitivity.multicurve.MulticurveSensitivity;
import com.opengamma.analytics.financial.schedule.ScheduleCalculator;
import com.opengamma.analytics.util.time.TimeCalculator;
import com.opengamma.financial.convention.calendar.Calendar;
import com.opengamma.timeseries.precise.zdt.ImmutableZonedDateTimeDoubleTimeSeries;
import com.opengamma.timeseries.precise.zdt.ZonedDateTimeDoubleTimeSeries;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.money.Currency;
import com.opengamma.util.tuple.Pair;
/**
* Utilities class for curve calibration tests and tutorials.
*/
public class CurveCalibrationTestsUtils {
private static final ZonedDateTimeDoubleTimeSeries TS_EMPTY = ImmutableZonedDateTimeDoubleTimeSeries.ofEmptyUTC();
public static void exportInflationCurve(
ZonedDateTime calibrationDate, ZonedDateTime startDate, InflationProviderDiscount multicurve, IndexPrice index,
File file, int nbDates, int jumpMonths) {
ZonedDateTime[] scheduleDate = ScheduleCalculator.getUnadjustedDateSchedule(startDate,
startDate.plusMonths(nbDates * jumpMonths), Period.ofMonths(jumpMonths), true, false);
final double[] indexValue = new double[nbDates];
final double[] time = new double[nbDates];
try (FileWriter writer = new FileWriter(file)) {
for (int loopdate = 0; loopdate < nbDates; loopdate++) {
time[loopdate] = TimeCalculator.getTimeBetween(calibrationDate, scheduleDate[loopdate]);
indexValue[loopdate] = multicurve.getPriceIndex(index, time[loopdate]);
writer.append(0.0 + "," + time[loopdate] + "," + indexValue[loopdate] + "\n");
}
writer.flush();
} catch (final IOException e) {
e.printStackTrace();
}
}
public static void exportIborForwardIborCurve(
ZonedDateTime calibrationDate, MulticurveProviderInterface multicurve, IborIndex index, Calendar cal,
File file, int startIndex, int nbDate, int jump) {
ZonedDateTime startDate = ScheduleCalculator.getAdjustedDate(calibrationDate, index.getSpotLag() + startIndex * jump, cal);
final double[] rateDsc = new double[nbDate];
final double[] startTime = new double[nbDate];
try (FileWriter writer = new FileWriter(file)) {
for (int loopdate = 0; loopdate < nbDate; loopdate++) {
startTime[loopdate] = TimeCalculator.getTimeBetween(calibrationDate, startDate);
final ZonedDateTime endDate = ScheduleCalculator.getAdjustedDate(startDate, index, cal);
final double endTime = TimeCalculator.getTimeBetween(calibrationDate, endDate);
final double accrualFactor = index.getDayCount().getDayCountFraction(startDate, endDate, cal);
rateDsc[loopdate] = multicurve.getSimplyCompoundForwardRate(index, startTime[loopdate], endTime, accrualFactor);
startDate = ScheduleCalculator.getAdjustedDate(startDate, jump, cal);
writer.append(0.0 + "," + startTime[loopdate] + "," + rateDsc[loopdate] + "\n");
}
writer.flush();
} catch (final IOException e) {
e.printStackTrace();
}
}
public static void exportONForwardONCurve(
ZonedDateTime calibrationDate, MulticurveProviderInterface multicurve, IndexON index, Calendar cal,
File file, int nbDate, int jump) {
ZonedDateTime startDate = calibrationDate;
final double[] rateDsc = new double[nbDate];
final double[] startTime = new double[nbDate];
try (FileWriter writer = new FileWriter(file)) {
for (int loopdate = 0; loopdate < nbDate; loopdate++) {
startTime[loopdate] = TimeCalculator.getTimeBetween(calibrationDate, startDate);
final ZonedDateTime endDate = ScheduleCalculator.getAdjustedDate(startDate, 1, cal);
final double endTime = TimeCalculator.getTimeBetween(calibrationDate, endDate);
final double accrualFactor = index.getDayCount().getDayCountFraction(startDate, endDate);
rateDsc[loopdate] = multicurve.getSimplyCompoundForwardRate(index, startTime[loopdate], endTime, accrualFactor);
startDate = ScheduleCalculator.getAdjustedDate(startDate, jump, cal);
writer.append(0.0 + "," + startTime[loopdate] + "," + rateDsc[loopdate] + "\n");
}
writer.flush();
} catch (final IOException e) {
e.printStackTrace();
}
}
public static void exportONForwardIborCurve(
ZonedDateTime calibrationDate, MulticurveProviderInterface multicurve, IborIndex index, Calendar cal,
File file, int nbDate, int jump) {
ZonedDateTime startDate = calibrationDate;
final double[] rateDsc = new double[nbDate];
final double[] startTime = new double[nbDate];
try (FileWriter writer = new FileWriter(file)) {
for (int loopdate = 0; loopdate < nbDate; loopdate++) {
startTime[loopdate] = TimeCalculator.getTimeBetween(calibrationDate, startDate);
final ZonedDateTime endDate = ScheduleCalculator.getAdjustedDate(startDate, 1, cal);
final double endTime = TimeCalculator.getTimeBetween(calibrationDate, endDate);
final double accrualFactor = index.getDayCount().getDayCountFraction(startDate, endDate);
rateDsc[loopdate] = multicurve.getSimplyCompoundForwardRate(index, startTime[loopdate], endTime, accrualFactor);
startDate = ScheduleCalculator.getAdjustedDate(startDate, jump, cal);
writer.append(0.0 + "," + startTime[loopdate] + "," + rateDsc[loopdate] + "\n");
}
writer.flush();
} catch (final IOException e) {
e.printStackTrace();
}
}
public static void exportZCRatesONCurve(
ZonedDateTime calibrationDate, MulticurveProviderDiscount multicurve, IndexON index, Calendar cal,
File file, int nbDate, int jump) {
ZonedDateTime startDate = calibrationDate;
final double[] rateZC = new double[nbDate];
final double[] startTime = new double[nbDate];
try (FileWriter writer = new FileWriter(file)) {
for (int loopdate = 0; loopdate < nbDate; loopdate++) {
startTime[loopdate] = TimeCalculator.getTimeBetween(calibrationDate, startDate);
rateZC[loopdate] = multicurve.getCurve(index).getInterestRate(startTime[loopdate]);
startDate = ScheduleCalculator.getAdjustedDate(startDate, jump, cal);
writer.append(0.0 + "," + startTime[loopdate] + "," + rateZC[loopdate] + "\n");
}
writer.flush();
} catch (final IOException e) {
e.printStackTrace();
}
}
public static void exportZCRatesIborCurve(
ZonedDateTime calibrationDate, MulticurveProviderDiscount multicurve, IborIndex index, Calendar cal,
File file, int nbDate, int jump) {
ZonedDateTime startDate = calibrationDate;
final double[] rateZC = new double[nbDate];
final double[] startTime = new double[nbDate];
try (FileWriter writer = new FileWriter(file)) {
for (int loopdate = 0; loopdate < nbDate; loopdate++) {
startTime[loopdate] = TimeCalculator.getTimeBetween(calibrationDate, startDate);
rateZC[loopdate] = multicurve.getCurve(index).getInterestRate(startTime[loopdate]);
startDate = ScheduleCalculator.getAdjustedDate(startDate, jump, cal);
writer.append(0.0 + "," + startTime[loopdate] + "," + rateZC[loopdate] + "\n");
}
writer.flush();
} catch (final IOException e) {
e.printStackTrace();
}
}
@SuppressWarnings("unchecked")
public static Pair<MulticurveProviderDiscount, CurveBuildingBlockBundle> makeCurvesFromDefinitionsMulticurve(
ZonedDateTime calibrationDate, final InstrumentDefinition<?>[][][] definitions,
final GeneratorYDCurve[][] curveGenerators, final String[][] curveNames, final MulticurveProviderDiscount knownData,
final InstrumentDerivativeVisitor<ParameterProviderInterface, Double> calculator,
final InstrumentDerivativeVisitor<ParameterProviderInterface, MulticurveSensitivity> sensitivityCalculator, final boolean withToday,
LinkedHashMap<String, Currency> dscMap, LinkedHashMap<String, IndexON[]> fwdOnMap, LinkedHashMap<String, IborIndex[]> fwdIborMap,
MulticurveDiscountBuildingRepository repository,
ZonedDateTimeDoubleTimeSeries[] htsFixedOisWithToday, ZonedDateTimeDoubleTimeSeries[] htsFixedOisWithoutToday,
ZonedDateTimeDoubleTimeSeries[] htsFixedIborWithToday, ZonedDateTimeDoubleTimeSeries[] htsFixedIborWithoutToday) {
final int nUnits = definitions.length;
final MultiCurveBundle<GeneratorYDCurve>[] curveBundles = new MultiCurveBundle[nUnits];
for (int i = 0; i < nUnits; i++) {
final int nCurves = definitions[i].length;
final SingleCurveBundle<GeneratorYDCurve>[] singleCurves = new SingleCurveBundle[nCurves];
for (int j = 0; j < nCurves; j++) {
final int nInstruments = definitions[i][j].length;
final InstrumentDerivative[] derivatives = new InstrumentDerivative[nInstruments];
final double[] rates = new double[nInstruments];
for (int k = 0; k < nInstruments; k++) {
derivatives[k] = convert(definitions[i][j][k], withToday, calibrationDate, htsFixedOisWithToday, htsFixedOisWithoutToday,
htsFixedIborWithToday, htsFixedIborWithoutToday);
rates[k] = CurveCalibrationTestsUtils.initialGuess(definitions[i][j][k]);
}
final GeneratorYDCurve generator = curveGenerators[i][j].finalGenerator(derivatives);
final double[] initialGuess = generator.initialGuess(rates);
singleCurves[j] = new SingleCurveBundle<>(curveNames[i][j], derivatives, initialGuess, generator);
}
curveBundles[i] = new MultiCurveBundle<>(singleCurves);
}
return repository.makeCurvesFromDerivatives(curveBundles, knownData, dscMap, fwdIborMap, fwdOnMap, calculator, sensitivityCalculator);
}
@SuppressWarnings("unchecked")
public static Pair<IssuerProviderDiscount, CurveBuildingBlockBundle> makeCurvesFromDefinitionsIssuer(
ZonedDateTime calibrationDate, final InstrumentDefinition<?>[][][] definitions,
final GeneratorYDCurve[][] curveGenerators, final String[][] curveNames, final IssuerProviderDiscount knownData,
final InstrumentDerivativeVisitor<ParameterIssuerProviderInterface, Double> calculator,
final InstrumentDerivativeVisitor<ParameterIssuerProviderInterface, MulticurveSensitivity> sensitivityCalculator,
boolean withToday, LinkedHashMap<String, Currency> dscMap, LinkedHashMap<String, IndexON[]> fwdOnMap,
LinkedHashMap<String, IborIndex[]> fwdIborMap,
LinkedListMultimap<String, Pair<Object, LegalEntityFilter<LegalEntity>>> issuerMap,
IssuerDiscountBuildingRepository repository,
ZonedDateTimeDoubleTimeSeries[] htsFixedOisWithToday, ZonedDateTimeDoubleTimeSeries[] htsFixedOisWithoutToday,
ZonedDateTimeDoubleTimeSeries[] htsFixedIborWithToday, ZonedDateTimeDoubleTimeSeries[] htsFixedIborWithoutToday) {
final int nUnits = definitions.length;
final MultiCurveBundle<GeneratorYDCurve>[] curveBundles = new MultiCurveBundle[nUnits];
for (int i = 0; i < nUnits; i++) {
final int nCurves = definitions[i].length;
final SingleCurveBundle<GeneratorYDCurve>[] singleCurves = new SingleCurveBundle[nCurves];
for (int j = 0; j < nCurves; j++) {
final int nInstruments = definitions[i][j].length;
final InstrumentDerivative[] derivatives = new InstrumentDerivative[nInstruments];
final double[] rates = new double[nInstruments];
for (int k = 0; k < nInstruments; k++) {
derivatives[k] = convert(definitions[i][j][k], withToday, calibrationDate, htsFixedOisWithToday, htsFixedOisWithoutToday,
htsFixedIborWithToday, htsFixedIborWithoutToday);
rates[k] = CurveCalibrationTestsUtils.initialGuess(definitions[i][j][k]);
}
final GeneratorYDCurve generator = curveGenerators[i][j].finalGenerator(derivatives);
final double[] initialGuess = generator.initialGuess(rates);
singleCurves[j] = new SingleCurveBundle<>(curveNames[i][j], derivatives, initialGuess, generator);
}
curveBundles[i] = new MultiCurveBundle<>(singleCurves);
}
return repository.makeCurvesFromDerivatives(curveBundles, knownData, dscMap, fwdIborMap, fwdOnMap, issuerMap,
calculator, sensitivityCalculator);
}
@SuppressWarnings("unchecked")
public static Pair<HullWhiteOneFactorProviderDiscount, CurveBuildingBlockBundle> makeCurvesFromDefinitionsHullWhite(
ZonedDateTime calibrationDate, final InstrumentDefinition<?>[][][] definitions,
final GeneratorYDCurve[][] curveGenerators, final String[][] curveNames, final HullWhiteOneFactorProviderDiscount knownData,
final InstrumentDerivativeVisitor<HullWhiteOneFactorProviderInterface, Double> calculator,
final InstrumentDerivativeVisitor<HullWhiteOneFactorProviderInterface, MulticurveSensitivity> sensitivityCalculator, final boolean withToday,
LinkedHashMap<String, Currency> dscMap, LinkedHashMap<String, IndexON[]> fwdOnMap, LinkedHashMap<String, IborIndex[]> fwdIborMap,
HullWhiteProviderDiscountBuildingRepository repository,
ZonedDateTimeDoubleTimeSeries[] htsFixedOisWithToday, ZonedDateTimeDoubleTimeSeries[] htsFixedOisWithoutToday,
ZonedDateTimeDoubleTimeSeries[] htsFixedIborWithToday, ZonedDateTimeDoubleTimeSeries[] htsFixedIborWithoutToday) {
final int nUnits = definitions.length;
final MultiCurveBundle<GeneratorYDCurve>[] curveBundles = new MultiCurveBundle[nUnits];
for (int i = 0; i < nUnits; i++) {
final int nCurves = definitions[i].length;
final SingleCurveBundle<GeneratorYDCurve>[] singleCurves = new SingleCurveBundle[nCurves];
for (int j = 0; j < nCurves; j++) {
final int nInstruments = definitions[i][j].length;
final InstrumentDerivative[] derivatives = new InstrumentDerivative[nInstruments];
final double[] rates = new double[nInstruments];
for (int k = 0; k < nInstruments; k++) {
derivatives[k] = convert(definitions[i][j][k], withToday, calibrationDate, htsFixedOisWithToday, htsFixedOisWithoutToday,
htsFixedIborWithToday, htsFixedIborWithoutToday);
rates[k] = CurveCalibrationTestsUtils.initialGuess(definitions[i][j][k]);
}
final GeneratorYDCurve generator = curveGenerators[i][j].finalGenerator(derivatives);
final double[] initialGuess = generator.initialGuess(rates);
singleCurves[j] = new SingleCurveBundle<>(curveNames[i][j], derivatives, initialGuess, generator);
}
curveBundles[i] = new MultiCurveBundle<>(singleCurves);
}
return repository.makeCurvesFromDerivatives(curveBundles, knownData, dscMap, fwdIborMap, fwdOnMap, calculator, sensitivityCalculator);
}
public static InstrumentDerivative convert(final InstrumentDefinition<?> instrument, final boolean withToday,
ZonedDateTime calibrationDate,
ZonedDateTimeDoubleTimeSeries[] htsFixedOisWithToday, ZonedDateTimeDoubleTimeSeries[] htsFixedOisWithoutToday,
ZonedDateTimeDoubleTimeSeries[] htsFixedIborWithToday, ZonedDateTimeDoubleTimeSeries[] htsFixedIborWithoutToday) {
if (instrument instanceof SwapFixedONDefinition) {
return ((SwapFixedONDefinition) instrument).toDerivative(calibrationDate,
getTSSwapFixedON(withToday, htsFixedOisWithToday, htsFixedOisWithoutToday));
}
if (instrument instanceof SwapFixedIborDefinition) {
return ((SwapFixedIborDefinition) instrument).toDerivative(calibrationDate,
getTSSwapFixedIbor(withToday, htsFixedIborWithToday, htsFixedIborWithoutToday));
}
if (instrument instanceof SwapDefinition) {
SwapDefinition swap = (SwapDefinition) instrument;
ZonedDateTimeDoubleTimeSeries[] hts = new ZonedDateTimeDoubleTimeSeries[2];
PaymentDefinition[] payment = new PaymentDefinition[2];
payment[0] = swap.getFirstLeg().getNthPayment(0);
payment[1] = swap.getSecondLeg().getNthPayment(0);
for (int loopleg = 0; loopleg < 2; loopleg++) {
if (payment[loopleg] instanceof CouponONDefinition) {
hts[loopleg] = withToday ? htsFixedOisWithToday[0] : htsFixedOisWithoutToday[0];
} else {
if ((payment[loopleg] instanceof CouponIborDefinition) || (payment[loopleg] instanceof CouponIborSpreadDefinition)) {
hts[loopleg] = withToday ? htsFixedIborWithToday[0] : htsFixedIborWithoutToday[0];
} else {
hts[loopleg] = ImmutableZonedDateTimeDoubleTimeSeries.ofEmptyUTC();
}
}
}
return swap.toDerivative(calibrationDate, hts);
}
if (instrument instanceof InterestRateFutureTransactionDefinition) {
return ((InterestRateFutureTransactionDefinition) instrument).toDerivative(calibrationDate, 0.0);
} // Trade date = today, reference price not used.
if (instrument instanceof SwapFuturesPriceDeliverableTransactionDefinition) {
return ((SwapFuturesPriceDeliverableTransactionDefinition) instrument).toDerivative(calibrationDate, 0.0);
} // Trade date = today, reference price not used.
return instrument.toDerivative(calibrationDate);
}
public static double initialGuess(final InstrumentDefinition<?> instrument) {
if (instrument instanceof SwapFixedONDefinition) {
return ((SwapFixedONDefinition) instrument).getFixedLeg().getNthPayment(0).getRate();
}
if (instrument instanceof SwapFixedIborDefinition) {
return ((SwapFixedIborDefinition) instrument).getFixedLeg().getNthPayment(0).getRate();
}
if (instrument instanceof ForwardRateAgreementDefinition) {
return ((ForwardRateAgreementDefinition) instrument).getRate();
}
if (instrument instanceof CashDefinition) {
return ((CashDefinition) instrument).getRate();
}
if (instrument instanceof InterestRateFutureTransactionDefinition) {
return 1 - ((InterestRateFutureTransactionDefinition) instrument).getTradePrice();
}
if (instrument instanceof SwapFixedInflationZeroCouponDefinition) {
PaymentDefinition cpn = ((SwapFixedInflationZeroCouponDefinition) instrument).getFirstLeg().getNthPayment(0);
return ((CouponFixedCompoundingDefinition) cpn).getRate();
}
return 0.01;
}
public static ZonedDateTimeDoubleTimeSeries[] getTSSwapFixedON(final Boolean withToday,
ZonedDateTimeDoubleTimeSeries[] htsWithToday, ZonedDateTimeDoubleTimeSeries[] htsWithoutToday) {
return withToday ? htsWithToday : htsWithoutToday;
}
public static ZonedDateTimeDoubleTimeSeries[] getTSSwapFixedIbor(final Boolean withToday,
ZonedDateTimeDoubleTimeSeries[] htsWithToday, ZonedDateTimeDoubleTimeSeries[] htsWithoutToday) {
return withToday ? htsWithToday : htsWithoutToday;
}
@SuppressWarnings("unchecked")
public static Pair<MulticurveProviderDiscount, CurveBuildingBlockBundle> makeCurvesFromDefinitionsMulticurve(
ZonedDateTime calibrationDate, final InstrumentDefinition<?>[][][] definitions,
final GeneratorYDCurve[][] curveGenerators, final String[][] curveNames, final MulticurveProviderDiscount knownData,
final InstrumentDerivativeVisitor<ParameterProviderInterface, Double> calculator,
final InstrumentDerivativeVisitor<ParameterProviderInterface, MulticurveSensitivity> sensitivityCalculator,
LinkedHashMap<String, Currency> dscMap, LinkedHashMap<String, IndexON[]> fwdOnMap, LinkedHashMap<String, IborIndex[]> fwdIborMap,
MulticurveDiscountBuildingRepository repository,
Map<IndexON,ZonedDateTimeDoubleTimeSeries> htsOis, Map<IborIndex,ZonedDateTimeDoubleTimeSeries> htsIbor) {
final int nUnits = definitions.length;
final MultiCurveBundle<GeneratorYDCurve>[] curveBundles = new MultiCurveBundle[nUnits];
for (int i = 0; i < nUnits; i++) {
final int nCurves = definitions[i].length;
final SingleCurveBundle<GeneratorYDCurve>[] singleCurves = new SingleCurveBundle[nCurves];
for (int j = 0; j < nCurves; j++) {
final int nInstruments = definitions[i][j].length;
final InstrumentDerivative[] derivatives = new InstrumentDerivative[nInstruments];
final double[] rates = new double[nInstruments];
for (int k = 0; k < nInstruments; k++) {
derivatives[k] = convert(definitions[i][j][k], calibrationDate, htsOis, htsIbor,
new LinkedHashMap<IndexPrice,ZonedDateTimeDoubleTimeSeries>());
rates[k] = CurveCalibrationTestsUtils.initialGuess(definitions[i][j][k]);
}
final GeneratorYDCurve generator = curveGenerators[i][j].finalGenerator(derivatives);
final double[] initialGuess = generator.initialGuess(rates);
singleCurves[j] = new SingleCurveBundle<>(curveNames[i][j], derivatives, initialGuess, generator);
}
curveBundles[i] = new MultiCurveBundle<>(singleCurves);
}
return repository.makeCurvesFromDerivatives(curveBundles, knownData, dscMap, fwdIborMap, fwdOnMap, calculator, sensitivityCalculator);
}
@SuppressWarnings("unchecked")
public static Pair<IssuerProviderDiscount, CurveBuildingBlockBundle> makeCurvesFromDefinitionsIssuer(
ZonedDateTime calibrationDate, final InstrumentDefinition<?>[][][] definitions,
final GeneratorYDCurve[][] curveGenerators, final String[][] curveNames,
final IssuerProviderDiscount knownData, CurveBuildingBlockBundle knownBlock,
final InstrumentDerivativeVisitor<ParameterIssuerProviderInterface, Double> calculator,
final InstrumentDerivativeVisitor<ParameterIssuerProviderInterface, MulticurveSensitivity> sensitivityCalculator,
LinkedHashMap<String, Currency> dscMap, LinkedHashMap<String, IndexON[]> fwdOnMap,
LinkedHashMap<String, IborIndex[]> fwdIborMap,
LinkedListMultimap<String, Pair<Object, LegalEntityFilter<LegalEntity>>> issuerMap,
IssuerDiscountBuildingRepository repository,
Map<IndexON,ZonedDateTimeDoubleTimeSeries> htsOis, Map<IborIndex,ZonedDateTimeDoubleTimeSeries> htsIbor) {
final int nUnits = definitions.length;
final MultiCurveBundle<GeneratorYDCurve>[] curveBundles = new MultiCurveBundle[nUnits];
for (int i = 0; i < nUnits; i++) {
final int nCurves = definitions[i].length;
final SingleCurveBundle<GeneratorYDCurve>[] singleCurves = new SingleCurveBundle[nCurves];
for (int j = 0; j < nCurves; j++) {
final int nInstruments = definitions[i][j].length;
final InstrumentDerivative[] derivatives = new InstrumentDerivative[nInstruments];
final double[] rates = new double[nInstruments];
for (int k = 0; k < nInstruments; k++) {
derivatives[k] = convert(definitions[i][j][k], calibrationDate, htsOis, htsIbor,
new LinkedHashMap<IndexPrice,ZonedDateTimeDoubleTimeSeries>());
rates[k] = CurveCalibrationTestsUtils.initialGuess(definitions[i][j][k]);
}
final GeneratorYDCurve generator = curveGenerators[i][j].finalGenerator(derivatives);
final double[] initialGuess = generator.initialGuess(rates);
singleCurves[j] = new SingleCurveBundle<>(curveNames[i][j], derivatives, initialGuess, generator);
}
curveBundles[i] = new MultiCurveBundle<>(singleCurves);
}
return repository.makeCurvesFromDerivatives(curveBundles, knownData, knownBlock, dscMap, fwdIborMap, fwdOnMap,
issuerMap, calculator, sensitivityCalculator);
}
@SuppressWarnings("unchecked")
public static Pair<InflationProviderDiscount, CurveBuildingBlockBundle> makeCurvesFromDefinitionsInflation(
ZonedDateTime calibrationDate, final InstrumentDefinition<?>[][][] definitions,
final GeneratorCurve[][] curveGenerators, final String[][] curveNames,
final InflationProviderDiscount knownData, CurveBuildingBlockBundle knownBlock,
final InstrumentDerivativeVisitor<ParameterInflationProviderInterface, Double> calculator,
final InstrumentDerivativeVisitor<ParameterInflationProviderInterface, InflationSensitivity> sensitivityCalculator,
LinkedHashMap<String, Currency> dscMap, LinkedHashMap<String, IndexON[]> fwdOnMap,
LinkedHashMap<String, IborIndex[]> fwdIborMap, LinkedHashMap<String, IndexPrice[]> priceMap,
InflationDiscountBuildingRepository repository,
Map<IndexON,ZonedDateTimeDoubleTimeSeries> htsOis, Map<IborIndex,ZonedDateTimeDoubleTimeSeries> htsIbor,
Map<IndexPrice,ZonedDateTimeDoubleTimeSeries> htsPrice) {
final int nUnits = definitions.length;
final MultiCurveBundle<GeneratorCurve>[] curveBundles = new MultiCurveBundle[nUnits];
for (int i = 0; i < nUnits; i++) {
final int nCurves = definitions[i].length;
final SingleCurveBundle<GeneratorCurve>[] singleCurves = new SingleCurveBundle[nCurves];
for (int j = 0; j < nCurves; j++) {
final int nInstruments = definitions[i][j].length;
final InstrumentDerivative[] derivatives = new InstrumentDerivative[nInstruments];
final double[] rates = new double[nInstruments];
for (int k = 0; k < nInstruments; k++) {
derivatives[k] = convert(definitions[i][j][k], calibrationDate, htsOis, htsIbor, htsPrice);
rates[k] = CurveCalibrationTestsUtils.initialGuess(definitions[i][j][k]);
}
final GeneratorCurve generator = curveGenerators[i][j].finalGenerator(derivatives);
final double[] initialGuess = generator.initialGuess(rates);
singleCurves[j] = new SingleCurveBundle<>(curveNames[i][j], derivatives, initialGuess, generator);
}
curveBundles[i] = new MultiCurveBundle<>(singleCurves);
}
return repository.makeCurvesFromDerivatives(curveBundles, knownData, knownBlock, dscMap, fwdOnMap, fwdIborMap,
priceMap, calculator, sensitivityCalculator);
}
@SuppressWarnings("unchecked")
public static Pair<InflationIssuerProviderDiscount, CurveBuildingBlockBundle> makeCurvesFromDefinitionsInflationIssuer(
ZonedDateTime calibrationDate, final InstrumentDefinition<?>[][][] definitions,
final GeneratorCurve[][] curveGenerators, final String[][] curveNames,
final InflationIssuerProviderDiscount knownData, CurveBuildingBlockBundle knownBlock,
final InstrumentDerivativeVisitor<ParameterInflationIssuerProviderInterface, Double> calculator,
final InstrumentDerivativeVisitor<ParameterInflationIssuerProviderInterface, InflationSensitivity> sensitivityCalculator,
LinkedHashMap<String, Currency> dscMap, LinkedHashMap<String, IndexON[]> fwdOnMap,
LinkedHashMap<String, IborIndex[]> fwdIborMap, LinkedHashMap<String, IndexPrice[]> priceMap,
LinkedListMultimap<String, Pair<Object, LegalEntityFilter<LegalEntity>>> issuerMap,
InflationIssuerDiscountBuildingRepository repository,
Map<IndexON,ZonedDateTimeDoubleTimeSeries> htsOis, Map<IborIndex,ZonedDateTimeDoubleTimeSeries> htsIbor,
Map<IndexPrice,ZonedDateTimeDoubleTimeSeries> htsPrice) {
final int nUnits = definitions.length;
final MultiCurveBundle<GeneratorCurve>[] curveBundles = new MultiCurveBundle[nUnits];
for (int i = 0; i < nUnits; i++) {
final int nCurves = definitions[i].length;
final SingleCurveBundle<GeneratorCurve>[] singleCurves = new SingleCurveBundle[nCurves];
for (int j = 0; j < nCurves; j++) {
final int nInstruments = definitions[i][j].length;
final InstrumentDerivative[] derivatives = new InstrumentDerivative[nInstruments];
final double[] rates = new double[nInstruments];
for (int k = 0; k < nInstruments; k++) {
derivatives[k] = convert(definitions[i][j][k], calibrationDate, htsOis, htsIbor, htsPrice);
rates[k] = CurveCalibrationTestsUtils.initialGuess(definitions[i][j][k]);
}
final GeneratorCurve generator = curveGenerators[i][j].finalGenerator(derivatives);
final double[] initialGuess = generator.initialGuess(rates);
singleCurves[j] = new SingleCurveBundle<>(curveNames[i][j], derivatives, initialGuess, generator);
}
curveBundles[i] = new MultiCurveBundle<>(singleCurves);
}
return repository.makeCurvesFromDerivatives(curveBundles, knownData, knownBlock, dscMap, fwdOnMap, fwdIborMap,
priceMap, issuerMap, calculator, sensitivityCalculator);
}
public static InstrumentDerivative convert(final InstrumentDefinition<?> instrument, ZonedDateTime calibrationDate,
Map<IndexON,ZonedDateTimeDoubleTimeSeries> htsOis, Map<IborIndex,ZonedDateTimeDoubleTimeSeries> htsIbor,
Map<IndexPrice,ZonedDateTimeDoubleTimeSeries> htsPrice) {
if (instrument instanceof SwapFixedONDefinition) {
IndexON index = ((SwapFixedONDefinition) instrument).getOISLeg().getOvernightIndex();
ZonedDateTimeDoubleTimeSeries[] hts = new ZonedDateTimeDoubleTimeSeries[] {htsOis.get(index)};
return ((SwapFixedONDefinition) instrument).toDerivative(calibrationDate, hts);
}
if (instrument instanceof SwapFixedIborDefinition) {
IborIndex index = ((SwapFixedIborDefinition) instrument).getIborLeg().getIborIndex();
ZonedDateTimeDoubleTimeSeries hts = htsIbor.get(index);
ArgumentChecker.notNull(hts, "time series from " + index.toString() + " is not present in map.");
ZonedDateTimeDoubleTimeSeries[] htsArray = new ZonedDateTimeDoubleTimeSeries[] {hts};
return ((SwapFixedIborDefinition) instrument).toDerivative(calibrationDate, htsArray);
}
if (instrument instanceof SwapFixedInflationZeroCouponDefinition) {
PaymentDefinition cpn = ((SwapFixedInflationZeroCouponDefinition) instrument).getSecondLeg().getNthPayment(0);
IndexPrice index = ((CouponInflationDefinition) cpn).getPriceIndex();
ZonedDateTimeDoubleTimeSeries hts = htsPrice.get(index);
ArgumentChecker.notNull(hts, "time series from " + index.toString() + " is not present in map.");
ZonedDateTimeDoubleTimeSeries[] htsArray = new ZonedDateTimeDoubleTimeSeries[] {TS_EMPTY, hts};
return ((SwapFixedInflationZeroCouponDefinition) instrument).toDerivative(calibrationDate, htsArray);
}
if (instrument instanceof SwapDefinition) {
SwapDefinition swap = (SwapDefinition) instrument;
ZonedDateTimeDoubleTimeSeries[] hts = new ZonedDateTimeDoubleTimeSeries[2];
PaymentDefinition[] payment = new PaymentDefinition[2];
payment[0] = swap.getFirstLeg().getNthPayment(0); // TODO: Improve for swaps with notional payment.
payment[1] = swap.getSecondLeg().getNthPayment(0);
for (int loopleg = 0; loopleg < 2; loopleg++) {
if (payment[loopleg] instanceof CouponONDefinition) {
hts[loopleg] = htsOis.get(payment[loopleg].getCurrency());
} else {
if ((payment[loopleg] instanceof CouponIborDefinition)) {
IborIndex index = ((CouponIborDefinition) payment[loopleg]).getIndex();
ZonedDateTimeDoubleTimeSeries htsIndex = htsIbor.get(index);
ArgumentChecker.notNull(htsIndex, "time series from " + index.toString() + " is not present in map.");
hts[loopleg] = htsIndex;
} else {
if (payment[loopleg] instanceof CouponIborSpreadDefinition) {
IborIndex index = ((CouponIborSpreadDefinition) payment[loopleg]).getIndex();
ZonedDateTimeDoubleTimeSeries htsIndex = htsIbor.get(index);
ArgumentChecker.notNull(htsIndex, "time series from " + index.toString() + " is not present in map.");
hts[loopleg] = htsIndex;
} else {
hts[loopleg] = ImmutableZonedDateTimeDoubleTimeSeries.ofEmptyUTC();}
}
}
}
return swap.toDerivative(calibrationDate, hts);
}
if (instrument instanceof InterestRateFutureTransactionDefinition) {
return ((InterestRateFutureTransactionDefinition) instrument).toDerivative(calibrationDate, 0.0);
} // Trade date = today, reference price not used.
if (instrument instanceof SwapFuturesPriceDeliverableTransactionDefinition) {
return ((SwapFuturesPriceDeliverableTransactionDefinition) instrument).toDerivative(calibrationDate, 0.0);
} // Trade date = today, reference price not used.
return instrument.toDerivative(calibrationDate);
}
@SuppressWarnings({"rawtypes", "unchecked" })
public static InstrumentDefinition<?>[] getDefinitions(final ZonedDateTime calibrationDate, final double notional,
final double[] marketQuotes, final GeneratorInstrument[] generators, final GeneratorAttribute[] attribute) {
final InstrumentDefinition<?>[] definitions = new InstrumentDefinition<?>[marketQuotes.length];
for (int loopmv = 0; loopmv < marketQuotes.length; loopmv++) {
definitions[loopmv] = generators[loopmv].generateInstrument(calibrationDate, marketQuotes[loopmv], notional,
attribute[loopmv]);
}
return definitions;
}
}