com.opengamma.strata.loader.impl.fpml.FxSwapFpmlParserPlugin Maven / Gradle / Ivy
Show all versions of strata-loader Show documentation
/*
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.loader.impl.fpml;
import java.time.LocalDate;
import com.opengamma.strata.basics.currency.CurrencyAmount;
import com.opengamma.strata.collect.io.XmlElement;
import com.opengamma.strata.loader.fpml.FpmlDocument;
import com.opengamma.strata.loader.fpml.FpmlParseException;
import com.opengamma.strata.loader.fpml.FpmlParserPlugin;
import com.opengamma.strata.product.Trade;
import com.opengamma.strata.product.TradeInfoBuilder;
import com.opengamma.strata.product.common.PayReceive;
import com.opengamma.strata.product.fx.FxSingle;
import com.opengamma.strata.product.fx.FxSwap;
import com.opengamma.strata.product.fx.FxSwapTrade;
/**
* FpML parser for FX swap.
*
* This parser handles the subset of FpML necessary to populate the trade model.
*/
final class FxSwapFpmlParserPlugin
implements FpmlParserPlugin {
// this class is loaded by ExtendedEnum reflection
/**
* The singleton instance of the parser.
*/
public static final FxSwapFpmlParserPlugin INSTANCE = new FxSwapFpmlParserPlugin();
/**
* Restricted constructor.
*/
private FxSwapFpmlParserPlugin() {
}
//-------------------------------------------------------------------------
@Override
public Trade parseTrade(FpmlDocument document, XmlElement tradeEl) {
// supported elements:
// 'nearLeg'
// 'farLeg'
TradeInfoBuilder tradeInfoBuilder = document.parseTradeInfo(tradeEl);
XmlElement fxEl = tradeEl.getChild("fxSwap");
FxSingle nearLeg = parseLeg(fxEl.getChild("nearLeg"), document, tradeInfoBuilder);
FxSingle farLeg = parseLeg(fxEl.getChild("farLeg"), document, tradeInfoBuilder);
return FxSwapTrade.builder()
.info(tradeInfoBuilder.build())
.product(FxSwap.of(nearLeg, farLeg))
.build();
}
private FxSingle parseLeg(XmlElement legEl, FpmlDocument document, TradeInfoBuilder tradeInfoBuilder) {
// supported elements:
// 'exchangedCurrency1/paymentAmount'
// 'exchangedCurrency2/paymentAmount'
// 'valueDate'
// ignored elements:
// 'dealtCurrency?'
// 'exchangeRate'
// rejected elements:
// 'nonDeliverableSettlement?'
// 'currency1ValueDate'
// 'currency2ValueDate'
document.validateNotPresent(legEl, "currency1ValueDate");
document.validateNotPresent(legEl, "currency2ValueDate");
document.validateNotPresent(legEl, "nonDeliverableSettlement");
XmlElement curr1El = legEl.getChild("exchangedCurrency1");
XmlElement curr2El = legEl.getChild("exchangedCurrency2");
// pay/receive and counterparty
PayReceive curr1PayReceive = document.parsePayerReceiver(curr1El, tradeInfoBuilder);
PayReceive curr2PayReceive = document.parsePayerReceiver(curr2El, tradeInfoBuilder);
if (curr1PayReceive == curr2PayReceive) {
throw new FpmlParseException("FX single leg currencies must not have same Pay/Receive direction");
}
// amount
CurrencyAmount curr1Amount = document.parseCurrencyAmount(curr1El.getChild("paymentAmount"));
CurrencyAmount curr2Amount = document.parseCurrencyAmount(curr2El.getChild("paymentAmount"));
if (curr1PayReceive == PayReceive.PAY) {
curr1Amount = curr1Amount.negative();
curr2Amount = curr2Amount.positive();
} else {
curr1Amount = curr1Amount.positive();
curr2Amount = curr2Amount.negative();
}
// payment date
LocalDate valueDate = document.parseDate(legEl.getChild("valueDate"));
// result
return FxSingle.of(curr1Amount, curr2Amount, valueDate);
}
//-------------------------------------------------------------------------
@Override
public String getName() {
return "fxSwap";
}
}