@Override protected Set<ComputedValue> getResult( final ForexDerivative fxOption, final SmileDeltaTermStructureDataBundle data, final FunctionInputs inputs, final ComputationTarget target) { final MultipleCurrencyAmount result = CALCULATOR.visit(fxOption, data); final int n = result.size(); final Currency[] keys = new Currency[n]; final double[] values = new double[n]; int i = 0; for (final CurrencyAmount ca : result) { keys[i] = ca.getCurrency(); values[i++] = ca.getAmount(); } final ValueProperties properties = createValueProperties() .with(ValuePropertyNames.PAY_CURVE, getPutCurveName()) .with(ValuePropertyNames.RECEIVE_CURVE, getCallCurveName()) .with(ValuePropertyNames.SURFACE, getSurfaceName()) .get(); final ValueSpecification spec = new ValueSpecification(getValueRequirementName(), target.toSpecification(), properties); return Collections.singleton( new ComputedValue(spec, new CurrencyLabelledMatrix1D(keys, values))); }
@Override public Set<ComputedValue> execute( final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) { final FXFutureSecurity security = (FXFutureSecurity) target.getSecurity(); final Clock snapshotClock = executionContext.getValuationClock(); final ZonedDateTime now = ZonedDateTime.now(snapshotClock); final Currency payCurrency = security.getNumerator(); final Object payCurveObject = inputs.getValue( YieldCurveFunction.getCurveRequirement(payCurrency, _payCurveName, null, null)); if (payCurveObject == null) { throw new OpenGammaRuntimeException("Could not get " + _payCurveName + " curve"); } final Currency receiveCurrency = security.getDenominator(); final Object receiveCurveObject = inputs.getValue( YieldCurveFunction.getCurveRequirement(receiveCurrency, _receiveCurveName, null, null)); if (receiveCurveObject == null) { throw new OpenGammaRuntimeException("Could not get " + _receiveCurveName + " curve"); } // TODO: The convention is only looked up here so that we can convert the spot rate; would be // better to request the spot rate using the correct currency pair in the first place final CurrencyPairs currencyPairs = OpenGammaExecutionContext.getCurrencyPairsSource(executionContext) .getCurrencyPairs(CurrencyPairs.DEFAULT_CURRENCY_PAIRS); final CurrencyPair currencyPair = currencyPairs.getCurrencyPair(payCurrency, receiveCurrency); final Currency currencyBase = currencyPair.getBase(); final Object spotObject = inputs.getValue(ValueRequirementNames.SPOT_RATE); if (spotObject == null) { throw new OpenGammaRuntimeException("Could not get market data for spot rate"); } double spot = (Double) spotObject; if (!receiveCurrency.equals(currencyBase) && receiveCurrency.equals(security.getCurrency())) { spot = 1. / spot; } final YieldAndDiscountCurve payCurve = (YieldAndDiscountCurve) payCurveObject; final YieldAndDiscountCurve receiveCurve = (YieldAndDiscountCurve) receiveCurveObject; final SimpleFXFutureDataBundle data = new SimpleFXFutureDataBundle(payCurve, receiveCurve, spot); final SimpleInstrument instrument = security.accept(CONVERTER).toDerivative(now); final CurrencyAmount pv = instrument.accept(CALCULATOR, data); final ValueProperties properties = createValueProperties() .with(ValuePropertyNames.PAY_CURVE, _payCurveName) .with(ValuePropertyNames.RECEIVE_CURVE, _receiveCurveName) .with(ValuePropertyNames.CURRENCY, pv.getCurrency().getCode()) .get(); final ValueSpecification spec = new ValueSpecification( ValueRequirementNames.PRESENT_VALUE, target.toSpecification(), properties); return Collections.singleton(new ComputedValue(spec, pv.getAmount())); }
public static CurrencyLabelledMatrix1D getMultipleCurrencyAmountAsMatrix( final MultipleCurrencyAmount mca) { ArgumentChecker.notNull(mca, "multiple currency amount"); final int n = mca.size(); final Currency[] keys = new Currency[n]; final double[] values = new double[n]; int i = 0; for (final CurrencyAmount ca : mca) { keys[i] = ca.getCurrency(); values[i++] = ca.getAmount(); } return new CurrencyLabelledMatrix1D(keys, values); }
@Test public void testPayCashFlowsNoNetting() { for (final InstrumentDefinition<?> definition : NO_NETTING_PAY_INSTRUMENTS) { final TreeMap<LocalDate, MultipleCurrencyAmount> pay = new TreeMap<LocalDate, MultipleCurrencyAmount>(definition.accept(PAY_CASH_FLOWS)); final TreeMap<LocalDate, MultipleCurrencyAmount> netted = new TreeMap<LocalDate, MultipleCurrencyAmount>(definition.accept(VISITOR)); assertEquals(pay.size(), netted.size()); assertEquals(pay.keySet(), netted.keySet()); final Iterator<Map.Entry<LocalDate, MultipleCurrencyAmount>> nettedIterator = netted.entrySet().iterator(); for (final Map.Entry<LocalDate, MultipleCurrencyAmount> payEntry : pay.entrySet()) { final Map.Entry<LocalDate, MultipleCurrencyAmount> nettedEntry = nettedIterator.next(); assertEquals(payEntry.getKey(), nettedEntry.getKey()); assertEquals(payEntry.getValue().size(), nettedEntry.getValue().size()); final Iterator<CurrencyAmount> nettedMCAIterator = nettedEntry.getValue().iterator(); for (final CurrencyAmount payCA : payEntry.getValue()) { final CurrencyAmount nettedCA = nettedMCAIterator.next(); assertEquals(payCA.getCurrency(), nettedCA.getCurrency()); assertEquals(payCA.getAmount(), -nettedCA.getAmount()); } } } }
@Test /** Check the conversion of a multiple currency amount. */ public void convert() { final FXMatrix fxMatrix = new FXMatrix(); fxMatrix.addCurrency(EUR, USD, EUR_USD); fxMatrix.addCurrency(GBP, EUR, GBP_EUR); final double amountGBP = 1.0; final double amountEUR = 2.0; final double amountUSD = 3.0; MultipleCurrencyAmount amount = MultipleCurrencyAmount.of(GBP, amountGBP); amount = amount.plus(EUR, amountEUR); amount = amount.plus(USD, amountUSD); final CurrencyAmount totalUSDCalculated = fxMatrix.convert(amount, USD); final double totalUSDExpected = amountUSD + amountEUR * EUR_USD + amountGBP * GBP_EUR * EUR_USD; assertEquals("FXMatrix - convert", totalUSDExpected, totalUSDCalculated.getAmount(), 1.0E-10); assertEquals("FXMatrix - convert", USD, totalUSDCalculated.getCurrency()); }