/** * Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.sesame.bond; import java.util.HashMap; import java.util.Map; import org.threeten.bp.ZonedDateTime; import com.opengamma.analytics.financial.instrument.InstrumentDefinition; import com.opengamma.analytics.financial.instrument.bond.BondFixedTransactionDefinition; import com.opengamma.analytics.financial.interestrate.bond.calculator.YieldFromCleanPriceCalculator; import com.opengamma.analytics.financial.interestrate.bond.definition.BondFixedTransaction; import com.opengamma.analytics.financial.interestrate.bond.provider.BondSecurityDiscountingMethod; import com.opengamma.analytics.financial.interestrate.bond.provider.BondTransactionDiscountingMethod; import com.opengamma.analytics.financial.provider.calculator.discounting.PV01CurveParametersCalculator; import com.opengamma.analytics.financial.provider.calculator.generic.MarketQuoteSensitivityBlockCalculator; import com.opengamma.analytics.financial.provider.calculator.issuer.PresentValueCurveSensitivityIssuerCalculator; import com.opengamma.analytics.financial.provider.calculator.issuer.PresentValueIssuerCalculator; import com.opengamma.analytics.financial.provider.calculator.issuer.ZSpreadIssuerCalculator; import com.opengamma.analytics.financial.provider.curve.CurveBuildingBlockBundle; import com.opengamma.analytics.financial.provider.description.interestrate.IssuerProviderInterface; import com.opengamma.analytics.financial.provider.description.interestrate.ParameterIssuerProviderInterface; 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.core.value.MarketDataRequirementNames; import com.opengamma.financial.analytics.DoubleLabelledMatrix1D; import com.opengamma.financial.analytics.conversion.BondAndBondFutureTradeConverter; import com.opengamma.financial.analytics.model.fixedincome.BucketedCurveSensitivities; import com.opengamma.sesame.CurveMatrixLabeller; import com.opengamma.sesame.Environment; import com.opengamma.sesame.marketdata.FieldName; import com.opengamma.sesame.marketdata.MarketDataFn; import com.opengamma.sesame.trade.BondTrade; 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.ObjectsPair; import com.opengamma.util.tuple.Pair; /** * Discounting calculator for bond. * * @deprecated use {@link DiscountingBondFn} instead of {@link DefaultBondFn}, the calculator and factory */ @Deprecated public class DiscountingBondCalculator implements BondCalculator { /** Calculator for PV from curves */ private static final PresentValueIssuerCalculator PVIC = PresentValueIssuerCalculator.getInstance(); /** Calculators for PV, yield and price from yield, clean price or yield */ private static final BondTransactionDiscountingMethod BTDM = BondTransactionDiscountingMethod.getInstance(); private static final BondSecurityDiscountingMethod BSDM = BondSecurityDiscountingMethod.getInstance(); private static final PV01CurveParametersCalculator<ParameterIssuerProviderInterface> PV01C = new PV01CurveParametersCalculator<>(PresentValueCurveSensitivityIssuerCalculator.getInstance()); private static final PresentValueCurveSensitivityIssuerCalculator PVCSDC = PresentValueCurveSensitivityIssuerCalculator.getInstance(); private static final ParameterSensitivityParameterCalculator<ParameterIssuerProviderInterface> PSC = new ParameterSensitivityParameterCalculator<>(PVCSDC); private static final MarketQuoteSensitivityBlockCalculator<ParameterIssuerProviderInterface> MQSBC = new MarketQuoteSensitivityBlockCalculator<>(PSC); private static final ZSpreadIssuerCalculator ZSC = ZSpreadIssuerCalculator.getInstance(); private static final YieldFromCleanPriceCalculator YFCPC = YieldFromCleanPriceCalculator.getInstance(); private static final double BASIS_POINT_FACTOR = 1.0E-4; private final BondFixedTransaction _derivative; private final ParameterIssuerProviderInterface _curves; private final CurveBuildingBlockBundle _blocks; private final Map<String, CurveMatrixLabeller> _curveLabellers; private final MarketDataFn _marketDataFn; private final Environment _env; private BondTrade _trade; /** * Creates a calculator for a InterestRateSwapSecurity. * * @param trade the bond trade to calculate values for * @param curves the ParameterIssuerProviderInterface * @param blocks the CurveBuildingBlockBundle * @param converter the BondAndBondFutureTradeConverter * @param env the Environment * @param curveLabellers the curve labellers * @param marketDataFn the Market Data Function */ public DiscountingBondCalculator(BondTrade trade, ParameterIssuerProviderInterface curves, CurveBuildingBlockBundle blocks, BondAndBondFutureTradeConverter converter, Environment env, Map<String, CurveMatrixLabeller> curveLabellers, MarketDataFn marketDataFn) { ArgumentChecker.notNull(converter, "converter"); _trade = ArgumentChecker.notNull(trade, "trade"); _env = ArgumentChecker.notNull(env, "valuationTime"); _blocks = ArgumentChecker.notNull(blocks, "blocks"); _curves = ArgumentChecker.notNull(curves, "curves"); _marketDataFn = ArgumentChecker.notNull(marketDataFn, "marketDataFn"); _curveLabellers = ArgumentChecker.notNull(curveLabellers, "curveLabellers"); _derivative = createInstrumentDerivative(trade, converter, env.getValuationTime()); } @Override public Result<MultipleCurrencyAmount> calculatePresentValueFromCurves() { return Result.success(_derivative.accept(PVIC, _curves)); } @Override public Result<MultipleCurrencyAmount> calculatePresentValueFromClean() { Result<Double> marketResult = calculateCleanPriceMarket(); if (marketResult.isSuccess()) { return Result.success(BTDM.presentValueFromCleanPrice(_derivative, _curves.getIssuerProvider(), marketResult.getValue())); } else { return Result.failure(marketResult); } } @Override public Result<MultipleCurrencyAmount> calculatePresentValueFromYield() { Result<Double> marketYield = calculateYieldToMaturityMarket(); if (marketYield.isSuccess()) { return Result.success(BTDM.presentValueFromYield(_derivative, _curves.getIssuerProvider(), marketYield.getValue())); } else { return Result.failure(marketYield); } } @Override public Result<Double> calculateCleanPriceMarket() { return _marketDataFn.getMarketValue(_env, _trade.getSecurity()); } @Override public Result<Double> calculateCleanPriceFromCurves() { return Result.success(BSDM.cleanPriceFromCurves(_derivative.getBondStandard(), _curves.getIssuerProvider())); } @Override public Result<Double> calculateCleanPriceFromYield() { Result<Double> marketYield = calculateYieldToMaturityMarket(); if (marketYield.isSuccess()) { return Result.success(BSDM.cleanPriceFromYield(_derivative.getBondStandard(), marketYield.getValue())); } else { return Result.failure(marketYield); } } @Override public Result<Double> calculateYieldToMaturityFromCleanPrice() { Result<Double> marketCleanPrice = calculateCleanPriceMarket(); if (marketCleanPrice.isSuccess()) { return Result.success(BSDM.yieldFromCleanPrice(_derivative.getBondStandard(), marketCleanPrice.getValue())); } else { return Result.failure(marketCleanPrice); } } @Override public Result<Double> calculateYieldToMaturityFromCurves() { return Result.success(BSDM.yieldFromCurves(_derivative.getBondStandard(), _curves.getIssuerProvider())); } @Override public Result<Double> calculateYieldToMaturityMarket() { FieldName fieldName = FieldName.of(MarketDataRequirementNames.YIELD_YIELD_TO_MATURITY_MID); return _marketDataFn.getValue(_env, _trade.getSecurity(), fieldName, Double.class); } @Override public Result<BucketedCurveSensitivities> calculateBucketedPV01() { MultipleCurrencyParameterSensitivity sensitivity = MQSBC .fromInstrument(_derivative, _curves, _blocks) .multipliedBy(BASIS_POINT_FACTOR); Map<Pair<String, Currency>, DoubleLabelledMatrix1D> labelledMatrix1DMap = new HashMap<>(); for (Map.Entry<Pair<String, Currency>, DoubleMatrix1D> entry : sensitivity.getSensitivities().entrySet()) { CurveMatrixLabeller labeller = _curveLabellers.get(entry.getKey().getFirst()); DoubleLabelledMatrix1D matrix = labeller.labelMatrix(entry.getValue()); labelledMatrix1DMap.put(entry.getKey(), matrix); } return Result.success(BucketedCurveSensitivities.of(labelledMatrix1DMap)); } @Override public Result<ReferenceAmount<Pair<String, Currency>>> calculatePV01() { return Result.success(_derivative.accept(PV01C, _curves)); } @Override public Result<Double> calculateZSpread() { Result<Double> marketResult = calculateCleanPriceMarket(); if (marketResult.isSuccess()) { ObjectsPair<IssuerProviderInterface, Double> pair = ObjectsPair.of(_curves.getIssuerProvider(), marketResult.getValue()); return Result.success(_derivative.accept(ZSC, pair)); } else { return Result.failure(marketResult); } } private BondFixedTransaction createInstrumentDerivative(BondTrade bondTrade, BondAndBondFutureTradeConverter converter, ZonedDateTime valuationTime) { InstrumentDefinition<?> definition = converter.convert(bondTrade.getTrade()); return ((BondFixedTransactionDefinition) definition).toDerivative(valuationTime); } }