/**
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.pricer.bond;
import static com.opengamma.strata.basics.currency.Currency.USD;
import static com.opengamma.strata.pricer.CompoundedRateType.CONTINUOUS;
import static com.opengamma.strata.pricer.CompoundedRateType.PERIODIC;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;
import com.opengamma.strata.basics.ReferenceData;
import com.opengamma.strata.basics.currency.CurrencyAmount;
import com.opengamma.strata.collect.array.DoubleArray;
import com.opengamma.strata.market.curve.CurveMetadata;
import com.opengamma.strata.market.param.CurrencyParameterSensitivities;
import com.opengamma.strata.market.sensitivity.PointSensitivities;
import com.opengamma.strata.pricer.datasets.LegalEntityDiscountingProviderDataSets;
import com.opengamma.strata.pricer.sensitivity.RatesFiniteDifferenceSensitivityCalculator;
import com.opengamma.strata.product.bond.ResolvedBondFuture;
import com.opengamma.strata.product.bond.ResolvedFixedCouponBond;
/**
* Test {@link DiscountingBondFutureProductPricer}.
*/
@Test
public class DiscountingBondFutureProductPricerTest {
private static final ReferenceData REF_DATA = ReferenceData.standard();
// product
private static final ResolvedBondFuture FUTURE_PRODUCT = BondDataSets.FUTURE_PRODUCT_USD.resolve(REF_DATA);
private static final ResolvedFixedCouponBond BOND = BondDataSets.BOND_USD[0].resolve(REF_DATA);
private static final Double[] CONVERSION_FACTOR = BondDataSets.CONVERSION_FACTOR_USD.clone();
// curves
private static final LegalEntityDiscountingProvider PROVIDER = LegalEntityDiscountingProviderDataSets.ISSUER_REPO_ZERO;
private static final CurveMetadata METADATA_ISSUER = LegalEntityDiscountingProviderDataSets.META_ZERO_ISSUER_USD;
private static final CurveMetadata METADATA_REPO = LegalEntityDiscountingProviderDataSets.META_ZERO_REPO_USD;
// parameters
private static final double Z_SPREAD = 0.0075;
private static final int PERIOD_PER_YEAR = 4;
private static final double TOL = 1.0e-12;
private static final double EPS = 1.0e-6;
// pricer
private static final DiscountingBondFutureProductPricer FUTURE_PRICER = DiscountingBondFutureProductPricer.DEFAULT;
private static final DiscountingFixedCouponBondProductPricer BOND_PRICER = DiscountingFixedCouponBondProductPricer.DEFAULT;
private static final RatesFiniteDifferenceSensitivityCalculator FD_CAL = new RatesFiniteDifferenceSensitivityCalculator(EPS);
//-------------------------------------------------------------------------
public void test_price() {
double computed = FUTURE_PRICER.price(FUTURE_PRODUCT, PROVIDER);
double dirtyPrice = BOND_PRICER.dirtyPriceFromCurves(
BOND,
PROVIDER,
FUTURE_PRODUCT.getLastDeliveryDate());
double expected = BOND_PRICER.cleanPriceFromDirtyPrice(
BOND,
FUTURE_PRODUCT.getLastDeliveryDate(), dirtyPrice) / CONVERSION_FACTOR[0];
assertEquals(computed, expected, TOL);
}
public void test_priceWithZSpread_continuous() {
double computed = FUTURE_PRICER.priceWithZSpread(FUTURE_PRODUCT, PROVIDER, Z_SPREAD, CONTINUOUS, 0);
double dirtyPrice = BOND_PRICER.dirtyPriceFromCurvesWithZSpread(
BOND,
PROVIDER,
Z_SPREAD,
CONTINUOUS,
0,
FUTURE_PRODUCT.getLastDeliveryDate());
double expected = BOND_PRICER.cleanPriceFromDirtyPrice(
BOND,
FUTURE_PRODUCT.getLastDeliveryDate(), dirtyPrice) / CONVERSION_FACTOR[0];
assertEquals(computed, expected, TOL);
}
public void test_priceWithZSpread_periodic() {
double computed = FUTURE_PRICER.priceWithZSpread(FUTURE_PRODUCT, PROVIDER, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR);
double dirtyPrice = BOND_PRICER.dirtyPriceFromCurvesWithZSpread(
BOND,
PROVIDER,
Z_SPREAD,
PERIODIC,
PERIOD_PER_YEAR,
FUTURE_PRODUCT.getLastDeliveryDate());
double expected = BOND_PRICER.cleanPriceFromDirtyPrice(
BOND,
FUTURE_PRODUCT.getLastDeliveryDate(), dirtyPrice) / CONVERSION_FACTOR[0];
assertEquals(computed, expected, TOL);
}
//-------------------------------------------------------------------------
public void test_priceSensitivity() {
PointSensitivities point = FUTURE_PRICER.priceSensitivity(FUTURE_PRODUCT, PROVIDER);
CurrencyParameterSensitivities computed = PROVIDER.parameterSensitivity(point);
CurrencyParameterSensitivities expected = FD_CAL.sensitivity(PROVIDER,
(p) -> CurrencyAmount.of(USD, FUTURE_PRICER.price(FUTURE_PRODUCT, (p))));
assertTrue(computed.equalWithTolerance(expected, EPS * 10.0));
}
public void test_priceSensitivityWithZSpread_continuous() {
PointSensitivities point = FUTURE_PRICER.priceSensitivityWithZSpread(
FUTURE_PRODUCT, PROVIDER, Z_SPREAD, CONTINUOUS, 0);
CurrencyParameterSensitivities computed = PROVIDER.parameterSensitivity(point);
CurrencyParameterSensitivities expected = FD_CAL.sensitivity(PROVIDER,
(p) -> CurrencyAmount.of(USD, FUTURE_PRICER.priceWithZSpread(FUTURE_PRODUCT, (p), Z_SPREAD, CONTINUOUS, 0)));
assertTrue(computed.equalWithTolerance(expected, EPS * 10.0));
}
public void test_priceSensitivityWithZSpread_periodic() {
PointSensitivities point = FUTURE_PRICER.priceSensitivityWithZSpread(
FUTURE_PRODUCT, PROVIDER, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR);
CurrencyParameterSensitivities computed = PROVIDER.parameterSensitivity(point);
CurrencyParameterSensitivities expected = FD_CAL.sensitivity(PROVIDER, (p) -> CurrencyAmount.of(
USD, FUTURE_PRICER.priceWithZSpread(FUTURE_PRODUCT, (p), Z_SPREAD, PERIODIC, PERIOD_PER_YEAR)));
assertTrue(computed.equalWithTolerance(expected, EPS * 10.0));
}
//-------------------------------------------------------------------------
// regression to 2.x
public void regression() {
double price = FUTURE_PRICER.price(FUTURE_PRODUCT, PROVIDER);
assertEquals(price, 1.2106928633440506, TOL);
PointSensitivities point = FUTURE_PRICER.priceSensitivity(FUTURE_PRODUCT, PROVIDER);
CurrencyParameterSensitivities test = PROVIDER.parameterSensitivity(point);
DoubleArray expectedIssuer = DoubleArray.of(
-3.940585873921608E-4, -0.004161527192990392, -0.014331606019672717, -1.0229665443857998, -4.220553063715371, 0);
DoubleArray actualIssuer = test.getSensitivity(METADATA_ISSUER.getCurveName(), USD).getSensitivity();
assertTrue(actualIssuer.equalWithTolerance(expectedIssuer, TOL));
DoubleArray expectedRepo = DoubleArray.of(0.14752541809405412, 0.20907575809356016, 0.0, 0.0, 0.0, 0.0);
DoubleArray actualRepo = test.getSensitivity(METADATA_REPO.getCurveName(), USD).getSensitivity();
assertTrue(actualRepo.equalWithTolerance(expectedRepo, TOL));
}
public void regression_withZSpread_continuous() {
double price = FUTURE_PRICER.priceWithZSpread(FUTURE_PRODUCT, PROVIDER, Z_SPREAD, CONTINUOUS, 0);
assertEquals(price, 1.1718691843665354, TOL);
// curve parameter sensitivity is not supported for continuous z-spread in 2.x.
}
public void regression_withZSpread_periodic() {
double price = FUTURE_PRICER.priceWithZSpread(FUTURE_PRODUCT, PROVIDER, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR);
assertEquals(price, 1.1720190529653407, TOL);
PointSensitivities point =
FUTURE_PRICER.priceSensitivityWithZSpread(FUTURE_PRODUCT, PROVIDER, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR);
CurrencyParameterSensitivities test = PROVIDER.parameterSensitivity(point);
DoubleArray expectedIssuer = DoubleArray.of(
-3.9201229100932256E-4, -0.0041367134351306374, -0.014173323438217467, -0.9886444827927878, -4.07533109609094, 0);
DoubleArray actualIssuer = test.getSensitivity(METADATA_ISSUER.getCurveName(), USD).getSensitivity();
assertTrue(actualIssuer.equalWithTolerance(expectedIssuer, TOL));
DoubleArray expectedRepo = DoubleArray.of(0.1428352116441475, 0.20242871054203687, 0.0, 0.0, 0.0, 0.0);
DoubleArray actualRepo = test.getSensitivity(METADATA_REPO.getCurveName(), USD).getSensitivity();
assertTrue(actualRepo.equalWithTolerance(expectedRepo, TOL));
}
}