/** * Copyright (C) 2016 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.strata.examples.blog.multicurve1; import static com.opengamma.strata.product.swap.type.FixedIborSwapConventions.GBP_FIXED_6M_LIBOR_6M; import java.time.LocalDate; import java.time.Period; import java.util.Map; import com.opengamma.strata.basics.ReferenceData; import com.opengamma.strata.basics.currency.MultiCurrencyAmount; import com.opengamma.strata.basics.date.Tenor; import com.opengamma.strata.collect.io.ResourceLocator; import com.opengamma.strata.collect.tuple.Pair; import com.opengamma.strata.data.ImmutableMarketData; 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.market.param.CurrencyParameterSensitivities; import com.opengamma.strata.market.sensitivity.PointSensitivities; import com.opengamma.strata.pricer.curve.CalibrationMeasures; import com.opengamma.strata.pricer.curve.CurveCalibrator; import com.opengamma.strata.pricer.rate.ImmutableRatesProvider; import com.opengamma.strata.pricer.sensitivity.MarketQuoteSensitivityCalculator; import com.opengamma.strata.pricer.swap.DiscountingSwapTradePricer; import com.opengamma.strata.product.common.BuySell; import com.opengamma.strata.product.swap.ResolvedSwapTrade; /** * Calibrates one set of curve, computes sensitivity (Bucketed PV01) and estimate computation time. * <p> * Code used for the blog "Strata and multi-curve - Blog 1: Curve calibration and bucketed PV01" available at * XXX */ public class CalibrationPVPerformanceExample { /* Reference data contains calendar. Here we use build-in holiday calendar. * It is possible to override them with customized versions.*/ private static final ReferenceData REF_DATA = ReferenceData.standard(); private static final LocalDate VALUATION_DATE = LocalDate.of(2016, 8, 1); // Configuration with discounting curve using OIS up to final maturity; Libor forward curve using IRS. private static final String CONFIG_STR = "GBP-DSCONOIS-L6MIRS"; private static final CurveGroupName CONFIG_NAME = CurveGroupName.of(CONFIG_STR); /* Swap description. */ private static final Period SWAP_PERIOD_TO_START = Period.ofMonths(3); private static final double SWAP_COUPON = 0.0250; private static final double SWAP_NOTIONAL = 10_000_000; /* Path to files */ private static final String PATH_CONFIG = "src/main/resources/example-calibration/curves/"; private static final String PATH_QUOTES = "src/main/resources/example-calibration/quotes/"; /* Files utilities */ private static final String SUFFIX_CSV = ".csv"; private static final String GROUPS_SUFFIX = "-group"; private static final String NODES_SUFFIX = "-nodes"; private static final String SETTINGS_SUFFIX = "-settings"; private static final ResourceLocator GROUP_RESOURCE = ResourceLocator.of(PATH_CONFIG + CONFIG_STR + "/" + CONFIG_STR + GROUPS_SUFFIX + SUFFIX_CSV); private static final ResourceLocator SETTINGS_RESOURCE = ResourceLocator.of(PATH_CONFIG + CONFIG_STR + "/" + CONFIG_STR + SETTINGS_SUFFIX + SUFFIX_CSV); private static final ResourceLocator NODES_RESOURCE = ResourceLocator.of(PATH_CONFIG + CONFIG_STR + "/" + CONFIG_STR + NODES_SUFFIX + SUFFIX_CSV); /* Raw data */ private static final String QUOTES_FILE = PATH_QUOTES + "MARKET-QUOTES-GBP-20160801.csv"; private static final Map<QuoteId, Double> MAP_MQ = QuotesCsvLoader.load(VALUATION_DATE, ResourceLocator.of(QUOTES_FILE)); private static final ImmutableMarketData MARKET_QUOTES = ImmutableMarketData.builder(VALUATION_DATE).values(MAP_MQ).build(); private static final CalibrationMeasures CALIBRATION_MEASURES = CalibrationMeasures.PAR_SPREAD; private static final CurveCalibrator CALIBRATOR = CurveCalibrator.of(1e-9, 1e-9, 100, CALIBRATION_MEASURES); private static final DiscountingSwapTradePricer PRICER_SWAP = DiscountingSwapTradePricer.DEFAULT; private static final MarketQuoteSensitivityCalculator MQC = MarketQuoteSensitivityCalculator.DEFAULT; private static final int NB_COUPONS = 100; private static final double SWAP_COUPON_RANGE = 0.0100; private static final int NB_TENORS = 20; private static final int TENOR_START = 1; @SuppressWarnings("null") public static void main(String[] arg) { int nbRrpWarm = 2; int nbRunPerf = 2; /* Load the curve configurations from csv files */ Map<CurveGroupName, CurveGroupDefinition> configs = RatesCalibrationCsvLoader.load(GROUP_RESOURCE, SETTINGS_RESOURCE, NODES_RESOURCE); /* Construct a swaps */ ResolvedSwapTrade[] swaps = new ResolvedSwapTrade[NB_COUPONS * NB_TENORS]; for (int loopswap = 0; loopswap < NB_COUPONS; loopswap++) { for (int looptenor = 0; looptenor < NB_TENORS; looptenor++) { double coupon = SWAP_COUPON + loopswap * SWAP_COUPON_RANGE / NB_COUPONS; swaps[looptenor * NB_COUPONS + loopswap] = GBP_FIXED_6M_LIBOR_6M.createTrade( VALUATION_DATE, SWAP_PERIOD_TO_START, Tenor.of(Period.ofYears(TENOR_START + looptenor)), BuySell.BUY, SWAP_NOTIONAL, coupon, REF_DATA).resolve(REF_DATA); } } /* Warm-up */ Pair<MultiCurrencyAmount[], CurrencyParameterSensitivities[]> r = null; for (int i = 0; i < nbRrpWarm; i++) { r = computation(configs, swaps); } long start, end; start = System.currentTimeMillis(); for (int i = 0; i < nbRunPerf; i++) { r = computation(configs, swaps); } end = System.currentTimeMillis(); System.out.println("Computation time: " + (end - start) + " ms"); System.out.println("Performance estimate for curve calibration, " + (NB_COUPONS * NB_TENORS) + " trades and " + nbRunPerf + " repetitions.\n" + r.getFirst() + r.getSecond()); } private static Pair<MultiCurrencyAmount[], CurrencyParameterSensitivities[]> computation( Map<CurveGroupName, CurveGroupDefinition> configs, ResolvedSwapTrade[] swaps) { int nbSwaps = swaps.length; /* Calibrate curves */ ImmutableRatesProvider multicurve = CALIBRATOR.calibrate(configs.get(CONFIG_NAME), MARKET_QUOTES, REF_DATA); /* Computes PV and bucketed PV01 */ MultiCurrencyAmount[] pv = new MultiCurrencyAmount[nbSwaps]; CurrencyParameterSensitivities[] mqs = new CurrencyParameterSensitivities[nbSwaps]; for (int loopswap = 0; loopswap < nbSwaps; loopswap++) { pv[loopswap] = PRICER_SWAP.presentValue(swaps[loopswap], multicurve); PointSensitivities pts = PRICER_SWAP.presentValueSensitivity(swaps[loopswap], multicurve); CurrencyParameterSensitivities ps = multicurve.parameterSensitivity(pts); mqs[loopswap] = MQC.sensitivity(ps, multicurve); } return Pair.of(pv, mqs); } }