/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.interestrate.future.calculator;
import com.opengamma.analytics.financial.interestrate.InstrumentDerivativeVisitorAdapter;
import com.opengamma.analytics.financial.interestrate.annuity.derivative.AnnuityPaymentFixed;
import com.opengamma.analytics.financial.interestrate.future.derivative.InterestRateFutureSecurity;
import com.opengamma.analytics.financial.interestrate.future.derivative.SwapFuturesPriceDeliverableSecurity;
import com.opengamma.analytics.financial.model.interestrate.HullWhiteOneFactorPiecewiseConstantInterestRateModel;
import com.opengamma.analytics.financial.model.interestrate.definition.HullWhiteOneFactorPiecewiseConstantParameters;
import com.opengamma.analytics.financial.provider.calculator.discounting.CashFlowEquivalentCalculator;
import com.opengamma.analytics.financial.provider.description.interestrate.HullWhiteOneFactorProviderInterface;
import com.opengamma.analytics.financial.provider.description.interestrate.MulticurveProviderInterface;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.money.Currency;
/**
* Computes the price for different types of futures. Calculator using a multi-curve and Hull-White one-factor parameters provider.
*/
public final class FuturesPriceHullWhiteCalculator extends InstrumentDerivativeVisitorAdapter<HullWhiteOneFactorProviderInterface, Double> {
/**
* The unique instance of the calculator.
*/
private static final FuturesPriceHullWhiteCalculator INSTANCE = new FuturesPriceHullWhiteCalculator();
/**
* Gets the calculator instance.
* @return The calculator.
*/
public static FuturesPriceHullWhiteCalculator getInstance() {
return INSTANCE;
}
/**
* Constructor.
*/
private FuturesPriceHullWhiteCalculator() {
}
/**
* The Hull-White model.
*/
private static final HullWhiteOneFactorPiecewiseConstantInterestRateModel MODEL = new HullWhiteOneFactorPiecewiseConstantInterestRateModel();
/**
* The cash flow equivalent calculator used in computations.
*/
private static final CashFlowEquivalentCalculator CFEC = CashFlowEquivalentCalculator.getInstance();
// ----- Futures -----
@Override
public Double visitInterestRateFutureSecurity(final InterestRateFutureSecurity futures, final HullWhiteOneFactorProviderInterface multicurve) {
ArgumentChecker.notNull(futures, "Future");
ArgumentChecker.notNull(multicurve, "Multi-curve with Hull-White");
final double forward = multicurve.getMulticurveProvider().getSimplyCompoundForwardRate(futures.getIborIndex(), futures.getFixingPeriodStartTime(), futures.getFixingPeriodEndTime(),
futures.getFixingPeriodAccrualFactor());
final double futureConvexityFactor = MODEL.futuresConvexityFactor(multicurve.getHullWhiteParameters(), futures.getTradingLastTime(),
futures.getFixingPeriodStartTime(), futures.getFixingPeriodEndTime());
final double price = 1.0 - futureConvexityFactor * forward + (1 - futureConvexityFactor) / futures.getFixingPeriodAccrualFactor();
return price;
}
@Override
public Double visitSwapFuturesPriceDeliverableSecurity(final SwapFuturesPriceDeliverableSecurity futures, final HullWhiteOneFactorProviderInterface multicurve) {
ArgumentChecker.notNull(futures, "Future");
ArgumentChecker.notNull(multicurve, "Multi-curves with Hull-White");
final Currency ccy = futures.getCurrency();
ArgumentChecker.isTrue(multicurve.getHullWhiteCurrency().equals(ccy), "Futures currency incompatible with data");
final HullWhiteOneFactorPiecewiseConstantParameters parameters = multicurve.getHullWhiteParameters();
final MulticurveProviderInterface multicurves = multicurve.getMulticurveProvider();
final AnnuityPaymentFixed cfe = futures.getUnderlyingSwap().accept(CFEC, multicurves);
final int nbCf = cfe.getNumberOfPayments();
final double[] adjustments = new double[nbCf];
final double[] df = new double[nbCf];
for (int loopcf = 0; loopcf < nbCf; loopcf++) {
adjustments[loopcf] = MODEL.futuresConvexityFactor(parameters, futures.getTradingLastTime(), cfe.getNthPayment(loopcf).getPaymentTime(), futures.getDeliveryTime());
df[loopcf] = multicurves.getDiscountFactor(ccy, cfe.getNthPayment(loopcf).getPaymentTime());
}
double price = 1.0;
for (int loopcf = 0; loopcf < nbCf; loopcf++) {
price += (cfe.getNthPayment(loopcf).getAmount() * df[loopcf] * adjustments[loopcf]) / df[0];
}
return price;
}
}