private void calibration_market_quote_sensitivity_check( Function<MarketData, ImmutableRatesProvider> calibrator, double shift) { double notional = 100_000_000.0; double fx = 1.1111; double fxPts = 0.0012; FxSwapTrade trade = EUR_USD.toTrade( VAL_DATE, Period.ofWeeks(6), Period.ofMonths(5), BuySell.BUY, notional, fx, fxPts); ImmutableRatesProvider result = CALIBRATOR.calibrate(CURVE_GROUP_CONFIG, VAL_DATE, ALL_QUOTES, TS); PointSensitivities pts = FX_PRICER.presentValueSensitivity(trade.getProduct(), result); CurveCurrencyParameterSensitivities ps = result.curveParameterSensitivity(pts); CurveCurrencyParameterSensitivities mqs = MQC.sensitivity(ps, result); double pvUsd = FX_PRICER.presentValue(trade.getProduct(), result).getAmount(USD).getAmount(); double pvEur = FX_PRICER.presentValue(trade.getProduct(), result).getAmount(EUR).getAmount(); double[] mqsUsd1Computed = mqs.getSensitivity(USD_DSCON_CURVE_NAME, USD).getSensitivity().toArray(); for (int i = 0; i < USD_DSC_NB_NODES; i++) { Map<MarketDataKey<?>, Object> map = new HashMap<>(ALL_QUOTES.getValues()); map.put( QuoteKey.of(StandardId.of(SCHEME, USD_DSC_ID_VALUE[i])), USD_DSC_MARKET_QUOTES[i] + shift); ImmutableMarketData marketData = ImmutableMarketData.of(map); ImmutableRatesProvider rpShifted = calibrator.apply(marketData); double pvS = FX_PRICER.presentValue(trade.getProduct(), rpShifted).getAmount(USD).getAmount(); assertEquals(mqsUsd1Computed[i], (pvS - pvUsd) / shift, TOLERANCE_PV_DELTA); } double[] mqsUsd2Computed = mqs.getSensitivity(USD_DSCON_CURVE_NAME, EUR).getSensitivity().toArray(); for (int i = 0; i < USD_DSC_NB_NODES; i++) { Map<MarketDataKey<?>, Object> map = new HashMap<>(ALL_QUOTES.getValues()); map.put( QuoteKey.of(StandardId.of(SCHEME, USD_DSC_ID_VALUE[i])), USD_DSC_MARKET_QUOTES[i] + shift); ImmutableMarketData ov = ImmutableMarketData.of(map); ImmutableRatesProvider rpShifted = calibrator.apply(ov); double pvS = FX_PRICER.presentValue(trade.getProduct(), rpShifted).getAmount(EUR).getAmount(); assertEquals(mqsUsd2Computed[i], (pvS - pvEur) / shift, TOLERANCE_PV_DELTA); } double[] mqsEur1Computed = mqs.getSensitivity(EUR_DSC_CURVE_NAME, USD).getSensitivity().toArray(); for (int i = 0; i < EUR_DSC_NB_NODES; i++) { assertEquals(mqsEur1Computed[i], 0.0, TOLERANCE_PV_DELTA); } double[] mqsEur2Computed = mqs.getSensitivity(EUR_DSC_CURVE_NAME, EUR).getSensitivity().toArray(); for (int i = 0; i < EUR_DSC_NB_NODES; i++) { Map<MarketDataKey<?>, Object> map = new HashMap<>(ALL_QUOTES.getValues()); map.put( QuoteKey.of(StandardId.of(SCHEME, EUR_DSC_ID_VALUE[i])), EUR_DSC_MARKET_QUOTES[i] + shift); ImmutableMarketData marketData = ImmutableMarketData.of(map); ImmutableRatesProvider rpShifted = calibrator.apply(marketData); double pvS = FX_PRICER.presentValue(trade.getProduct(), rpShifted).getAmount(EUR).getAmount(); assertEquals(mqsEur2Computed[i], (pvS - pvEur) / shift, TOLERANCE_PV_DELTA, "Node " + i); } }
static { Map<MarketDataKey<?>, Object> map = new HashMap<>(); for (int i = 0; i < USD_DSC_NB_NODES; i++) { map.put(QuoteKey.of(StandardId.of(SCHEME, USD_DSC_ID_VALUE[i])), USD_DSC_MARKET_QUOTES[i]); } for (int i = 0; i < EUR_DSC_NB_NODES; i++) { map.put(QuoteKey.of(StandardId.of(SCHEME, EUR_DSC_ID_VALUE[i])), EUR_DSC_MARKET_QUOTES[i]); } map.put(FxRateKey.of(EUR, USD), FX_RATE_EUR_USD); ALL_QUOTES = ImmutableMarketData.of(map); }
// ------------------------------------------------------------------------- @Override public FunctionRequirements requirements(GenericFutureOptionTrade trade) { QuoteKey key = QuoteKey.of(trade.getSecurity().getStandardId()); return FunctionRequirements.builder() .singleValueRequirements(ImmutableSet.of(key)) .outputCurrencies(trade.getProduct().getCurrency()) .build(); }
static { for (int i = 0; i < EUR_DSC_NB_FX_NODES; i++) { EUR_DSC_NODES[i] = FxSwapCurveNode.of( FxSwapTemplate.of(EUR_DSC_FX_TENORS[i], EUR_USD), QuoteKey.of(StandardId.of(SCHEME, EUR_DSC_ID_VALUE[i]))); } }
static { USD_DSC_NODES[0] = TermDepositCurveNode.of( TermDepositTemplate.of(Period.ofDays(1), USD_DEPOSIT_T0), QuoteKey.of(StandardId.of(SCHEME, USD_DSC_ID_VALUE[0]))); USD_DSC_NODES[1] = TermDepositCurveNode.of( TermDepositTemplate.of(Period.ofDays(1), USD_DEPOSIT_T1), QuoteKey.of(StandardId.of(SCHEME, USD_DSC_ID_VALUE[1]))); for (int i = 0; i < USD_DSC_NB_OIS_NODES; i++) { USD_DSC_NODES[USD_DSC_NB_DEPO_NODES + i] = FixedOvernightSwapCurveNode.of( FixedOvernightSwapTemplate.of( Period.ZERO, Tenor.of(USD_DSC_OIS_TENORS[i]), USD_FIXED_1Y_FED_FUND_OIS), QuoteKey.of(StandardId.of(SCHEME, USD_DSC_ID_VALUE[USD_DSC_NB_DEPO_NODES + i]))); } }
/** Test {@link CurveGroupEntry}. */ @Test public class CurveGroupEntryTest { private static final InterpolatedNodalCurveDefinition CURVE_DEFN = InterpolatedNodalCurveDefinition.builder() .name(CurveName.of("Test")) .xValueType(ValueType.YEAR_FRACTION) .yValueType(ValueType.ZERO_RATE) .dayCount(ACT_365F) .nodes( ImmutableList.of( DummyFraCurveNode.of( Period.ofMonths(1), GBP_LIBOR_1M, QuoteKey.of(StandardId.of("OG", "Ticker"))))) .interpolator(CurveInterpolators.LINEAR) .extrapolatorLeft(CurveExtrapolators.FLAT) .extrapolatorRight(CurveExtrapolators.FLAT) .build(); private static final InterpolatedNodalCurveDefinition CURVE_DEFN2 = CURVE_DEFN.toBuilder().name(CurveName.of("Test2")).build(); public void test_builder() { CurveGroupEntry test = CurveGroupEntry.builder() .curveDefinition(CURVE_DEFN) .discountCurrencies(GBP) .iborIndices(GBP_LIBOR_1M, GBP_LIBOR_3M) .overnightIndices(GBP_SONIA) .build(); assertEquals(test.getCurveDefinition(), CURVE_DEFN); assertEquals(test.getDiscountCurrencies(), ImmutableSet.of(GBP)); assertEquals(test.getIborIndices(), ImmutableSet.of(GBP_LIBOR_1M, GBP_LIBOR_3M)); assertEquals(test.getOvernightIndices(), ImmutableSet.of(GBP_SONIA)); } // ------------------------------------------------------------------------- public void coverage() { CurveGroupEntry test = CurveGroupEntry.builder().curveDefinition(CURVE_DEFN).discountCurrencies(GBP).build(); coverImmutableBean(test); CurveGroupEntry test2 = CurveGroupEntry.builder() .curveDefinition(CURVE_DEFN2) .iborIndices(GBP_LIBOR_1M) .overnightIndices(GBP_SONIA) .build(); coverBeanEquals(test, test2); } public void test_serialization() { CurveGroupEntry test = CurveGroupEntry.builder().curveDefinition(CURVE_DEFN).discountCurrencies(GBP).build(); assertSerialization(test); } }
public static ObservableValues allQuotes( double[] dscOisQuotes, String[] dscIdValues, double[] fwd3MarketQuotes, String[] fwd3IdValue, double[] fwd6MarketQuotes, String[] fwd6IdValue) { /* All quotes for the curve calibration */ Map<ObservableKey, Double> allQuotes = new HashMap<>(); for (int i = 0; i < dscOisQuotes.length; i++) { allQuotes.put(QuoteKey.of(StandardId.of(SCHEME, dscIdValues[i])), dscOisQuotes[i]); } for (int i = 0; i < fwd3MarketQuotes.length; i++) { allQuotes.put(QuoteKey.of(StandardId.of(SCHEME, fwd3IdValue[i])), fwd3MarketQuotes[i]); } for (int i = 0; i < fwd6MarketQuotes.length; i++) { allQuotes.put(QuoteKey.of(StandardId.of(SCHEME, fwd6IdValue[i])), fwd6MarketQuotes[i]); } return ObservableValues.of(allQuotes); }
static FixedIborSwapCurveNode fixedIborSwapNode(Tenor tenor, String id) { QuoteKey quoteKey = QuoteKey.of(StandardId.of(TEST_SCHEME, id)); FixedIborSwapTemplate template = FixedIborSwapTemplate.of(Period.ZERO, tenor, SWAP_CONVENTION); return FixedIborSwapCurveNode.of(template, quoteKey); }
static FraCurveNode fraNode(int startMonths, String id) { Period periodToStart = Period.ofMonths(startMonths); QuoteKey quoteKey = QuoteKey.of(StandardId.of(TEST_SCHEME, id)); return FraCurveNode.of(FraTemplate.of(periodToStart, IborIndices.USD_LIBOR_3M), quoteKey); }
public static CurveGroupDefinition config( Period[] dscOisTenors, String[] dscIdValues, Period[] fwd3FraTenors, Period[] fwd3IrsTenors, String[] fwd3IdValues, Period[] fwd6FraTenors, Period[] fwd6IrsTenors, String[] fwd6IdValues) { CurveNode[] dscNodes = new CurveNode[dscOisTenors.length]; for (int i = 0; i < dscOisTenors.length; i++) { dscNodes[i] = FixedOvernightSwapCurveNode.of( FixedOvernightSwapTemplate.of( Period.ZERO, Tenor.of(dscOisTenors[i]), EUR_FIXED_1Y_EONIA_OIS), QuoteKey.of(StandardId.of(SCHEME, dscIdValues[i]))); } CurveNode[] fwd3Nodes = new CurveNode[fwd3IdValues.length]; fwd3Nodes[0] = IborFixingDepositCurveNode.of( IborFixingDepositTemplate.of(EUR_EURIBOR_3M), QuoteKey.of(StandardId.of(SCHEME, fwd3IdValues[0]))); for (int i = 0; i < fwd3FraTenors.length; i++) { fwd3Nodes[i + 1] = FraCurveNode.of( FraTemplate.of(fwd3FraTenors[i], EUR_EURIBOR_3M), QuoteKey.of(StandardId.of(SCHEME, fwd3IdValues[i + 1]))); } for (int i = 0; i < fwd3IrsTenors.length; i++) { fwd3Nodes[i + 1 + fwd3FraTenors.length] = FixedIborSwapCurveNode.of( FixedIborSwapTemplate.of( Period.ZERO, Tenor.of(fwd3IrsTenors[i]), EUR_FIXED_1Y_EURIBOR_3M), QuoteKey.of(StandardId.of(SCHEME, fwd3IdValues[i + 1]))); } CurveNode[] fwd6Nodes = new CurveNode[fwd6IdValues.length]; fwd6Nodes[0] = IborFixingDepositCurveNode.of( IborFixingDepositTemplate.of(EUR_EURIBOR_6M), QuoteKey.of(StandardId.of(SCHEME, fwd6IdValues[0]))); for (int i = 0; i < fwd6FraTenors.length; i++) { fwd6Nodes[i + 1] = FraCurveNode.of( FraTemplate.of(fwd6FraTenors[i], EUR_EURIBOR_6M), QuoteKey.of(StandardId.of(SCHEME, fwd6IdValues[i + 1]))); } for (int i = 0; i < fwd6IrsTenors.length; i++) { fwd6Nodes[i + 1 + fwd6FraTenors.length] = FixedIborSwapCurveNode.of( FixedIborSwapTemplate.of( Period.ZERO, Tenor.of(fwd6IrsTenors[i]), EUR_FIXED_1Y_EURIBOR_6M), QuoteKey.of(StandardId.of(SCHEME, fwd6IdValues[i + 1]))); } InterpolatedNodalCurveDefinition DSC_CURVE_DEFN = InterpolatedNodalCurveDefinition.builder() .name(DSCON_CURVE_NAME) .xValueType(ValueType.YEAR_FRACTION) .yValueType(ValueType.ZERO_RATE) .dayCount(CURVE_DC) .interpolator(INTERPOLATOR_LINEAR) .extrapolatorLeft(EXTRAPOLATOR_FLAT) .extrapolatorRight(EXTRAPOLATOR_FLAT) .nodes(dscNodes) .build(); InterpolatedNodalCurveDefinition FWD3_CURVE_DEFN = InterpolatedNodalCurveDefinition.builder() .name(FWD3_CURVE_NAME) .xValueType(ValueType.YEAR_FRACTION) .yValueType(ValueType.ZERO_RATE) .dayCount(CURVE_DC) .interpolator(INTERPOLATOR_LINEAR) .extrapolatorLeft(EXTRAPOLATOR_FLAT) .extrapolatorRight(EXTRAPOLATOR_FLAT) .nodes(fwd3Nodes) .build(); InterpolatedNodalCurveDefinition FWD6_CURVE_DEFN = InterpolatedNodalCurveDefinition.builder() .name(FWD6_CURVE_NAME) .xValueType(ValueType.YEAR_FRACTION) .yValueType(ValueType.ZERO_RATE) .dayCount(CURVE_DC) .interpolator(INTERPOLATOR_LINEAR) .extrapolatorLeft(EXTRAPOLATOR_FLAT) .extrapolatorRight(EXTRAPOLATOR_FLAT) .nodes(fwd6Nodes) .build(); return CurveGroupDefinition.builder() .name(CURVE_GROUP_NAME) .addCurve(DSC_CURVE_DEFN, EUR, EUR_EONIA) .addForwardCurve(FWD3_CURVE_DEFN, EUR_EURIBOR_3M) .addForwardCurve(FWD6_CURVE_DEFN, EUR_EURIBOR_6M) .build(); }