SpotRateShift implements StructureManipulator<Double>, ImmutableBean { @Override public Double execute(Double spotRate, ValueSpecification valueSpecification, FunctionExecutionContext executionContext) { CurrencyPair currencyPair = SimulationUtils.getCurrencyPair(valueSpecification); if (_currencyPairs.contains(currencyPair)) { return applyShift(spotRate); } else if (_currencyPairs.contains(currencyPair.inverse())) { double inverseRate = 1 / spotRate; double shiftedRate = applyShift(inverseRate); return 1 / shiftedRate; } else { throw new IllegalArgumentException("Currency pair " + currencyPair + " shouldn't match " + _currencyPairs); } } SpotRateShift(ScenarioShiftType shiftType, Number shiftAmount, Set<CurrencyPair> currencyPairs);   SpotRateShift(ScenarioShiftType shiftType,
                              Number shiftAmount,
                              Number minRate,
                              Number maxRate,
                              CurrencyPair currencyPair); private  SpotRateShift(
      ScenarioShiftType shiftType,
      double shiftAmount,
      double minRate,
      double maxRate,
      Set<CurrencyPair> currencyPairs); @Override Double execute(Double spotRate,
                        ValueSpecification valueSpecification,
                        FunctionExecutionContext executionContext); @Override Class<Double> getExpectedType(); static SpotRateShift.Meta meta(); static SpotRateShift.Builder builder(); @Override SpotRateShift.Meta metaBean(); @Override Property<R> property(String propertyName); @Override Set<String> propertyNames(); ScenarioShiftType getShiftType(); double getShiftAmount(); double getMinRate(); double getMaxRate(); Set<CurrencyPair> getCurrencyPairs(); Builder toBuilder(); @Override boolean equals(Object obj); @Override int hashCode(); @Override String toString();  }
@Test public void normalPair() { assertEquals(3d, ABSOLUTE_SHIFT.execute(2d, valueSpec("EUR/USD"), new FunctionExecutionContext()), DELTA); assertEquals(5d, ABSOLUTE_SHIFT.execute(4d, valueSpec("CHF/JPY"), new FunctionExecutionContext()), DELTA); assertEquals(2.2d, RELATIVE_SHIFT.execute(2d, valueSpec("EUR/USD"), new FunctionExecutionContext()), DELTA); assertEquals(4.4d, RELATIVE_SHIFT.execute(4d, valueSpec("CHF/JPY"), new FunctionExecutionContext()), DELTA); }
@Test public void inversePair() { assertEquals(0.6666666666, ABSOLUTE_SHIFT.execute(2d, valueSpec("USD/EUR"), new FunctionExecutionContext()), DELTA); assertEquals(0.8d, ABSOLUTE_SHIFT.execute(4d, valueSpec("JPY/CHF"), new FunctionExecutionContext()), DELTA); assertEquals(1.8181818181818181, RELATIVE_SHIFT.execute(2d, valueSpec("USD/EUR"), new FunctionExecutionContext()), DELTA); assertEquals(3.6363636363636362, RELATIVE_SHIFT.execute(4d, valueSpec("JPY/CHF"), new FunctionExecutionContext()), DELTA); }
@Test public void boundedRate() { SpotRateShift upOne = new SpotRateShift(ScenarioShiftType.ABSOLUTE, 1d, 0, 6d, CurrencyPair.parse("EUR/USD")); assertEquals(3d, upOne.execute(2d, valueSpec("EUR/USD"), new FunctionExecutionContext()), DELTA); assertEquals(6d, upOne.execute(5.5, valueSpec("EUR/USD"), new FunctionExecutionContext()), DELTA); SpotRateShift downOne = new SpotRateShift(ScenarioShiftType.ABSOLUTE, -1d, 0.5, 6d, CurrencyPair.parse("EUR/USD")); assertEquals(1d, downOne.execute(2d, valueSpec("EUR/USD"), new FunctionExecutionContext()), DELTA); assertEquals(0.5, downOne.execute(1d, valueSpec("EUR/USD"), new FunctionExecutionContext()), DELTA); SpotRateShift upFiftyPc = new SpotRateShift(ScenarioShiftType.RELATIVE, 0.5, 0.1, 6d, CurrencyPair.parse("EUR/USD")); assertEquals(1.5d, upFiftyPc.execute(1d, valueSpec("EUR/USD"), new FunctionExecutionContext()), DELTA); assertEquals(6d, upFiftyPc.execute(5d, valueSpec("EUR/USD"), new FunctionExecutionContext()), DELTA); SpotRateShift downFiftyPc = new SpotRateShift(ScenarioShiftType.RELATIVE, -0.5, 0.2, 6d, CurrencyPair.parse("EUR/USD")); assertEquals(1d, downFiftyPc.execute(2d, valueSpec("EUR/USD"), new FunctionExecutionContext()), DELTA); assertEquals(0.2, downFiftyPc.execute(0.3, valueSpec("EUR/USD"), new FunctionExecutionContext()), DELTA); }
@Test public void boundedInverseRate() { SpotRateShift upTwo = new SpotRateShift(ScenarioShiftType.ABSOLUTE, 2d, 0, 6d, CurrencyPair.parse("EUR/USD")); assertEquals(0.4, upTwo.execute(2d, valueSpec("USD/EUR"), new FunctionExecutionContext()), DELTA); assertEquals(0.166666666, upTwo.execute(0.2, valueSpec("USD/EUR"), new FunctionExecutionContext()), DELTA); SpotRateShift downTwo = new SpotRateShift(ScenarioShiftType.ABSOLUTE, -2d, 0.1, 6d, CurrencyPair.parse("EUR/USD")); assertEquals(0.5, downTwo.execute(0.25, valueSpec("USD/EUR"), new FunctionExecutionContext()), DELTA); assertEquals(10d, downTwo.execute(0.5, valueSpec("USD/EUR"), new FunctionExecutionContext()), DELTA); SpotRateShift upFiftyPc = new SpotRateShift(ScenarioShiftType.RELATIVE, 0.5, 0.1, 6d, CurrencyPair.parse("EUR/USD")); assertEquals(0.333333333, upFiftyPc.execute(0.5, valueSpec("USD/EUR"), new FunctionExecutionContext()), DELTA); assertEquals(0.166666666, upFiftyPc.execute(0.2, valueSpec("USD/EUR"), new FunctionExecutionContext()), DELTA); SpotRateShift downFiftyPc = new SpotRateShift(ScenarioShiftType.RELATIVE, -0.5, 0.2, 6d, CurrencyPair.parse("EUR/USD")); assertEquals(1d, downFiftyPc.execute(0.5d, valueSpec("USD/EUR"), new FunctionExecutionContext()), DELTA); assertEquals(5d, downFiftyPc.execute(4d, valueSpec("USD/EUR"), new FunctionExecutionContext()), DELTA); }
@Test(expectedExceptions = IllegalArgumentException.class) public void unexpectedTargetType() { ValueProperties properties = ValueProperties.with(ValuePropertyNames.FUNCTION, "foo").get(); ComputationTargetSpecification targetSpec = new ComputationTargetSpecification(ComputationTargetType.CURRENCY, Currency.GBP.getUniqueId()); ValueSpecification valueSpec = new ValueSpecification("SpotRate", targetSpec, properties); ABSOLUTE_SHIFT.execute(2d, valueSpec, new FunctionExecutionContext()); }
@Test(expectedExceptions = IllegalArgumentException.class) public void unexpectedCurrencyPair() { ABSOLUTE_SHIFT.execute(2d, valueSpec("GBP/USD"), new FunctionExecutionContext()); }