Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,12 @@
/**
* Example to illustrate using the calculation API to price a swap.
* <p>
* This makes use of the example market data environment.
* This makes use of the example market data environment. The example uses a
* multi-curve setup: the USD discount curve is used for discounting and the
* USD-LIBOR-3M curve is used for floating-rate projection. The resulting NPV
* is therefore not directly comparable with a single flat risk-free-rate curve
* used by another pricing library unless the market data and conventions are
* aligned first.
*/
public class SwapPricingExample {

Expand Down Expand Up @@ -95,7 +100,9 @@ private static void calculate(CalculationRunner runner) {
Column.of(Measures.PV01_CALIBRATED_BUCKETED),
Column.of(AdvancedMeasures.PV01_SEMI_PARALLEL_GAMMA_BUCKETED));

// use the built-in example market data
// Use the built-in multi-curve example market data. USD-Disc is used for
// discounting and USD-3ML for USD-LIBOR-3M projection. This is not a flat
// 1% risk-free-rate setup.
LocalDate valuationDate = LocalDate.of(2014, 1, 22);
ExampleMarketDataBuilder marketDataBuilder = ExampleMarketData.builder();
MarketData marketData = marketDataBuilder.buildSnapshot(valuationDate);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
import com.opengamma.strata.product.swap.SwapTrade;
import com.opengamma.strata.product.swap.type.SingleCurrencySwapConvention;
import com.opengamma.strata.product.swap.type.XCcyIborIborSwapConvention;
import com.opengamma.strata.product.swap.type.XCcyOvernightOvernightSwapConvention;

/**
* Loads Swap trades from CSV files.
Expand Down Expand Up @@ -357,10 +358,9 @@ static SwapTrade parseWithConvention(CsvRow row, TradeInfo info, ReferenceData r
Period periodToStart = periodToStartOpt.get();
Tenor tenor = tenorOpt.get();
if (fxRateOpt.isPresent()) {
XCcyIborIborSwapConvention convention = XCcyIborIborSwapConvention.of(conventionStr);
double notionalFlat = notional * fxRateOpt.get();
SwapTrade trade = convention.createTrade(
tradeDate, periodToStart, tenor, buySell, notional, notionalFlat, fixedRate, refData);
SwapTrade trade = createCrossCurrencySwap(
conventionStr, tradeDate, periodToStart, tenor, buySell, notional,
notional * fxRateOpt.get(), fixedRate, refData);
trade = trade.toBuilder().info(info).build();
return adjustTrade(trade, rollCnvOpt, stubCnvOpt, firstRegStartDateOpt, lastRegEndDateOpt, dateCnv, dateCalOpt);
} else {
Expand Down Expand Up @@ -396,15 +396,52 @@ private static SwapTrade createSwap(
Optional<Double> fxRateOpt) {

if (fxRateOpt.isPresent()) {
XCcyIborIborSwapConvention convention = XCcyIborIborSwapConvention.of(conventionStr);
double notionalFlat = notional * fxRateOpt.get();
return convention.toTrade(info, startDate, endDate, buySell, notional, notionalFlat, fixedRate);
return createCrossCurrencySwap(
conventionStr, info, startDate, endDate, buySell, notional,
notional * fxRateOpt.get(), fixedRate);
} else {
SingleCurrencySwapConvention convention = SingleCurrencySwapConvention.of(conventionStr);
return convention.toTrade(info, startDate, endDate, buySell, notional, fixedRate);
}
}

private static SwapTrade createCrossCurrencySwap(
String conventionStr,
LocalDate tradeDate,
Period periodToStart,
Tenor tenor,
BuySell buySell,
double notionalSpreadLeg,
double notionalFlatLeg,
double spread,
ReferenceData refData) {

if (XCcyIborIborSwapConvention.extendedEnum().lookupAll().containsKey(conventionStr)) {
return XCcyIborIborSwapConvention.of(conventionStr).createTrade(
tradeDate, periodToStart, tenor, buySell, notionalSpreadLeg, notionalFlatLeg, spread, refData);
}
return XCcyOvernightOvernightSwapConvention.of(conventionStr).createTrade(
tradeDate, periodToStart, tenor, buySell, notionalSpreadLeg, notionalFlatLeg, spread, refData);
}

private static SwapTrade createCrossCurrencySwap(
String conventionStr,
TradeInfo info,
LocalDate startDate,
LocalDate endDate,
BuySell buySell,
double notionalSpreadLeg,
double notionalFlatLeg,
double spread) {

if (XCcyIborIborSwapConvention.extendedEnum().lookupAll().containsKey(conventionStr)) {
return XCcyIborIborSwapConvention.of(conventionStr).toTrade(
info, startDate, endDate, buySell, notionalSpreadLeg, notionalFlatLeg, spread);
}
return XCcyOvernightOvernightSwapConvention.of(conventionStr).toTrade(
info, startDate, endDate, buySell, notionalSpreadLeg, notionalFlatLeg, spread);
}

// adjust trade based on additional fields specified
private static SwapTrade adjustTrade(
SwapTrade trade,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@
public class TradeCsvLoaderTest {

private static final ReferenceData REF_DATA = ReferenceData.standard();
private static final int NUMBER_SWAPS = 11;
private static final int NUMBER_SWAPS = 12;

private static final ResourceLocator FILE =
ResourceLocator.of("classpath:com/opengamma/strata/loader/csv/trades.csv");
Expand Down Expand Up @@ -745,6 +745,13 @@ public void test_load_swap() {
assertBeanEquals(expected8, filtered.get(8));
assertBeanEquals(expected9, filtered.get(9));
assertBeanEquals(expected10, filtered.get(10));
SwapTrade overnightSwap = filtered.get(11);
assertThat(overnightSwap.getInfo().getId().get().getValue()).isEqualTo("123422");
assertThat(overnightSwap.getProduct().getLegs()).hasSize(2);
assertThat(overnightSwap.getProduct().getLegs().get(0).getCurrency()).isEqualTo(EUR);
assertThat(overnightSwap.getProduct().getLegs().get(1).getCurrency()).isEqualTo(USD);
assertThat(overnightSwap.getProduct().getLegs().get(0).getPayReceive()).isEqualTo(PAY);
assertThat(overnightSwap.getProduct().getLegs().get(1).getPayReceive()).isEqualTo(RECEIVE);

checkRoundtrip(
SwapTrade.class,
Expand All @@ -759,7 +766,8 @@ public void test_load_swap() {
expected7,
expected8,
expected9,
expected10);
expected10,
overnightSwap);
}

private SwapTrade expectedSwap0() {
Expand Down Expand Up @@ -2315,7 +2323,7 @@ public void test_load_filtered() {
ImmutableList.of(FILE.getCharSource()), ImmutableList.of(FraTrade.class, TermDepositTrade.class));

assertThat(trades.getValue()).hasSize(6);
assertThat(trades.getFailures()).hasSize(29);
assertThat(trades.getFailures()).hasSize(30);
assertThat(trades.getFailures().get(0).getMessage()).isEqualTo(
"Trade type not allowed " + SwapTrade.class.getName() + ", only these types are supported: FraTrade, TermDepositTrade");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Variable,,,,,,,,,,,,,,,,,,01/06/2018,,,,,,,,,,,,,,2500000,,,,,,,,,,,,,,,,,,,,,,,
Swap,OG,123419,01/06/2017,,,,,,,,,,,,,,,,,,,,Pay,01/07/2017,01/07/2018,,,1T,BRL,1000000,1.3,,BUS/252,,,Receive,01/07/2017,01/07/2018,1T,BRL,1000000,BRL-CDI,OvernightCompoundedAnnualRate,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
Swap,OG,123420,01/06/2017,,,,,,,,,,,,,,,,,,,,Pay,01/07/2017,01/07/2018,,,1T,BRL,2000000,1.5,,BUS/252,,,Receive,01/07/2017,01/07/2018,1T,BRL,2000000,BRL-CDI,OvernightCompoundedAnnualRate,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
Swap,OG,123421,01/06/2017,,,,,,,,,,,,,,,,,,,,Pay,01/07/2017,01/07/2018,,,1T,BRL,3000000,1.7,,BUS/252,,,Receive,01/07/2017,01/07/2018,1T,BRL,3000000,BRL-CDI,Compounded,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
Swap,OG,123422,01/06/2017,,,,EUR-ESTR-3M-USD-SOFR-3M,Buy,,P3Y,,,0.6,1.25,,,2000000,05/07/2017,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
Swaption,OG,123411,01/06/2017,,,,GBP-FIXED-1Y-LIBOR-3M,Buy,P1M,P5Y,,,0.4,,,,2000000,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,Long,ParYield,03/07/2017,30/06/2017,11:00,Europe/London,Pay,GBP,1000,03/06/2017,,,,,,,,,,,,,,,,,,,,,
Swaption,OG,123412,01/06/2017,,,,GBP-FIXED-6M-LIBOR-6M,BUY,,,,,-0.01,,,,3100000,01/08/2017,01/08/2022,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,Short,Physical,,30/06/2017,11:00,Europe/London,Receive,GBP,1000,03/06/2017,,,,,,,,,,,,,,,,,,,,,
Expand Down