com.opengamma.strata.pricer.index.HullWhiteIborFutureProductPricer Maven / Gradle / Ivy
/*
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.pricer.index;
import java.time.LocalDate;
import com.opengamma.strata.basics.index.IborIndexObservation;
import com.opengamma.strata.collect.array.DoubleArray;
import com.opengamma.strata.market.sensitivity.PointSensitivities;
import com.opengamma.strata.pricer.model.HullWhiteOneFactorPiecewiseConstantParametersProvider;
import com.opengamma.strata.pricer.rate.IborRateSensitivity;
import com.opengamma.strata.pricer.rate.RatesProvider;
import com.opengamma.strata.product.index.IborFuture;
import com.opengamma.strata.product.index.ResolvedIborFuture;
/**
* Pricer for for Ibor future products.
*
* This function provides the ability to price a {@link IborFuture} based on
* Hull-White one-factor model with piecewise constant volatility.
*
* Reference: Henrard M., Eurodollar Futures and Options: Convexity Adjustment in HJM One-Factor Model. March 2005.
* Available at http://ssrn.com/abstract=682343
*
*
Price
* The price of an Ibor future is based on the interest rate of the underlying index.
* It is defined as {@code (100 - percentRate)}.
*
* Strata uses decimal prices for Ibor futures in the trade model, pricers and market data.
* The decimal price is based on the decimal rate equivalent to the percentage.
* For example, a price of 99.32 implies an interest rate of 0.68% which is represented in Strata by 0.9932.
*/
public class HullWhiteIborFutureProductPricer {
/**
* Default implementation.
*/
public static final HullWhiteIborFutureProductPricer DEFAULT = new HullWhiteIborFutureProductPricer();
/**
* Creates an instance.
*/
public HullWhiteIborFutureProductPricer() {
}
//-------------------------------------------------------------------------
/**
* Calculates the number related to Ibor futures product on which the daily margin is computed.
*
* For two consecutive settlement prices C1 and C2, the daily margin is computed as
* {@code (marginIndex(future, C2) - marginIndex(future, C1))}.
*
* @param future the future
* @param price the price of the product, in decimal form
* @return the index
*/
double marginIndex(ResolvedIborFuture future, double price) {
return price * future.getNotional() * future.getAccrualFactor();
}
/**
* Calculates the margin index sensitivity of the Ibor future product.
*
* The margin index sensitivity is the sensitivity of the margin index to the underlying curves.
* For two consecutive settlement prices C1 and C2, the daily margin is computed as
* {@code (marginIndex(future, C2) - marginIndex(future, C1))}.
*
* @param future the future
* @param priceSensitivity the price sensitivity of the product
* @return the index sensitivity
*/
PointSensitivities marginIndexSensitivity(ResolvedIborFuture future, PointSensitivities priceSensitivity) {
return priceSensitivity.multipliedBy(future.getNotional() * future.getAccrualFactor());
}
//-------------------------------------------------------------------------
/**
* Calculates the price of the Ibor future product.
*
* The price of the product is the price on the valuation date.
*
* @param future the future
* @param ratesProvider the rates provider
* @param hwProvider the Hull-White model parameter provider
* @return the price of the product, in decimal form
*/
public double price(
ResolvedIborFuture future,
RatesProvider ratesProvider,
HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider) {
double parRate = parRate(future, ratesProvider, hwProvider);
return 1d - parRate;
}
/**
* Calculates the convexity adjustment (to the price) of the Ibor future product.
*
* The convexity adjustment of the product is the value on the valuation date.
*
* @param future the future
* @param ratesProvider the rates provider
* @param hwProvider the Hull-White model parameter provider
* @return the convexity adjustment, in decimal form
*/
public double convexityAdjustment(
ResolvedIborFuture future,
RatesProvider ratesProvider,
HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider) {
IborIndexObservation obs = future.getIborRate().getObservation();
double forward = ratesProvider.iborIndexRates(future.getIndex()).rate(obs);
double parRate = parRate(future, ratesProvider, hwProvider);
return forward - parRate;
}
/**
* Calculates the par rate of the Ibor future product.
*
* The par rate is given by ({@code 1 - price}).
* The par rate of the product is the value on the valuation date.
*
* @param future the future
* @param ratesProvider the rates provider
* @param hwProvider the Hull-White model parameter provider
* @return the par rate of the product, in decimal form
*/
public double parRate(
ResolvedIborFuture future,
RatesProvider ratesProvider,
HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider) {
IborIndexObservation obs = future.getIborRate().getObservation();
double forward = ratesProvider.iborIndexRates(future.getIndex()).rate(obs);
LocalDate fixingStartDate = obs.getEffectiveDate();
LocalDate fixingEndDate = obs.getMaturityDate();
double fixingYearFraction = obs.getYearFraction();
double convexity = hwProvider.futuresConvexityFactor(future.getLastTradeDate(), fixingStartDate, fixingEndDate);
return convexity * forward - (1d - convexity) / fixingYearFraction;
}
/**
* Calculates the price sensitivity of the Ibor future product.
*
* The price sensitivity of the product is the sensitivity of the price to the underlying curves.
*
* @param future the future
* @param ratesProvider the rates provider
* @param hwProvider the Hull-White model parameter provider
* @return the price curve sensitivity of the product
*/
public PointSensitivities priceSensitivityRates(
ResolvedIborFuture future,
RatesProvider ratesProvider,
HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider) {
IborIndexObservation obs = future.getIborRate().getObservation();
LocalDate fixingStartDate = obs.getEffectiveDate();
LocalDate fixingEndDate = obs.getMaturityDate();
double convexity = hwProvider.futuresConvexityFactor(future.getLastTradeDate(), fixingStartDate, fixingEndDate);
IborRateSensitivity sensi = IborRateSensitivity.of(obs, -convexity);
// The sensitivity should be to no currency or currency XXX. To avoid useless conversion, the dimension-less
// price sensitivity is reported in the future currency.
return PointSensitivities.of(sensi);
}
/**
* Calculates the price sensitivity to piecewise constant volatility parameters of the Hull-White model.
*
* @param future the future
* @param ratesProvider the rates provider
* @param hwProvider the Hull-White model parameter provider
* @return the price parameter sensitivity of the product
*/
public DoubleArray priceSensitivityModelParamsHullWhite(
ResolvedIborFuture future,
RatesProvider ratesProvider,
HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider) {
IborIndexObservation obs = future.getIborRate().getObservation();
double forward = ratesProvider.iborIndexRates(future.getIndex()).rate(obs);
LocalDate fixingStartDate = obs.getEffectiveDate();
LocalDate fixingEndDate = obs.getMaturityDate();
double fixingYearFraction = obs.getYearFraction();
DoubleArray convexityDeriv = hwProvider.futuresConvexityFactorAdjoint(
future.getLastTradeDate(), fixingStartDate, fixingEndDate).getDerivatives();
convexityDeriv = convexityDeriv.multipliedBy(-forward - 1d / fixingYearFraction);
return convexityDeriv;
}
}