PV01 and DV01 for fixed-float interest rate vanilla swaps

Hi

I am trying to calculate the PV and DV01 for a plain vanilla 3 year interest rate swap.

Have the following code modified from SwapPricingTest.java:

SwapLeg payLeg = RateCalculationSwapLeg.builder()
.payReceive(PayReceive.PAY)
.accrualSchedule(PeriodicSchedule.builder()
.startDate(LocalDate.of(2016, 8, 10))
.endDate(LocalDate.of(2019, 8, 10))
.frequency(Frequency.P6M)
.businessDayAdjustment(BusinessDayAdjustment.of(BusinessDayConventions.MODIFIED_FOLLOWING, CalendarUSD.NYC))
.stubConvention(null)
.build())
.paymentSchedule(PaymentSchedule.builder()
.paymentFrequency(Frequency.P6M)
.paymentDateOffset(DaysAdjustment.NONE)
.build())
.notionalSchedule(NOTIONAL)
.calculation(FixedRateCalculation.of(1.072 * 0.01, THIRTY_U_360))
.build();

    SwapLeg receiveLeg = RateCalculationSwapLeg.builder()
        .payReceive(RECEIVE)
        .accrualSchedule(PeriodicSchedule.builder()
            .startDate(LocalDate.of(2016, 8, 10))
            .endDate(LocalDate.of(2019, 8, 10))
            .frequency(Frequency.P1M)
            .businessDayAdjustment(BusinessDayAdjustment.of(BusinessDayConventions.MODIFIED_FOLLOWING, CalendarUSD.NYC))
            .build())
        .paymentSchedule(PaymentSchedule.builder()
            .paymentFrequency(Frequency.P1M)
            .paymentDateOffset(DaysAdjustment.NONE)
            .build())
        .notionalSchedule(NOTIONAL)
        .calculation(IborRateCalculation.builder()
            .index(USD_LIBOR_1M)
            .fixingDateOffset(DaysAdjustment.ofBusinessDays(-2, CalendarUSD.NYC, BDA_P))
            .build())
        .build();

    Swap swap = Swap.of(payLeg, receiveLeg);
    SwapTrade trade = SwapTrade.builder()
        .info(TradeInfo.builder().tradeDate(LocalDate.of(2016, 8, 8)).build())
        .product(swap).build();
    
    CurveGroupName groupName = CurveGroupName.of("Test");
    CurveId idUsdDsc = CurveId.of(groupName, StandardDataSets.GROUP1_USD_DSC.getName());
    CurveId idUsdOn = CurveId.of(groupName, StandardDataSets.GROUP1_USD_ON.getName());
    CurveId idUsdL1M = CurveId.of(groupName, StandardDataSets.GROUP1_USD_L1M.getName());
    CurveId idUsdL3M = CurveId.of(groupName, StandardDataSets.GROUP1_USD_L3M.getName());
    CurveId idUsdL6M = CurveId.of(groupName, StandardDataSets.GROUP1_USD_L6M.getName());
    MarketData suppliedData = ImmutableMarketData.builder(VAL_DATE)
        .addValue(idUsdDsc, StandardDataSets.GROUP1_USD_DSC)
        .addValue(idUsdOn, StandardDataSets.GROUP1_USD_ON)
        .addValue(idUsdL1M, StandardDataSets.GROUP1_USD_L1M)
        .addValue(idUsdL3M, StandardDataSets.GROUP1_USD_L3M)
        .addValue(idUsdL6M, StandardDataSets.GROUP1_USD_L6M)
        .build();

    CalculationFunctions functions = StandardComponents.calculationFunctions();

    RatesMarketDataLookup ratesLookup = RatesMarketDataLookup.of(
        ImmutableMap.of(
            USD, idUsdDsc),
        ImmutableMap.of(
            USD_FED_FUND, idUsdOn,
            USD_LIBOR_1M, idUsdL1M,
            USD_LIBOR_3M, idUsdL3M,
            USD_LIBOR_6M, idUsdL6M));

    // create the calculation runner
    List<SwapTrade> trades = ImmutableList.of(trade);
    List<Column> columns = ImmutableList.of(
            Column.of(Measures.LEG_INITIAL_NOTIONAL),
            Column.of(Measures.PRESENT_VALUE),
            Column.of(Measures.LEG_PRESENT_VALUE),
            Column.of(Measures.PV01_CALIBRATED_SUM),
            Column.of(Measures.PAR_RATE),
            Column.of(Measures.ACCRUED_INTEREST));
    CalculationRules rules = CalculationRules.of(functions, USD, ratesLookup);

    // calculate results using the runner
    // using the direct executor means there is no need to close/shutdown the runner
    CalculationRunner runner = CalculationRunner.of(MoreExecutors.newDirectExecutorService());
    Results results = runner.calculate(rules, trades, columns, suppliedData, REF_DATA);
    //System.out.println(JodaBeanSer.PRETTY.xmlWriter().write(swap));
    
    for(int i = 0; i< results.getRowCount(); i++){
    	for(int j =0;j < results.getColumnCount(); j++){
	    	Result<?> result = results.get(i, j);
		    System.out.println(result.getClass()+":"+result.getValue());
    	}
    }

2 questions:

  1. I have my own real-time source of Libor and swap rates. How do I build the MarketData for the CalculationRunner in order to match the Bloomberg terminal ?
  2. Measures/AdvancedMeasures doesn’t have DV01. Do you currently support it ?

In your example code, you’re supplying pre-calibrated zero curves in the MarketData instance. If you want to price directly off market quotes, instead you’ll need to provide curve group configuration and a set of raw quotes keyed by Bloomberg ticker.

A convenient way of specifying curve group configuration is Strata’s CSV format. You can see this in action in the CalibrationEur3CheckExample example.

Quotes can be supplied via a similar CSV file (as in the referenced example) or simply by building up a Map<QuoteId, Double> in code. The keys of the map must align with the tickers referenced in the curve node file (called CALIBRATION_RESOURCE in the example).

When you say DV01, please could you clarify exactly what you mean? (e.g. parallel curve shift or per node/bump and reprice or algorithmic differentiation/sensitivity to par quotes or calibrated zeros?) Strata uses the terminology PV01 when referring to the first order sensitivity of a 1 b.p. shift of the underlying curve (i.e. sum) or node (i.e. bucketed), computed via algorithmic differentiation. In this case you may be interested in PV01_MARKET_QUOTE_SUM (sensitivity summed along the curve) or PV01_MARKET_QUOTE_BUCKETED (sensitivity split out by curve node).

@tim: Thanks for the reply. I tried adding both Measures.PV01_MARKET_QUOTE_BUCKETED and Measures.PV01_MARKET_QUOTE_SUM to the above code:
Getting the following exception at runtime,

Exception in thread “main” java.lang.IllegalStateException: Unable to get a value from a failure result: Market Quote sensitivity requires Jacobian calibration information.

Am I missing some ref/market data ? I still am using the pre-calibrated zero curves from the StandardDataSets.

Most likely, from BBG definition of DV01, PV01_MARKET_QUOTE_SUM is what I would likely be looking at computing.

The Jacobian is built as part of the calibration phase and cached on the curve. You need to ensure you’re calibrating the curve rather than just passing in externally calibrated zero curves. See my previous response for further details on how to do this.

Ok @tim. I will try that however I noticed the calibration-eur.csv has quotes until 30Y. The real-time data provided to me for USD Libor is only from Overnight to 1Y. Is there any way to workaround this issue ?

When you say:

The real-time data provided to me for USD Libor is only from Overnight to 1Y

Are you referring to the curves in the curve group only being specified for indices from ON to 1Y? Or is it that the par rates on the curve only going out to 1Y? In either case you should be able to configure the calibrator appropriately. See either the docs on curve groups file or curve nodes file. If the curve nodes do only go out to 1Y, you can configure an extrapolator in the curve settings file.

@tim: Would it be possible to use the Strata library to price the interest rate swap using Eurodollar futures prices ? If so, I would like to go with this approach rather than extrapolating the curve nodes for USD Libor. Please advise.

Yes, futures nodes are supported. See IborFuture node type in the calibration docs.

Note, I linked you to the wrong page for curve nodes in my last post due to a bogus link on the docs site. Here’s the actual curve nodes page for calibrated curves.

Have the following code to load the csv files:

// load quotes
ImmutableMap<QuoteId, Double> quotes = QuotesCsvLoader.load(VAL_DATE, QUOTES_RESOURCE);

// create the market data
MarketData marketData = ImmutableMarketData.of(VAL_DATE, quotes);

// load the curve definition
Map<CurveGroupName, CurveGroupDefinition> defns =
RatesCalibrationCsvLoader.load(GROUPS_RESOURCE, SETTINGS_RESOURCE, CALIBRATION_RESOURCE);

//CurveId usdLiborCurve = CurveId.of(CURVE_GROUP_NAME.toString(), “USD-LIBOR-IRS”);

CurveGroupDefinition curveGroupDefinition = defns.get(CURVE_GROUP_NAME).filtered(VAL_DATE, REF_DATA);

// the configuration that defines how to create the curves when a curve group is requested
MarketDataConfig marketDataConfig = MarketDataConfig.builder()
.add(CURVE_GROUP_NAME, curveGroupDefinition)
.build();
// the complete set of rules for calculating measures
CalculationFunctions functions = StandardComponents.calculationFunctions();
RatesMarketDataLookup ratesLookup = RatesMarketDataLookup.of(curveGroupDefinition);
CalculationRules rules = CalculationRules.of(functions, ratesLookup);
// calculate results using the runner
// using the direct executor means there is no need to close/shutdown the runner
CalculationRunner runner = CalculationRunner.of(MoreExecutors.newDirectExecutorService());
List trades = ImmutableList.of(trade);
List columns = ImmutableList.of(
Column.of(Measures.LEG_INITIAL_NOTIONAL),
Column.of(Measures.PRESENT_VALUE),
Column.of(Measures.LEG_PRESENT_VALUE),
Column.of(Measures.PV01_CALIBRATED_SUM),
Column.of(Measures.PAR_RATE),
Column.of(Measures.ACCRUED_INTEREST),
Column.of(Measures.PV01_MARKET_QUOTE_SUM),
Column.of(Measures.PV01_MARKET_QUOTE_BUCKETED)
);
// calibrate the curves and calculate the results
MarketDataRequirements reqs = MarketDataRequirements.of(rules, trades, columns, REF_DATA);
MarketData calibratedMarketData = marketDataFactory().create(reqs, marketDataConfig, marketData, REF_DATA);
Results results = runner.calculate(rules, trades, columns, calibratedMarketData, REF_DATA);

However it gives the following exception:

Exception in thread “main” java.lang.IllegalArgumentException: Rates lookup has no forward curve defined for index 'USD-LIBOR-1M’
at com.opengamma.strata.measure.rate.DefaultRatesMarketDataLookup.requirements(DefaultRatesMarketDataLookup.java:137)
at com.opengamma.strata.measure.swap.SwapTradeCalculationFunction.requirements(SwapTradeCalculationFunction.java:123)
at com.opengamma.strata.measure.swap.SwapTradeCalculationFunction.requirements(SwapTradeCalculationFunction.java:1)
at com.opengamma.strata.calc.runner.CalculationTask.requirements(CalculationTask.java:148)
at com.opengamma.strata.calc.runner.CalculationTasks.requirements(CalculationTasks.java:207)
at com.opengamma.strata.calc.marketdata.MarketDataRequirements.of(MarketDataRequirements.java:87)

My csv files are as follows:

calibrations-usd.csv
Curve Name,Label,Symbology,Ticker,Field Name,Type,Convention,Time,Date,Min Gap,Clash Action,Spread
USD-LIBOR-IRS,IRS-1M,OG-Ticker,USD-IRS-1M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,1M,
USD-LIBOR-IRS,IRS-2M,OG-Ticker,USD-IRS-2M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,2M,
USD-LIBOR-IRS,IRS-3M,OG-Ticker,USD-IRS-3M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,3M,
USD-LIBOR-IRS,IRS-6M,OG-Ticker,USD-IRS-6M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,6M,
USD-LIBOR-IRS,IRS-1Y,OG-Ticker,USD-IRS-1Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,1Y,

groups-usd.csv
Group Name,Curve Type,Reference,Curve Name
LIBOR,Discount,USD,USD-LIBOR-IRS

quotes-usd.csv
Valuation Date,Symbology,Ticker,Field Name,Value
2016-08-09,OG-Ticker,USD-IRS-1M,MarketValue,0.005119
2016-08-09,OG-Ticker,USD-IRS-2M,MarketValue,0.006268
2016-08-09,OG-Ticker,USD-IRS-3M,MarketValue,0.008065
2016-08-09,OG-Ticker,USD-IRS-6M,MarketValue,0.011852
2016-08-09,OG-Ticker,USD-IRS-1Y,MarketValue,0.015081

settings-usd.csv
Curve Name,Value Type,Day Count,Interpolator,Left Extrapolator,Right Extrapolator
USD-LIBOR-IRS,df,Act/365F,LogNaturalSplineDiscountFactor,Interpolator,LogLinear

The swap you have defined above receives floating payments based on the USD_LIBOR_1M index, therefore you’ll need to configure a curve to project its rate. The most straight-forward approach is to reuse your discount curve as a forward curve like so:

groups-usd.csv

Group Name,Curve Type,Reference,Curve Name
LIBOR,Discount,USD,USD-LIBOR-IRS
LIBOR,Forward,USD-LIBOR-1M,USD-LIBOR-IRS

This effectively specifies a single-curve pricing environment (i.e. same curve for projection and discounting). You may also want to consider specifying a separate curve/par rates for projection, as in the aforementioned EUR example.

@tim: Just looked at Bloomberg and they are using

  1. 3m Libor rates
  2. Eurodollar futures from Sep 2016 till Dec 2017.(convexity adjusted).
  3. Swap rates from 2Y - 50Y.

to build a single curve to calculate the DV01. Is this what you mean by a discount and a forward curve in the groups-usd.csv ?

Also, I am getting an exception after loading the 3 curves and running the calculation for floating leg with index = USD_LIBOR_3M

Exception in thread “main” java.lang.IllegalStateException: Unable to get a value from a failure result: yData containing NaN
at com.opengamma.strata.collect.result.Result.getValue(Result.java:610)

My csv files are as given below:

settings-usd.csv
Curve Name,Value Type,Day Count,Interpolator,Left Extrapolator,Right Extrapolator
USD-LIBOR-IRS,df,Act/365F,LogNaturalSplineDiscountFactor,Interpolator,LogLinear
EURODOLLAR-FUTURE,df,Act/365F,LogNaturalSplineDiscountFactor,Interpolator,LogLinear
SWAP-RATES,df,Act/365F,LogNaturalSplineDiscountFactor,Interpolator,LogLinear

groups-usd.csv
Group Name,Curve Type,Reference,Curve Name
SWAP_CURVE,Discount,USD,USD-LIBOR-IRS
SWAP_CURVE,Forward,USD-LIBOR-3M,EURODOLLAR-FUTURE
SWAP_CURVE,Forward,USD-LIBOR-3M,SWAP-RATES

calibrations-usd.csv
Curve Name,Label,Symbology,Ticker,Field Name,Type,Convention,Time,Date,Min Gap,Clash Action,Spread
USD-LIBOR-IRS,USD_LIBOR-IRS-1M,OG-Ticker,USD_LIBOR-IRS-1M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,1M,
USD-LIBOR-IRS,USD_LIBOR-IRS-2M,OG-Ticker,USD_LIBOR-IRS-2M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,2M,
USD-LIBOR-IRS,USD_LIBOR-IRS-3M,OG-Ticker,USD_LIBOR-IRS-3M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,3M,
USD-LIBOR-IRS,USD_LIBOR-IRS-6M,OG-Ticker,USD_LIBOR-IRS-6M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,6M,
USD-LIBOR-IRS,USD_LIBOR-IRS-1Y,OG-Ticker,USD_LIBOR-IRS-1Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,1Y,
EURODOLLAR-FUTURE,EURODOLLAR-FUTURE-6M,OG-Ticker,EURODOLLAR-FUTURE-6M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,6M,
EURODOLLAR-FUTURE,EURODOLLAR-FUTURE-9M,OG-Ticker,EURODOLLAR-FUTURE-9M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,9M,
EURODOLLAR-FUTURE,EURODOLLAR-FUTURE-1Y,OG-Ticker,EURODOLLAR-FUTURE-1Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,1Y,
EURODOLLAR-FUTURE,EURODOLLAR-FUTURE-15M,OG-Ticker,EURODOLLAR-FUTURE-15M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,15M,
EURODOLLAR-FUTURE,EURODOLLAR-FUTURE-18M,OG-Ticker,EURODOLLAR-FUTURE-18M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,18M,
EURODOLLAR-FUTURE,EURODOLLAR-FUTURE-21M,OG-Ticker,EURODOLLAR-FUTURE-21M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,21M,
SWAP-RATES,SWAP-RATES-2Y,OG-Ticker,SWAP-RATES-2Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,2Y,
SWAP-RATES,SWAP-RATES-3Y,OG-Ticker,SWAP-RATES-3Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,3Y,
SWAP-RATES,SWAP-RATES-4Y,OG-Ticker,SWAP-RATES-4Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,4Y,
SWAP-RATES,SWAP-RATES-5Y,OG-Ticker,SWAP-RATES-5Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,5Y,
SWAP-RATES,SWAP-RATES-6Y,OG-Ticker,SWAP-RATES-6Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,6Y,
SWAP-RATES,SWAP-RATES-7Y,OG-Ticker,SWAP-RATES-7Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,7Y,
SWAP-RATES,SWAP-RATES-10Y,OG-Ticker,SWAP-RATES-10Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,10Y,

quotes-usd.csv
Valuation Date,Symbology,Ticker,Field Name,Value
2016-08-15,OG-Ticker,USD_LIBOR-IRS-1M,MarketValue,0.0050665
2016-08-15,OG-Ticker,USD_LIBOR-IRS-2M,MarketValue,0.0063255
2016-08-15,OG-Ticker,USD_LIBOR-IRS-3M,MarketValue,0.0081825
2016-08-15,OG-Ticker,USD_LIBOR-IRS-6M,MarketValue,0.012067
2016-08-15,OG-Ticker,USD_LIBOR-IRS-1Y,MarketValue,0.015257
2016-08-15,OG-Ticker,EURODOLLAR-FUTURE-6M,MarketValue,0.0082727
2016-08-15,OG-Ticker,EURODOLLAR-FUTURE-9M,MarketValue,0.0087891
2016-08-15,OG-Ticker,EURODOLLAR-FUTURE-1Y,MarketValue,0.0090751
2016-08-15,OG-Ticker,EURODOLLAR-FUTURE-15M,MarketValue,0.0094562
2016-08-15,OG-Ticker,EURODOLLAR-FUTURE-18M,MarketValue,0.0097833
2016-08-15,OG-Ticker,EURODOLLAR-FUTURE-21M,MarketValue,0.010256
2016-08-15,OG-Ticker,SWAP-RATES-2Y,MarketValue,0.0095742
2016-08-15,OG-Ticker,SWAP-RATES-3Y,MarketValue,0.0101884
2016-08-15,OG-Ticker,SWAP-RATES-4Y,MarketValue,0.0107997
2016-08-15,OG-Ticker,SWAP-RATES-5Y,MarketValue,0.0114322
2016-08-15,OG-Ticker,SWAP-RATES-6Y,MarketValue,0.0120991
2016-08-15,OG-Ticker,SWAP-RATES-7Y,MarketValue,0.0127277
2016-08-15,OG-Ticker,SWAP-RATES-10Y,MarketValue,0.0143447

A discount curve is used for present value discounting. A forward curve is used to predict the value of an index such as LIBOR in the future.

Your definition is currently split in three parts, but it looks like you only want one curve (used for both discounting and forward LIBOR). As such, you should have a single curve in settings-usd, referred to in groups-usd for both discount and forward. All nodes then refer to the same curve:

settings-usd.csv

Curve Name,Value Type,Day Count,Interpolator,Left Extrapolator,Right Extrapolator
USD-CURVE,zero,Act/365F,LogNaturalSplineDiscountFactor,Interpolator,LogLinear

groups-usd.csv

Group Name,Curve Type,Reference,Curve Name
SWAP_CURVE,Discount,USD,USD-CURVE
SWAP_CURVE,Forward,USD-LIBOR-3M,USD-CURVE

calibrations-usd.csv

Curve Name,Label,Symbology,Ticker,Field Name,Type,Convention,Time,Date,Min Gap,Clash Action,Spread
USD-CURVE,USD_LIBOR-IRS-1M,OG-Ticker,USD_LIBOR-IRS-1M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,1M,,,,
USD-CURVE,USD_LIBOR-IRS-2M,OG-Ticker,USD_LIBOR-IRS-2M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,2M,,,,
USD-CURVE,USD_LIBOR-IRS-3M,OG-Ticker,USD_LIBOR-IRS-3M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,3M,,,,
USD-CURVE,USD_LIBOR-IRS-6M,OG-Ticker,USD_LIBOR-IRS-6M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,6M,,,,
USD-CURVE,USD_LIBOR-IRS-1Y,OG-Ticker,USD_LIBOR-IRS-1Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,1Y,,,,
USD-CURVE,EURODOLLAR-FUTURE-6M,OG-Ticker,EURODOLLAR-FUTURE-6M,SettlementPrice,IRS,USD-LIBOR-3M-Quarterly-IMM,Mar17,7D,DropThis,,
USD-CURVE,EURODOLLAR-FUTURE-9M,OG-Ticker,EURODOLLAR-FUTURE-9M,SettlementPrice,IRS,USD-LIBOR-3M-Quarterly-IMM,Jun17,7D,DropThis,,
USD-CURVE,EURODOLLAR-FUTURE-1Y,OG-Ticker,EURODOLLAR-FUTURE-1Y,SettlementPrice,IRS,USD-LIBOR-3M-Quarterly-IMM,Sep17,7D,DropThis,,
USD-CURVE,EURODOLLAR-FUTURE-15M,OG-Ticker,EURODOLLAR-FUTURE-15M,SettlementPrice,IRS,USD-LIBOR-3M-Quarterly-IMM,Dec17,7D,DropThis,,
USD-CURVE,EURODOLLAR-FUTURE-18M,OG-Ticker,EURODOLLAR-FUTURE-18M,SettlementPrice,IRS,USD-LIBOR-3M-Quarterly-IMM,Mar18,7D,DropThis,,
USD-CURVE,EURODOLLAR-FUTURE-21M,OG-Ticker,EURODOLLAR-FUTURE-21M,SettlementPrice,IRS,USD-LIBOR-3M-Quarterly-IMM,Jun18,7D,DropThis,,
USD-CURVE,SWAP-RATES-2Y,OG-Ticker,SWAP-RATES-2Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,2Y,,,,
USD-CURVE,SWAP-RATES-3Y,OG-Ticker,SWAP-RATES-3Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,3Y,,,,
USD-CURVE,SWAP-RATES-4Y,OG-Ticker,SWAP-RATES-4Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,4Y,,,,
USD-CURVE,SWAP-RATES-5Y,OG-Ticker,SWAP-RATES-5Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,5Y,,,,
USD-CURVE,SWAP-RATES-6Y,OG-Ticker,SWAP-RATES-6Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,6Y,,,,
USD-CURVE,SWAP-RATES-7Y,OG-Ticker,SWAP-RATES-7Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,7Y,,,,
USD-CURVE,SWAP-RATES-10Y,OG-Ticker,SWAP-RATES-10Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,10Y,,,,

quotes-usd.csv

Valuation Date,Symbology,Ticker,Field Name,Value
2016-08-15,OG-Ticker,USD_LIBOR-IRS-1M,MarketValue,0.0050665
2016-08-15,OG-Ticker,USD_LIBOR-IRS-2M,MarketValue,0.0063255
2016-08-15,OG-Ticker,USD_LIBOR-IRS-3M,MarketValue,0.0081825
2016-08-15,OG-Ticker,USD_LIBOR-IRS-6M,MarketValue,0.012067
2016-08-15,OG-Ticker,USD_LIBOR-IRS-1Y,MarketValue,0.015257
2016-08-15,OG-Ticker,EURODOLLAR-FUTURE-6M,SettlementPrice,0.0082727
2016-08-15,OG-Ticker,EURODOLLAR-FUTURE-9M,SettlementPrice,0.0087891
2016-08-15,OG-Ticker,EURODOLLAR-FUTURE-1Y,SettlementPrice,0.0090751
2016-08-15,OG-Ticker,EURODOLLAR-FUTURE-15M,SettlementPrice,0.0094562
2016-08-15,OG-Ticker,EURODOLLAR-FUTURE-18M,SettlementPrice,0.0097833
2016-08-15,OG-Ticker,EURODOLLAR-FUTURE-21M,SettlementPrice,0.010256
2016-08-15,OG-Ticker,SWAP-RATES-2Y,MarketValue,0.0095742
2016-08-15,OG-Ticker,SWAP-RATES-3Y,MarketValue,0.0101884
2016-08-15,OG-Ticker,SWAP-RATES-4Y,MarketValue,0.0107997
2016-08-15,OG-Ticker,SWAP-RATES-5Y,MarketValue,0.0114322
2016-08-15,OG-Ticker,SWAP-RATES-6Y,MarketValue,0.0120991
2016-08-15,OG-Ticker,SWAP-RATES-7Y,MarketValue,0.0127277
2016-08-15,OG-Ticker,SWAP-RATES-10Y,MarketValue,0.0143447

Because you have some futures that are before short-tenor swaps, I have added “7D, DropThis” to the futures nodes. This will cause a future to be dropped when building the curve if it is within 7 days, or before, an IRS row. You may want to remove/drop the 6M or 1Y swap instead.

I have also corrected the definition of the futures. I changed them from “MarketValue” to “SettlementPrice”, and changed the convention. See the documentation for more details on the valid values for each node.

I suspect that your short-tenor swaps should be OIS, not IRS, but I haven’t changed those.

@stephen: Thanks for replying with the corrections. I had to modify the calibration-usd.csv a little bit to match them to the enum IborFutureConventions however they seem to give the same exception:

Exception in thread “main” java.lang.IllegalStateException: Unable to get a value from a failure result: yData containing NaN
at com.opengamma.strata.collect.result.Result.getValue(Result.java:610)

calibrations-usd.csv
Curve Name,Label,Symbology,Ticker,Field Name,Type,Convention,Time,Date,Min Gap,Clash Action,Spread
USD-CURVE,USD_LIBOR-IRS-1M,OG-Ticker,USD_LIBOR-IRS-1M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,1M,
USD-CURVE,USD_LIBOR-IRS-2M,OG-Ticker,USD_LIBOR-IRS-2M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,2M,
USD-CURVE,USD_LIBOR-IRS-3M,OG-Ticker,USD_LIBOR-IRS-3M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,3M,
USD-CURVE,USD_LIBOR-IRS-6M,OG-Ticker,USD_LIBOR-IRS-6M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,6M,
USD-CURVE,USD_LIBOR-IRS-1Y,OG-Ticker,USD_LIBOR-IRS-1Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,1Y,
USD-CURVE,EURODOLLAR-FUTURE-6M,OG-Ticker,EURODOLLAR-FUTURE-6M,SettlementPrice,IFU,USD-LIBOR-3M-Quarterly-IMM,P3M+3,2017-03-01,P7D,DropThis,
USD-CURVE,EURODOLLAR-FUTURE-9M,OG-Ticker,EURODOLLAR-FUTURE-9M,SettlementPrice,IFU,USD-LIBOR-3M-Quarterly-IMM,P6M+3,2017-06-01,P7D,DropThis,
USD-CURVE,EURODOLLAR-FUTURE-1Y,OG-Ticker,EURODOLLAR-FUTURE-1Y,SettlementPrice,IFU,USD-LIBOR-3M-Quarterly-IMM,P6M+6,2017-09-01,P7D,DropThis,
USD-CURVE,EURODOLLAR-FUTURE-15M,OG-Ticker,EURODOLLAR-FUTURE-15M,SettlementPrice,IFU,USD-LIBOR-3M-Quarterly-IMM,P9M+6,2017-12-01,P7D,DropThis,
USD-CURVE,EURODOLLAR-FUTURE-18M,OG-Ticker,EURODOLLAR-FUTURE-18M,SettlementPrice,IFU,USD-LIBOR-3M-Quarterly-IMM,P9M+9,2018-03-01,P7D,DropThis,
USD-CURVE,SWAP-RATES-2Y,OG-Ticker,SWAP-RATES-2Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,2Y,
USD-CURVE,SWAP-RATES-3Y,OG-Ticker,SWAP-RATES-3Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,3Y,
USD-CURVE,SWAP-RATES-4Y,OG-Ticker,SWAP-RATES-4Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,4Y,
USD-CURVE,SWAP-RATES-5Y,OG-Ticker,SWAP-RATES-5Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,5Y,
USD-CURVE,SWAP-RATES-6Y,OG-Ticker,SWAP-RATES-6Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,6Y,
USD-CURVE,SWAP-RATES-7Y,OG-Ticker,SWAP-RATES-7Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,7Y,
USD-CURVE,SWAP-RATES-10Y,OG-Ticker,SWAP-RATES-10Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,10Y,

The following file produces output:

Curve Name,Label,Symbology,Ticker,Field Name,Type,Convention,Time,Date,Min Gap,Clash Action,Spread
USD-CURVE,USD_LIBOR-IRS-3M,OG-Ticker,USD_LIBOR-IRS-3M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,3M,,,,
USD-CURVE,USD_LIBOR-IRS-6M,OG-Ticker,USD_LIBOR-IRS-6M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,6M,,,,
USD-CURVE,USD_LIBOR-IRS-1Y,OG-Ticker,USD_LIBOR-IRS-1Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,1Y,,,,
USD-CURVE,EURODOLLAR-FUTURE-6M,OG-Ticker,EURODOLLAR-FUTURE-6M,SettlementPrice,IFU,USD-LIBOR-3M-Quarterly-IMM,Mar17,,7D,DropThis,
USD-CURVE,EURODOLLAR-FUTURE-9M,OG-Ticker,EURODOLLAR-FUTURE-9M,SettlementPrice,IFU,USD-LIBOR-3M-Quarterly-IMM,Jun17,,7D,DropThis,
USD-CURVE,EURODOLLAR-FUTURE-1Y,OG-Ticker,EURODOLLAR-FUTURE-1Y,SettlementPrice,IFU,USD-LIBOR-3M-Quarterly-IMM,Sep17,,7D,DropThis,
USD-CURVE,EURODOLLAR-FUTURE-15M,OG-Ticker,EURODOLLAR-FUTURE-15M,SettlementPrice,IFU,USD-LIBOR-3M-Quarterly-IMM,Dec17,,7D,DropThis,
USD-CURVE,EURODOLLAR-FUTURE-18M,OG-Ticker,EURODOLLAR-FUTURE-18M,SettlementPrice,IFU,USD-LIBOR-3M-Quarterly-IMM,Mar18,,7D,DropThis,
USD-CURVE,EURODOLLAR-FUTURE-21M,OG-Ticker,EURODOLLAR-FUTURE-21M,SettlementPrice,IFU,USD-LIBOR-3M-Quarterly-IMM,Jun18,,7D,DropThis,
USD-CURVE,SWAP-RATES-2Y,OG-Ticker,SWAP-RATES-2Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,2Y,,,,
USD-CURVE,SWAP-RATES-3Y,OG-Ticker,SWAP-RATES-3Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,3Y,,,,
USD-CURVE,SWAP-RATES-4Y,OG-Ticker,SWAP-RATES-4Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,4Y,,,,
USD-CURVE,SWAP-RATES-5Y,OG-Ticker,SWAP-RATES-5Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,5Y,,,,
USD-CURVE,SWAP-RATES-6Y,OG-Ticker,SWAP-RATES-6Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,6Y,,,,
USD-CURVE,SWAP-RATES-7Y,OG-Ticker,SWAP-RATES-7Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,7Y,,,,
USD-CURVE,SWAP-RATES-10Y,OG-Ticker,SWAP-RATES-10Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,10Y,,,,

It fixes my mistakes in the futures rows and removes the 1 and 2 month swaps.

As I mentioned above, you are defining vanilla interest rate swaps for the short-tenor nodes. For the 1 and two month nodes, you were defining a swap that lasts just 1 or 2 months but observes 2 month LIBOR, which isn’t sensible, thus I removed it.

@stephen: Thanks for this update. DV01 (PV01_CALIBRATED_SUM) outputs to 2880.75 whereas Bloomberg gives 2950.
I noticed Bloomberg only uses the 3M Libor rate while dropping the 6M and 1Y for building the curve data. When I mimicked that as shown as below and ran the code for 1Y to 30Y tenor swaps:

calibrations-usd.csv:

Curve Name,Label,Symbology,Ticker,Field Name,Type,Convention,Time,Date,Min Gap,Clash Action,Spread
USD-CURVE,USD_LIBOR-IRS-3M,OG-Ticker,USD_LIBOR-IRS-3M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,3M,,,,
USD-CURVE,USD_LIBOR-IRS-6M,OG-Ticker,USD_LIBOR-IRS-6M,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,6M,,,DropThis,
USD-CURVE,USD_LIBOR-IRS-1Y,OG-Ticker,USD_LIBOR-IRS-1Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,1Y,,,DropThis,
USD-CURVE,EURODOLLAR-FUTURE-6M,OG-Ticker,EURODOLLAR-FUTURE-6M,SettlementPrice,IFU,USD-LIBOR-3M-Quarterly-IMM,Sep16,,,,
USD-CURVE,EURODOLLAR-FUTURE-9M,OG-Ticker,EURODOLLAR-FUTURE-9M,SettlementPrice,IFU,USD-LIBOR-3M-Quarterly-IMM,Dec16,,,,
USD-CURVE,EURODOLLAR-FUTURE-1Y,OG-Ticker,EURODOLLAR-FUTURE-1Y,SettlementPrice,IFU,USD-LIBOR-3M-Quarterly-IMM,Mar17,,7D,DropThis,
USD-CURVE,EURODOLLAR-FUTURE-15M,OG-Ticker,EURODOLLAR-FUTURE-15M,SettlementPrice,IFU,USD-LIBOR-3M-Quarterly-IMM,Jun17,,7D,DropThis,
USD-CURVE,EURODOLLAR-FUTURE-18M,OG-Ticker,EURODOLLAR-FUTURE-18M,SettlementPrice,IFU,USD-LIBOR-3M-Quarterly-IMM,Sep17,,7D,DropThis,
USD-CURVE,EURODOLLAR-FUTURE-21M,OG-Ticker,EURODOLLAR-FUTURE-21M,SettlementPrice,IFU,USD-LIBOR-3M-Quarterly-IMM,Dec17,,7D,DropThis,
USD-CURVE,SWAP-RATES-2Y,OG-Ticker,SWAP-RATES-2Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,2Y,,,,
USD-CURVE,SWAP-RATES-3Y,OG-Ticker,SWAP-RATES-3Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,3Y,,,,
USD-CURVE,SWAP-RATES-4Y,OG-Ticker,SWAP-RATES-4Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,4Y,,,,
USD-CURVE,SWAP-RATES-5Y,OG-Ticker,SWAP-RATES-5Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,5Y,,,,
USD-CURVE,SWAP-RATES-6Y,OG-Ticker,SWAP-RATES-6Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,6Y,,,,
USD-CURVE,SWAP-RATES-7Y,OG-Ticker,SWAP-RATES-7Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,7Y,,,,
USD-CURVE,SWAP-RATES-10Y,OG-Ticker,SWAP-RATES-10Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,10Y,,,,
USD-CURVE,SWAP-RATES-11Y,OG-Ticker,SWAP-RATES-11Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,11Y,,,,
USD-CURVE,SWAP-RATES-12Y,OG-Ticker,SWAP-RATES-12Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,12Y,,,,
USD-CURVE,SWAP-RATES-15Y,OG-Ticker,SWAP-RATES-15Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,15Y,,,,
USD-CURVE,SWAP-RATES-20Y,OG-Ticker,SWAP-RATES-20Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,20Y,,,,
USD-CURVE,SWAP-RATES-25Y,OG-Ticker,SWAP-RATES-25Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,25Y,,,,
USD-CURVE,SWAP-RATES-30Y,OG-Ticker,SWAP-RATES-30Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,30Y,,,,
USD-CURVE,SWAP-RATES-40Y,OG-Ticker,SWAP-RATES-40Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,40Y,,,,
USD-CURVE,SWAP-RATES-50Y,OG-Ticker,SWAP-RATES-50Y,MarketValue,IRS,USD-FIXED-6M-LIBOR-3M,50Y,,,,

quotes-usd.csv

Valuation Date,Symbology,Ticker,Field Name,Value
2016-08-26,OG-Ticker,USD_LIBOR-IRS-3M,MarketValue,0.0082933
2016-08-26,OG-Ticker,USD_LIBOR-IRS-6M,MarketValue,0.0121011
2016-08-26,OG-Ticker,USD_LIBOR-IRS-1Y,MarketValue,0.0151544
2016-08-26,OG-Ticker,EURODOLLAR-FUTURE-6M,SettlementPrice,0.0088738
2016-08-26,OG-Ticker,EURODOLLAR-FUTURE-9M,SettlementPrice,0.0095418
2016-08-26,OG-Ticker,EURODOLLAR-FUTURE-1Y,SettlementPrice,0.00993
2016-08-26,OG-Ticker,EURODOLLAR-FUTURE-15M,SettlementPrice,0.0103138
2016-08-26,OG-Ticker,EURODOLLAR-FUTURE-18M,SettlementPrice,0.0106939
2016-08-26,OG-Ticker,EURODOLLAR-FUTURE-21M,SettlementPrice,0.0111701
2016-08-26,OG-Ticker,SWAP-RATES-2Y,MarketValue,0.0104525
2016-08-26,OG-Ticker,SWAP-RATES-3Y,MarketValue,0.010670
2016-08-26,OG-Ticker,SWAP-RATES-4Y,MarketValue,0.0116150
2016-08-26,OG-Ticker,SWAP-RATES-5Y,MarketValue,0.012159
2016-08-26,OG-Ticker,SWAP-RATES-6Y,MarketValue,0.0127
2016-08-26,OG-Ticker,SWAP-RATES-7Y,MarketValue,0.01321
2016-08-26,OG-Ticker,SWAP-RATES-8Y,MarketValue,0.01369
2016-08-26,OG-Ticker,SWAP-RATES-9Y,MarketValue,0.0141225
2016-08-26,OG-Ticker,SWAP-RATES-10Y,MarketValue,0.01451
2016-08-26,OG-Ticker,SWAP-RATES-11Y,MarketValue,0.0148677
2016-08-26,OG-Ticker,SWAP-RATES-12Y,MarketValue,0.015175
2016-08-26,OG-Ticker,SWAP-RATES-15Y,MarketValue,0.015875
2016-08-26,OG-Ticker,SWAP-RATES-20Y,MarketValue,0.016605
2016-08-26,OG-Ticker,SWAP-RATES-25Y,MarketValue,0.0169177
2016-08-26,OG-Ticker,SWAP-RATES-30Y,MarketValue,0.01707
2016-08-26,OG-Ticker,SWAP-RATES-40Y,MarketValue,0.0172075
2016-08-26,OG-Ticker,SWAP-RATES-50Y,MarketValue,0.017095

DV01 Comparison Output:

Tenor|VAL_DATE|startDate|endDate|Fixed Rate (in %)|Bloomberg DV01 (in USD)|OpenGamma DVO1 (in USD)|Diff (in %)
1Y|2016-08-26|2016-08-31|2017-08-31|0.952347|756.94|USD 23.362472959353536|96.9135634317973
2Y|2016-08-26|2016-08-31|2018-08-31|1.015999|1981.01|USD 1936.6760404401668|2.23794728748634
3Y|2016-08-26|2016-08-31|2019-08-31|1.0682|2952.37|USD 2903.392958407643|1.6589059498760903
4Y|2016-08-26|2016-08-31|2020-08-31|1.1171|3906.47|USD 3860.3812344075027|1.1798059524966815
5Y|2016-08-26|2016-08-31|2021-08-31|1.16475|4861.16|USD 4822.2973053886035|0.799453106077487
6Y|2016-08-26|2016-08-31|2022-08-31|1.217629|5796.86|USD 5755.543735287856|0.7127352517077089
7Y|2016-08-26|2016-08-31|2023-08-31|1.2755|6716.5|USD 6672.95323185361|0.6483550680620813
8Y|2016-08-26|2016-08-31|2024-08-31|1.32564|7619.0|USD 7613.9280876817875|0.06656926523444712
9Y|2016-08-26|2016-08-31|2025-08-31|1.37065|8503.64|USD 8479.684247244475|0.28171174644651437
10Y|2016-08-26|2016-08-31|2026-08-31|1.409039|9373.51|USD 9323.941134334864|0.52881861399984
15Y|2016-08-26|2016-08-31|2031-08-31|1.553999|13505.17|USD 13404.502535043599|0.7453994652151812
20Y|2016-08-26|2016-08-31|2036-08-31|1.63225|17264.54|USD 17112.301378369433|0.8817994665978222
25Y|2016-08-26|2016-08-31|2041-08-31|1.6655|20689.89|USD 20504.66856970134|0.8952267522865403
30Y|2016-08-26|2016-08-31|2046-08-31|1.684|23812.14|USD 23619.801416854203|0.8077332954778373

The % difference is quite huge for the 1Y swap. Also, is the % difference for other swaps expected ?

I calculated the DV01 for the 1Y tenor swap using fixed coupon bond versus floating rate coupon bond valuation.The number (USD 747) appears to be close to Bloomberg terminal’s DV01 number (USD 756). However Opengamma’s number for 1Y swap is USD 23 which is way off. Can you please advise ?

Hi Sudharshan,

We support open source users of the library through the forum on its generic aspects.

In general, it is difficult for us to provide a consulting service with detailed comparison of our library to other systems through the forum.

The best approach is probably to have a phone conversation on what you try to achieve and how we can help in a more structured way. I will contact you privately.

Regards,

Marc Henrard