/**
* Copyright (C) 2016 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.examples.finance;
import static com.opengamma.strata.measure.StandardComponents.marketDataFactory;
import java.io.File;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.opengamma.strata.basics.ReferenceData;
import com.opengamma.strata.basics.StandardId;
import com.opengamma.strata.calc.CalculationRules;
import com.opengamma.strata.calc.CalculationRunner;
import com.opengamma.strata.calc.Column;
import com.opengamma.strata.calc.Results;
import com.opengamma.strata.calc.marketdata.MarketDataConfig;
import com.opengamma.strata.calc.marketdata.MarketDataRequirements;
import com.opengamma.strata.calc.runner.CalculationFunctions;
import com.opengamma.strata.collect.io.ResourceLocator;
import com.opengamma.strata.collect.timeseries.LocalDateDoubleTimeSeries;
import com.opengamma.strata.data.ImmutableMarketData;
import com.opengamma.strata.data.MarketData;
import com.opengamma.strata.data.ObservableId;
import com.opengamma.strata.examples.marketdata.ExampleData;
import com.opengamma.strata.loader.csv.FixingSeriesCsvLoader;
import com.opengamma.strata.loader.csv.QuotesCsvLoader;
import com.opengamma.strata.loader.csv.RatesCalibrationCsvLoader;
import com.opengamma.strata.market.curve.CurveGroupDefinition;
import com.opengamma.strata.market.curve.CurveGroupName;
import com.opengamma.strata.market.observable.QuoteId;
import com.opengamma.strata.measure.Measures;
import com.opengamma.strata.measure.StandardComponents;
import com.opengamma.strata.measure.calc.TradeCounterpartyCalculationParameter;
import com.opengamma.strata.measure.rate.RatesMarketDataLookup;
import com.opengamma.strata.product.Trade;
import com.opengamma.strata.product.TradeAttributeType;
import com.opengamma.strata.product.TradeInfo;
import com.opengamma.strata.product.common.BuySell;
import com.opengamma.strata.product.swap.type.FixedIborSwapConventions;
import com.opengamma.strata.report.ReportCalculationResults;
import com.opengamma.strata.report.trade.TradeReport;
import com.opengamma.strata.report.trade.TradeReportTemplate;
/**
* Example to illustrate using the engine to price a swap.
* <p>
* This makes use of the example engine and the example market data environment.
*/
public class SwapPricingCcpExample {
/**
* The valuation date.
*/
private static final LocalDate VAL_DATE = LocalDate.of(2015, 7, 21);
/**
* The curve group name.
*/
private static final CurveGroupName CURVE_GROUP_NAME_CCP1 = CurveGroupName.of("USD-DSCON-LIBOR3M");
private static final CurveGroupName CURVE_GROUP_NAME_CCP2 = CurveGroupName.of("USD-DSCON-LIBOR3M-CCP2");
/**
* The location of the data files.
*/
private static final String PATH_CONFIG = "src/main/resources/";
/**
* The location of the curve calibration groups file for CCP1 and CCP2.
*/
private static final ResourceLocator GROUPS_RESOURCE_CCP1 =
ResourceLocator.ofFile(new File(PATH_CONFIG + "example-calibration/curves/groups.csv"));
private static final ResourceLocator GROUPS_RESOURCE_CCP2 =
ResourceLocator.ofFile(new File(PATH_CONFIG + "example-calibration/curves/groups-ccp2.csv"));
/**
* The location of the curve calibration settings file for CCP1 and CCP2.
*/
private static final ResourceLocator SETTINGS_RESOURCE_CCP1 =
ResourceLocator.ofFile(new File(PATH_CONFIG + "example-calibration/curves/settings.csv"));
private static final ResourceLocator SETTINGS_RESOURCE_CCP2 =
ResourceLocator.ofFile(new File(PATH_CONFIG + "example-calibration/curves/settings-ccp2.csv"));
/**
* The location of the curve calibration nodes file for CCP1 and CCP2.
*/
private static final ResourceLocator CALIBRATION_RESOURCE_CCP1 =
ResourceLocator.ofFile(new File(PATH_CONFIG + "example-calibration/curves/calibrations.csv"));
private static final ResourceLocator CALIBRATION_RESOURCE_CCP2 =
ResourceLocator.ofFile(new File(PATH_CONFIG + "example-calibration/curves/calibrations-ccp2.csv"));
/**
* The location of the market quotes file for CCP1 and CCP2.
*/
private static final ResourceLocator QUOTES_RESOURCE_CCP1 =
ResourceLocator.ofFile(new File(PATH_CONFIG + "example-calibration/quotes/quotes.csv"));
private static final ResourceLocator QUOTES_RESOURCE_CCP2 =
ResourceLocator.ofFile(new File(PATH_CONFIG + "example-calibration/quotes/quotes-ccp2.csv"));
/**
* The location of the historical fixing file.
*/
private static final ResourceLocator FIXINGS_RESOURCE =
ResourceLocator.ofFile(new File(PATH_CONFIG + "example-marketdata/historical-fixings/usd-libor-3m.csv"));
/**
* The first counterparty.
*/
private static final StandardId CCP1_ID = StandardId.of("example", "CCP-1");
/**
* The second counterparty.
*/
private static final StandardId CCP2_ID = StandardId.of("example", "CCP-2");
/**
* Runs the example, pricing the instruments, producing the output as an ASCII table.
*
* @param args ignored
*/
public static void main(String[] args) {
// setup calculation runner component, which needs life-cycle management
// a typical application might use dependency injection to obtain the instance
try (CalculationRunner runner = CalculationRunner.ofMultiThreaded()) {
calculate(runner);
}
}
// obtains the data and calculates the grid of results
private static void calculate(CalculationRunner runner) {
// the trades that will have measures calculated
List<Trade> trades = createSwapTrades();
// the columns, specifying the measures to be calculated
List<Column> columns = ImmutableList.of(
Column.of(Measures.PRESENT_VALUE),
Column.of(Measures.PAR_RATE),
Column.of(Measures.PV01_MARKET_QUOTE_BUCKETED),
Column.of(Measures.PV01_CALIBRATED_BUCKETED));
// load quotes
ImmutableMap<QuoteId, Double> quotesCcp1 = QuotesCsvLoader.load(VAL_DATE, QUOTES_RESOURCE_CCP1);
ImmutableMap<QuoteId, Double> quotesCcp2 = QuotesCsvLoader.load(VAL_DATE, QUOTES_RESOURCE_CCP2);
// load fixings
ImmutableMap<ObservableId, LocalDateDoubleTimeSeries> fixings = FixingSeriesCsvLoader.load(FIXINGS_RESOURCE);
// create the market data
MarketData marketData = ImmutableMarketData.builder(VAL_DATE)
.addValueMap(quotesCcp1)
.addValueMap(quotesCcp2)
.addTimeSeriesMap(fixings)
.build();
// the reference data, such as holidays and securities
ReferenceData refData = ReferenceData.standard();
// load the curve definition
Map<CurveGroupName, CurveGroupDefinition> defnsCcp1 =
RatesCalibrationCsvLoader.load(GROUPS_RESOURCE_CCP1, SETTINGS_RESOURCE_CCP1, CALIBRATION_RESOURCE_CCP1);
Map<CurveGroupName, CurveGroupDefinition> defnsCcp2 =
RatesCalibrationCsvLoader.load(GROUPS_RESOURCE_CCP2, SETTINGS_RESOURCE_CCP2, CALIBRATION_RESOURCE_CCP2);
CurveGroupDefinition curveGroupDefinitionCcp1 = defnsCcp1.get(CURVE_GROUP_NAME_CCP1).filtered(VAL_DATE, refData);
CurveGroupDefinition curveGroupDefinitionCcp2 = defnsCcp2.get(CURVE_GROUP_NAME_CCP2).filtered(VAL_DATE, refData);
// the configuration that defines how to create the curves when a curve group is requested
MarketDataConfig marketDataConfig = MarketDataConfig.builder()
.add(CURVE_GROUP_NAME_CCP1, curveGroupDefinitionCcp1)
.add(CURVE_GROUP_NAME_CCP2, curveGroupDefinitionCcp2)
.build();
// the complete set of rules for calculating measures
CalculationFunctions functions = StandardComponents.calculationFunctions();
RatesMarketDataLookup ratesLookupCcp1 = RatesMarketDataLookup.of(curveGroupDefinitionCcp1);
RatesMarketDataLookup ratesLookupCcp2 = RatesMarketDataLookup.of(curveGroupDefinitionCcp2);
// choose RatesMarketDataLookup instance based on counterparty
TradeCounterpartyCalculationParameter perCounterparty = TradeCounterpartyCalculationParameter.of(
ImmutableMap.of(CCP1_ID, ratesLookupCcp1, CCP2_ID, ratesLookupCcp2), ratesLookupCcp1);
CalculationRules rules = CalculationRules.of(functions, perCounterparty);
// calibrate the curves and calculate the results
MarketDataRequirements reqs = MarketDataRequirements.of(rules, trades, columns, refData);
MarketData calibratedMarketData = marketDataFactory().create(reqs, marketDataConfig, marketData, refData);
Results results = runner.calculate(rules, trades, columns, calibratedMarketData, refData);
// use the report runner to transform the engine results into a trade report
ReportCalculationResults calculationResults =
ReportCalculationResults.of(VAL_DATE, trades, columns, results, functions, refData);
TradeReportTemplate reportTemplate = ExampleData.loadTradeReportTemplate("swap-report-template2");
TradeReport tradeReport = TradeReport.of(calculationResults, reportTemplate);
tradeReport.writeAsciiTable(System.out);
}
//-----------------------------------------------------------------------
// create swap trades
private static List<Trade> createSwapTrades() {
return ImmutableList.of(createVanillaFixedVsLibor3mSwap(CCP1_ID), createVanillaFixedVsLibor3mSwap(CCP2_ID));
}
//-----------------------------------------------------------------------
// create a vanilla fixed vs libor 3m swap
private static Trade createVanillaFixedVsLibor3mSwap(StandardId ctptyId) {
TradeInfo tradeInfo = TradeInfo.builder()
.id(StandardId.of("example", "1"))
.addAttribute(TradeAttributeType.DESCRIPTION, "Fixed vs Libor 3m")
.counterparty(ctptyId)
.settlementDate(LocalDate.of(2014, 9, 12))
.build();
return FixedIborSwapConventions.USD_FIXED_6M_LIBOR_3M.toTrade(
tradeInfo,
LocalDate.of(2014, 9, 12), // the start date
LocalDate.of(2021, 9, 12), // the end date
BuySell.BUY, // indicates whether this trade is a buy or sell
100_000_000, // the notional amount
0.015); // the fixed interest rate
}
}