/** * Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.sesame.inflation; import java.util.HashMap; import java.util.Map; import java.util.Set; import com.opengamma.analytics.financial.instrument.swap.SwapFixedInflationZeroCouponDefinition; import com.opengamma.analytics.financial.interestrate.InstrumentDerivative; import com.opengamma.analytics.financial.interestrate.InstrumentDerivativeVisitor; import com.opengamma.analytics.financial.provider.calculator.inflation.MarketQuoteInflationSensitivityBlockCalculator; import com.opengamma.analytics.financial.provider.calculator.inflation.ParRateInflationDiscountingCalculator; import com.opengamma.analytics.financial.provider.calculator.inflation.PresentValueCurveSensitivityDiscountingInflationCalculator; import com.opengamma.analytics.financial.provider.calculator.inflation.PresentValueDiscountingInflationCalculator; import com.opengamma.analytics.financial.provider.curve.CurveBuildingBlockBundle; import com.opengamma.analytics.financial.provider.description.inflation.ParameterInflationProviderInterface; import com.opengamma.analytics.financial.provider.sensitivity.inflation.ParameterSensitivityInflationParameterCalculator; import com.opengamma.analytics.financial.provider.sensitivity.multicurve.MultipleCurrencyParameterSensitivity; import com.opengamma.analytics.math.matrix.DoubleMatrix1D; import com.opengamma.financial.analytics.DoubleLabelledMatrix1D; import com.opengamma.financial.analytics.model.fixedincome.BucketedCurveSensitivities; import com.opengamma.sesame.CurveLabellingFn; import com.opengamma.sesame.CurveMatrixLabeller; import com.opengamma.sesame.Environment; import com.opengamma.sesame.InflationProviderBundle; import com.opengamma.sesame.LookupInflationProviderFn; import com.opengamma.sesame.trade.ZeroCouponInflationSwapTrade; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.money.Currency; import com.opengamma.util.money.MultipleCurrencyAmount; import com.opengamma.util.result.Result; import com.opengamma.util.tuple.Pair; /** * Discounting function for calculating risk measures for zero coupon inflation swaps. */ public class DiscountingZeroCouponInflationSwapFn implements ZeroCouponInflationSwapFn { private final InflationSwapConverterFn _converter; private final LookupInflationProviderFn _inflationProviderFn; private final CurveLabellingFn _curveLabellingFn; private static final InstrumentDerivativeVisitor<ParameterInflationProviderInterface, MultipleCurrencyAmount> PV_CALC = PresentValueDiscountingInflationCalculator.getInstance(); private static final ParRateInflationDiscountingCalculator PAR_RATE_CALC = ParRateInflationDiscountingCalculator.getInstance(); private static final PresentValueCurveSensitivityDiscountingInflationCalculator PVCSDIC = PresentValueCurveSensitivityDiscountingInflationCalculator.getInstance(); private static final ParameterSensitivityInflationParameterCalculator<ParameterInflationProviderInterface> PSC = new ParameterSensitivityInflationParameterCalculator<>(PVCSDIC); private static final MarketQuoteInflationSensitivityBlockCalculator<ParameterInflationProviderInterface> MQSBC = new MarketQuoteInflationSensitivityBlockCalculator<>(PSC); private static final double BP1 = 1.0E-4; public DiscountingZeroCouponInflationSwapFn(InflationSwapConverterFn converter, LookupInflationProviderFn inflationProviderFn, CurveLabellingFn curveLabellingFn) { _inflationProviderFn = ArgumentChecker.notNull(inflationProviderFn, "inflationProviderFn"); _converter = ArgumentChecker.notNull(converter, "converter"); _curveLabellingFn = ArgumentChecker.notNull(curveLabellingFn, "curveLabellingFn"); } @Override public Result<MultipleCurrencyAmount> calculatePV(Environment env, ZeroCouponInflationSwapTrade trade) { Result<InflationProviderBundle> bundleResult = _inflationProviderFn.getInflationBundle(env, trade); Result<Pair<SwapFixedInflationZeroCouponDefinition, InstrumentDerivative>> tradeResults = _converter.convert(env, trade.getSecurity()); if (!bundleResult.isSuccess() || !tradeResults.isSuccess()) { return Result.failure(bundleResult, tradeResults); } else { ParameterInflationProviderInterface data = bundleResult.getValue().getParameterInflationProvider(); InstrumentDerivative inflationDerivative = tradeResults.getValue().getSecond(); return Result.success(inflationDerivative.accept(PV_CALC, data)); } } @Override public Result<BucketedCurveSensitivities> calculateBucketedPV01(Environment env, ZeroCouponInflationSwapTrade trade) { Result<InflationProviderBundle> bundleResult = _inflationProviderFn.getInflationBundle(env, trade); Result<Pair<SwapFixedInflationZeroCouponDefinition, InstrumentDerivative>> tradeResults = _converter.convert(env, trade.getSecurity()); if (!bundleResult.isSuccess() || !tradeResults.isSuccess()) { return Result.failure(bundleResult, tradeResults); } else { ParameterInflationProviderInterface data = bundleResult.getValue().getParameterInflationProvider(); CurveBuildingBlockBundle block = bundleResult.getValue().getCurveBuildingBlockBundle(); Set<String> curveNames = block.getData().keySet(); Result<Map<String, CurveMatrixLabeller>> curveLabels = _curveLabellingFn.getCurveLabellers(curveNames); if (!curveLabels.isSuccess()) { return Result.failure(curveLabels); } InstrumentDerivative swap = tradeResults.getValue().getSecond(); MultipleCurrencyParameterSensitivity sensitivity = MQSBC.fromInstrument(swap, data, block).multipliedBy(BP1); Map<Pair<String, Currency>, DoubleLabelledMatrix1D> labelledMatrix1DMap = new HashMap<>(); for (Map.Entry<Pair<String, Currency>, DoubleMatrix1D> entry : sensitivity.getSensitivities().entrySet()) { CurveMatrixLabeller curveMatrixLabeller = curveLabels.getValue().get(entry.getKey().getFirst()); DoubleLabelledMatrix1D matrix = curveMatrixLabeller.labelMatrix(entry.getValue()); labelledMatrix1DMap.put(entry.getKey(), matrix); } return Result.success(BucketedCurveSensitivities.of(labelledMatrix1DMap)); } } @Override public Result<Double> calculateParRate(Environment env, ZeroCouponInflationSwapTrade trade) { Result<InflationProviderBundle> bundleResult = _inflationProviderFn.getInflationBundle(env, trade); Result<Pair<SwapFixedInflationZeroCouponDefinition, InstrumentDerivative>> tradeResults = _converter.convert(env, trade.getSecurity()); if (!bundleResult.isSuccess() || !tradeResults.isSuccess()) { return Result.failure(bundleResult, tradeResults); } else { ParameterInflationProviderInterface data = bundleResult.getValue().getParameterInflationProvider(); InstrumentDerivative inflationDerivative = tradeResults.getValue().getSecond(); return Result.success(inflationDerivative.accept(PAR_RATE_CALC, data)); } } }