/**
* Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.interestrate.bond.provider;
import static org.testng.AssertJUnit.assertEquals;
import java.util.LinkedHashMap;
import org.testng.annotations.Test;
import org.threeten.bp.ZonedDateTime;
import com.opengamma.analytics.financial.instrument.bond.BondDataSetsGbp;
import com.opengamma.analytics.financial.instrument.bond.BondFixedSecurityDefinition;
import com.opengamma.analytics.financial.instrument.bond.BondFixedTransactionDefinition;
import com.opengamma.analytics.financial.interestrate.bond.definition.BondFixedTransaction;
import com.opengamma.analytics.financial.interestrate.datasets.StandardDataSetsBondCurveGBP;
import com.opengamma.analytics.financial.interestrate.datasets.StandardDataSetsMulticurveGBP;
import com.opengamma.analytics.financial.legalentity.LegalEntity;
import com.opengamma.analytics.financial.legalentity.LegalEntityFilter;
import com.opengamma.analytics.financial.legalentity.LegalEntityShortName;
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.curve.CurveBuildingBlockBundle;
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.ParameterIssuerProviderInterface;
import com.opengamma.analytics.financial.provider.sensitivity.multicurve.MultipleCurrencyParameterSensitivity;
import com.opengamma.analytics.financial.provider.sensitivity.parameter.ParameterSensitivityParameterCalculator;
import com.opengamma.analytics.financial.util.AssertSensitivityObjects;
import com.opengamma.analytics.math.matrix.DoubleMatrix1D;
import com.opengamma.util.money.Currency;
import com.opengamma.util.money.MultipleCurrencyAmount;
import com.opengamma.util.test.TestGroup;
import com.opengamma.util.time.DateUtils;
import com.opengamma.util.tuple.ObjectsPair;
import com.opengamma.util.tuple.Pair;
import com.opengamma.util.tuple.Pairs;
/**
* Tests on (fixed coupon) bonds with static data. Data available also in interface unit test and in snapshots.
*/
@Test(groups = TestGroup.UNIT)
public class BondFixedTransactionDiscountingMethodE2ETest {
private static final Currency GBP = Currency.GBP;
private static final ZonedDateTime CALIBRATION_DATE = DateUtils.getUTCDate(2014, 7, 11);
// Curve calibrated on swaps (OIS)
private static final Pair<MulticurveProviderDiscount, CurveBuildingBlockBundle> MULTICURVE_SWAP_PAIR =
StandardDataSetsMulticurveGBP.getCurvesGBPSonia(CALIBRATION_DATE);
private static final MulticurveProviderDiscount MULTICURVE_SWAP = MULTICURVE_SWAP_PAIR.getFirst();
private static final CurveBuildingBlockBundle BLOCK_SWAP = MULTICURVE_SWAP_PAIR.getSecond();
// Curve calibrated with bills and bonds.
private static final Pair<IssuerProviderDiscount, CurveBuildingBlockBundle> ISSUER_GOVT_PAIR =
StandardDataSetsBondCurveGBP.getCurvesGBPSoniaGovt(CALIBRATION_DATE);
private static final IssuerProviderDiscount ISSUER_GOVT = ISSUER_GOVT_PAIR.getFirst();
private static final CurveBuildingBlockBundle BLOCK_GOVT = ISSUER_GOVT_PAIR.getSecond();
// Bond description
private static final BondFixedSecurityDefinition UKT_800_20210607_SEC_DEF = BondDataSetsGbp.bondUKT800_20210607(1.0);
private static final String NAME_ISSUER = UKT_800_20210607_SEC_DEF.getIssuer();
private static final IssuerProviderDiscount ISSUER_SWAP = new IssuerProviderDiscount(MULTICURVE_SWAP);
static {
ISSUER_SWAP.setCurve(Pairs.of((Object) NAME_ISSUER, (LegalEntityFilter<LegalEntity>)
new LegalEntityShortName()), MULTICURVE_SWAP.getCurve(GBP));
}
private static final double QUANTITY_UKT_800_20210607 = 10000000; // 10m
private static final double TRADE_PRICE_800_20210607 = 0.99;
private static final ZonedDateTime SETTLE_DATE_UKT_800_20210607_SPOT = DateUtils.getUTCDate(2014, 7, 16);
private static final ZonedDateTime SETTLE_DATE_UKT_800_20210607_PAST = DateUtils.getUTCDate(2014, 7, 10);
private static final ZonedDateTime SETTLE_DATE_UKT_800_20210607_FWD = DateUtils.getUTCDate(2014, 7, 25);
private static final BondFixedTransactionDefinition UKT_800_20210607_TRA_SPOT_DEF =
new BondFixedTransactionDefinition(UKT_800_20210607_SEC_DEF, QUANTITY_UKT_800_20210607,
SETTLE_DATE_UKT_800_20210607_SPOT, TRADE_PRICE_800_20210607);
private static final BondFixedTransactionDefinition UKT_800_20210607_TRA_PAST_DEF =
new BondFixedTransactionDefinition(UKT_800_20210607_SEC_DEF, QUANTITY_UKT_800_20210607,
SETTLE_DATE_UKT_800_20210607_PAST, TRADE_PRICE_800_20210607);
private static final BondFixedTransactionDefinition UKT_800_20210607_TRA_FWD_DEF =
new BondFixedTransactionDefinition(UKT_800_20210607_SEC_DEF, QUANTITY_UKT_800_20210607,
SETTLE_DATE_UKT_800_20210607_FWD, TRADE_PRICE_800_20210607);
private static final BondFixedTransaction UKT_800_20210607_TRA_SPOT =
UKT_800_20210607_TRA_SPOT_DEF.toDerivative(CALIBRATION_DATE);
private static final BondFixedTransaction UKT_800_20210607_TRA_PAST =
UKT_800_20210607_TRA_PAST_DEF.toDerivative(CALIBRATION_DATE);
private static final BondFixedTransaction UKT_800_20210607_TRA_FWD =
UKT_800_20210607_TRA_FWD_DEF.toDerivative(CALIBRATION_DATE);
// Calculator and methods
private static final PresentValueIssuerCalculator PVIC = PresentValueIssuerCalculator.getInstance();
private static final BondTransactionDiscountingMethod METHOD_BOND_TRA =
BondTransactionDiscountingMethod.getInstance();
private static final BondSecurityDiscountingMethod METHOD_BOND_SEC =
BondSecurityDiscountingMethod.getInstance();
private static final PresentValueCurveSensitivityIssuerCalculator PVCSIC =
PresentValueCurveSensitivityIssuerCalculator.getInstance();
private static final ParameterSensitivityParameterCalculator<ParameterIssuerProviderInterface> PSC =
new ParameterSensitivityParameterCalculator<>(PVCSIC);
private static final MarketQuoteSensitivityBlockCalculator<ParameterIssuerProviderInterface> MQSBC =
new MarketQuoteSensitivityBlockCalculator<>(PSC);
private static final double BOND_QUOTED_CLEAN_PRICE = 1.40;
private static final double BOND_QUOTED_YIELD = 0.018;
private static final double TOLERANCE_PV = 1.0E-4;
private static final double TOLERANCE_PV_DELTA = 1.0E-2;
private static final double TOLERANCE_YIELD = 1.0E-6;
private static final double TOLERANCE_PRICE = 1.0E-6;
private static final double BP1 = 1.0E-4;
/** Curve calibrated on swaps (OIS) */
@Test
public void presentValueCurveOis() {
double pvExpected1 = 4079490.1191;
MultipleCurrencyAmount pvComputed1 = UKT_800_20210607_TRA_SPOT.accept(PVIC, ISSUER_SWAP);
assertEquals("BondFixedTransactionDiscountingMethodE2ETest", pvExpected1, pvComputed1.getAmount(GBP), TOLERANCE_PV);
double pvExpected2 = 14064158.3895;
MultipleCurrencyAmount pvComputed2 = UKT_800_20210607_TRA_PAST.accept(PVIC, ISSUER_SWAP);
assertEquals("BondFixedTransactionDiscountingMethodE2ETest", pvExpected2, pvComputed2.getAmount(GBP), TOLERANCE_PV);
double pvExpected3 = 4060862.9747;
MultipleCurrencyAmount pvComputed3 = UKT_800_20210607_TRA_FWD.accept(PVIC, ISSUER_SWAP);
assertEquals("BondFixedTransactionDiscountingMethodE2ETest", pvExpected3, pvComputed3.getAmount(GBP), TOLERANCE_PV);
}
@Test
public void presentValuePriceOis() {
double pvExpected1 = 4095717.0907;
MultipleCurrencyAmount pvComputed1 =
METHOD_BOND_TRA.presentValueFromCleanPrice(UKT_800_20210607_TRA_SPOT, ISSUER_SWAP, BOND_QUOTED_CLEAN_PRICE);
assertEquals("BondFixedTransactionDiscountingMethodE2ETest", pvExpected1, pvComputed1.getAmount(GBP), TOLERANCE_PV);
double pvExpected2 = 14080385.3611;
MultipleCurrencyAmount pvComputed2 =
METHOD_BOND_TRA.presentValueFromCleanPrice(UKT_800_20210607_TRA_PAST, ISSUER_SWAP, BOND_QUOTED_CLEAN_PRICE);
assertEquals("BondFixedTransactionDiscountingMethodE2ETest", pvExpected2, pvComputed2.getAmount(GBP), TOLERANCE_PV);
double pvExpected3 = 4077089.9463;
MultipleCurrencyAmount pvComputed3 =
METHOD_BOND_TRA.presentValueFromCleanPrice(UKT_800_20210607_TRA_FWD, ISSUER_SWAP, BOND_QUOTED_CLEAN_PRICE);
assertEquals("BondFixedTransactionDiscountingMethodE2ETest", pvExpected3, pvComputed3.getAmount(GBP), TOLERANCE_PV);
}
@Test
public void presentValueYieldOis() {
double pvExpected1 = 4100927.5796;
MultipleCurrencyAmount pvComputed1 =
METHOD_BOND_TRA.presentValueFromYield(UKT_800_20210607_TRA_SPOT, ISSUER_SWAP, BOND_QUOTED_YIELD);
assertEquals("BondFixedTransactionDiscountingMethodE2ETest", pvExpected1, pvComputed1.getAmount(GBP), TOLERANCE_PV);
double pvExpected2 = 14085595.8500;
MultipleCurrencyAmount pvComputed2 =
METHOD_BOND_TRA.presentValueFromYield(UKT_800_20210607_TRA_PAST, ISSUER_SWAP, BOND_QUOTED_YIELD);
assertEquals("BondFixedTransactionDiscountingMethodE2ETest", pvExpected2, pvComputed2.getAmount(GBP), TOLERANCE_PV);
double pvExpected3 = 4082300.4352;
MultipleCurrencyAmount pvComputed3 =
METHOD_BOND_TRA.presentValueFromYield(UKT_800_20210607_TRA_FWD, ISSUER_SWAP, BOND_QUOTED_YIELD);
assertEquals("BondFixedTransactionDiscountingMethodE2ETest", pvExpected3, pvComputed3.getAmount(GBP), TOLERANCE_PV);
}
@Test
public void priceCurveOis() {
double priceExpected = 1.39837725; // Clean price
double priceComputed1 = METHOD_BOND_SEC.cleanPriceFromCurves(UKT_800_20210607_TRA_SPOT.getBondStandard(), ISSUER_SWAP);
assertEquals("BondFixedTransactionDiscountingMethodE2ETest", priceExpected, priceComputed1, TOLERANCE_PRICE);
double priceComputed2 = METHOD_BOND_SEC.cleanPriceFromCurves(UKT_800_20210607_TRA_PAST.getBondStandard(), ISSUER_SWAP);
assertEquals("BondFixedTransactionDiscountingMethodE2ETest", priceExpected, priceComputed2, TOLERANCE_PRICE);
double priceComputed3 = METHOD_BOND_SEC.cleanPriceFromCurves(UKT_800_20210607_TRA_FWD.getBondStandard(), ISSUER_SWAP);
assertEquals("BondFixedTransactionDiscountingMethodE2ETest", priceExpected, priceComputed3, TOLERANCE_PRICE);
}
@Test
public void priceYield() {
double priceExpected = 1.4005210670; // Clean price
double priceComputed1 = METHOD_BOND_SEC.cleanPriceFromYield(UKT_800_20210607_TRA_SPOT.getBondStandard(), BOND_QUOTED_YIELD);
assertEquals("BondFixedTransactionDiscountingMethodE2ETest", priceExpected, priceComputed1, TOLERANCE_PRICE);
double priceComputed2 = METHOD_BOND_SEC.cleanPriceFromYield(UKT_800_20210607_TRA_PAST.getBondStandard(), BOND_QUOTED_YIELD);
assertEquals("BondFixedTransactionDiscountingMethodE2ETest", priceExpected, priceComputed2, TOLERANCE_PRICE);
double priceComputed3 = METHOD_BOND_SEC.cleanPriceFromYield(UKT_800_20210607_TRA_FWD.getBondStandard(), BOND_QUOTED_YIELD);
assertEquals("BondFixedTransactionDiscountingMethodE2ETest", priceExpected, priceComputed3, TOLERANCE_PRICE);
}
@Test
public void yieldCurveOis() {
double yieldExpected = 0.0182715311;
double yieldComputed = METHOD_BOND_SEC.yieldFromCurves(UKT_800_20210607_TRA_SPOT.getBondStandard(), ISSUER_SWAP);
assertEquals("BondFixedTransactionDiscountingMethodE2ETest", yieldExpected, yieldComputed, TOLERANCE_YIELD);
}
@Test
public void yieldPrice() {
double yieldExpected = 0.0180659508;
double yieldComputed = METHOD_BOND_SEC.yieldFromCleanPrice(UKT_800_20210607_TRA_SPOT.getBondStandard(), BOND_QUOTED_CLEAN_PRICE);
assertEquals("BondFixedTransactionDiscountingMethodE2ETest", yieldExpected, yieldComputed, TOLERANCE_YIELD);
}
@Test
public void BucketedPV01Ois() {
final double[] deltaDsc = {
9.8781,3.2928,0.4993,0.2126,-6.5819,-9.8512,-13.9385,-38.6992,-111.4245,-167.3524,
-223.7036,-278.8639,-961.1644,-6113.7830,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000 };
final LinkedHashMap<Pair<String, Currency>, DoubleMatrix1D> sensitivity = new LinkedHashMap<>();
sensitivity.put(
ObjectsPair.of(ISSUER_SWAP.getName(UKT_800_20210607_SEC_DEF.getIssuerEntity()), GBP), new DoubleMatrix1D(deltaDsc));
final MultipleCurrencyParameterSensitivity pvpsExpected = new MultipleCurrencyParameterSensitivity(sensitivity);
final MultipleCurrencyParameterSensitivity pvpsComputed =
MQSBC.fromInstrument(UKT_800_20210607_TRA_SPOT, ISSUER_SWAP, BLOCK_SWAP).multipliedBy(BP1);
AssertSensitivityObjects.assertEquals(
"BondFixedTransactionDiscountingMethodE2ETest: bucketed deltas from standard curves",
pvpsExpected, pvpsComputed, TOLERANCE_PV_DELTA);
}
/** Curve calibrated with bills and bonds. */
@Test
public void presentValueCurveGovt() {
double pvExpectedGSpot = 4045194.6254;
MultipleCurrencyAmount pvComputedGSpot = UKT_800_20210607_TRA_SPOT.accept(PVIC, ISSUER_GOVT);
assertEquals("BondFixedTransactionDiscountingMethodE2ETest",
pvExpectedGSpot, pvComputedGSpot.getAmount(GBP), TOLERANCE_PV);
double pvExpectedGPast = 14029862.8957;
MultipleCurrencyAmount pvComputedGPast = UKT_800_20210607_TRA_PAST.accept(PVIC, ISSUER_GOVT);
assertEquals("BondFixedTransactionDiscountingMethodE2ETest",
pvExpectedGPast, pvComputedGPast.getAmount(GBP), TOLERANCE_PV);
double pvExpectedGFwd = 4026567.4809;
MultipleCurrencyAmount pvComputedGFwd = UKT_800_20210607_TRA_FWD.accept(PVIC, ISSUER_GOVT);
assertEquals("BondFixedTransactionDiscountingMethodE2ETest",
pvExpectedGFwd, pvComputedGFwd.getAmount(GBP), TOLERANCE_PV);
}
@Test
public void BucketedPV01Govt() {
final double[] deltaDsc = {
-2.9421,3.2927,0.5064,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,
0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000
};
final double[] deltaGovt = {-4.1797,-25.1585,186.5606,899.7372,393.5744 };
final LinkedHashMap<Pair<String, Currency>, DoubleMatrix1D> sensitivity = new LinkedHashMap<>();
sensitivity.put(ObjectsPair.of(ISSUER_GOVT.getMulticurveProvider().getName(GBP), GBP), new DoubleMatrix1D(deltaDsc));
sensitivity.put(
ObjectsPair.of(ISSUER_GOVT.getName(UKT_800_20210607_SEC_DEF.getIssuerEntity()), GBP), new DoubleMatrix1D(deltaGovt));
final MultipleCurrencyParameterSensitivity pvpsExpected = new MultipleCurrencyParameterSensitivity(sensitivity);
final MultipleCurrencyParameterSensitivity pvpsComputed =
MQSBC.fromInstrument(UKT_800_20210607_TRA_SPOT, ISSUER_GOVT, BLOCK_GOVT).multipliedBy(BP1);
AssertSensitivityObjects.assertEquals(
"BondFixedTransactionDiscountingMethodE2ETest: bucketed deltas from standard curves",
pvpsExpected, pvpsComputed, TOLERANCE_PV_DELTA);
}
}