/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.provider.calculator.discounting; import com.opengamma.analytics.financial.interestrate.InstrumentDerivative; import com.opengamma.analytics.financial.interestrate.InstrumentDerivativeVisitor; import com.opengamma.analytics.financial.interestrate.InstrumentDerivativeVisitorSameMethodAdapter; import com.opengamma.analytics.financial.provider.description.interestrate.ParameterProviderInterface; import com.opengamma.analytics.financial.provider.sensitivity.multicurve.MultipleCurrencyMulticurveSensitivity; import com.opengamma.analytics.financial.provider.sensitivity.multicurve.MultipleCurrencyParameterSensitivity; import com.opengamma.analytics.financial.provider.sensitivity.parameter.ParameterSensitivityParameterCalculator; import com.opengamma.analytics.math.matrix.DoubleMatrix1D; import com.opengamma.analytics.util.amount.ReferenceAmount; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.money.Currency; import com.opengamma.util.tuple.Pair; /** * Returns the change in present value of an instrument due to a parallel move of all the curve's parameters, scaled so that the move is one basis point (0.0001). * @param <T> The type of the multi-curve provider */ public final class PV01CurveParametersCalculator<T extends ParameterProviderInterface> extends InstrumentDerivativeVisitorSameMethodAdapter<T, ReferenceAmount<Pair<String, Currency>>> { /** * The size of the scaling: 1 basis point. */ private static final double BP1 = 1.0E-4; /** * The present value curve sensitivity calculator. */ private final ParameterSensitivityParameterCalculator<T> _parameterSensitivityCalculator; /** * Constructs a PV01 calculator that uses a particular sensitivity calculator. * @param curveSensitivityCalculator The curve sensitivity calculator, not null */ public PV01CurveParametersCalculator(final InstrumentDerivativeVisitor<T, MultipleCurrencyMulticurveSensitivity> curveSensitivityCalculator) { ArgumentChecker.notNull(curveSensitivityCalculator, "curve sensitivity calculator"); _parameterSensitivityCalculator = new ParameterSensitivityParameterCalculator<>(curveSensitivityCalculator); } /** * Calculates the change in present value of an instrument due to a parallel move of each yield curve the instrument is sensitive to, scaled so that the move is 1bp. * @param ird The instrument, not null * @param multicurves The multi-curves provider, not null * @return The scale sensitivity for each curve/currency. */ @Override public ReferenceAmount<Pair<String, Currency>> visit(final InstrumentDerivative ird, final T multicurves) { ArgumentChecker.notNull(ird, "derivative"); ArgumentChecker.notNull(multicurves, "multicurves"); final MultipleCurrencyParameterSensitivity sensi = _parameterSensitivityCalculator.calculateSensitivity(ird, multicurves); return pv01CurveParameters(sensi); } /** * Given a MultipleCurrencyParameterSensitivity, compute total parameter sensitivities for individual currencies * @param sensi MultipleCurrencyParameterSensitivity * @return PV01 */ public ReferenceAmount<Pair<String, Currency>> pv01CurveParameters(final MultipleCurrencyParameterSensitivity sensi) { ArgumentChecker.notNull(sensi, "parameter sensitivity"); final ReferenceAmount<Pair<String, Currency>> ref = new ReferenceAmount<>(); for (final Pair<String, Currency> nameCcy : sensi.getAllNamesCurrency()) { final DoubleMatrix1D vector = sensi.getSensitivity(nameCcy); double total = 0.0; for (int loopv = 0; loopv < vector.getNumberOfElements(); loopv++) { total += vector.getEntry(loopv); } ref.add(nameCcy, total * BP1); } return ref; } @Override public ReferenceAmount<Pair<String, Currency>> visit(final InstrumentDerivative derivative) { throw new UnsupportedOperationException("Need curve data"); } }