/** * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.interestrate.payments.method; import org.apache.commons.lang.Validate; import com.opengamma.analytics.financial.interestrate.InstrumentDerivative; import com.opengamma.analytics.financial.interestrate.YieldCurveBundle; import com.opengamma.analytics.financial.interestrate.method.PricingMethod; import com.opengamma.analytics.financial.interestrate.payments.derivative.CapFloorIbor; import com.opengamma.analytics.financial.model.interestrate.definition.LiborMarketModelDisplacedDiffusionDataBundle; import com.opengamma.analytics.financial.model.option.pricing.analytic.formula.BlackFunctionData; import com.opengamma.analytics.financial.model.option.pricing.analytic.formula.BlackPriceFunction; import com.opengamma.analytics.financial.model.option.pricing.analytic.formula.EuropeanVanillaOption; import com.opengamma.analytics.math.function.Function1D; import com.opengamma.util.money.CurrencyAmount; /** * Class used to compute the price a Ibor cap/floor with LMM. * No convexity adjustment is done for payment at non-standard dates. * @deprecated Use {@link com.opengamma.analytics.financial.interestrate.payments.provider.CapFloorIborLMMDDMethod} */ @Deprecated public class CapFloorIborLMMDDMethod implements PricingMethod { /** * The Black function used in the pricing. */ private static final BlackPriceFunction BLACK_FUNCTION = new BlackPriceFunction(); /** * Computes the present value of the cap/floor in the LMM. It is computed using a Black formula (on the shifted rate). The volatility is the LMM volatilities for the * relevant period multiplied by the time dependent factor square mean. * The method is used mainly for calibration purposes. * @param cap The cap. Should have the same underlying index as the model (same payment frequency). * @param lmmData The Model parameters. * @return The present value. */ public CurrencyAmount presentValue(final CapFloorIbor cap, final LiborMarketModelDisplacedDiffusionDataBundle lmmData) { final int index = lmmData.getLmmParameter().getTimeIndex(cap.getFixingPeriodStartTime()); double volatility = 0; for (int loopfact = 0; loopfact < lmmData.getLmmParameter().getNbFactor(); loopfact++) { volatility += lmmData.getLmmParameter().getVolatility()[index][loopfact] * lmmData.getLmmParameter().getVolatility()[index][loopfact]; } volatility = Math.sqrt(volatility); final double timeDependentFactor = Math.sqrt((Math.exp(2 * lmmData.getLmmParameter().getMeanReversion() * cap.getFixingTime()) - 1.0) / (2.0 * lmmData.getLmmParameter().getMeanReversion())); volatility *= timeDependentFactor; final double displacement = lmmData.getLmmParameter().getDisplacement()[index]; final double beta = lmmData.getCurve(cap.getForwardCurveName()).getDiscountFactor(cap.getFixingPeriodStartTime()) / lmmData.getCurve(cap.getForwardCurveName()).getDiscountFactor(cap.getFixingPeriodEndTime()) * lmmData.getCurve(cap.getFundingCurveName()).getDiscountFactor(cap.getFixingPeriodEndTime()) / lmmData.getCurve(cap.getFundingCurveName()).getDiscountFactor(cap.getFixingPeriodStartTime()); final double strikeAdjusted = (cap.getStrike() - (beta - 1) / cap.getFixingAccrualFactor()) / beta; final EuropeanVanillaOption option = new EuropeanVanillaOption(strikeAdjusted + displacement, 1.0, cap.isCap()); // Time is in timeDependentFactor final double forwardDsc = (lmmData.getCurve(cap.getFundingCurveName()).getDiscountFactor(cap.getFixingPeriodStartTime()) / lmmData.getCurve(cap.getFundingCurveName()).getDiscountFactor(cap.getFixingPeriodEndTime()) - 1.0) / cap.getFixingAccrualFactor(); final double df = lmmData.getCurve(cap.getFundingCurveName()).getDiscountFactor(cap.getPaymentTime()); final BlackFunctionData dataBlack = new BlackFunctionData(forwardDsc + displacement, df, volatility); final Function1D<BlackFunctionData, Double> func = BLACK_FUNCTION.getPriceFunction(option); final double price = beta * func.evaluate(dataBlack) * cap.getNotional() * cap.getPaymentYearFraction(); return CurrencyAmount.of(cap.getCurrency(), price); } @Override public CurrencyAmount presentValue(final InstrumentDerivative instrument, final YieldCurveBundle curves) { Validate.isTrue(instrument instanceof CapFloorIbor, "Ibor Cap/floor"); Validate.isTrue(curves instanceof LiborMarketModelDisplacedDiffusionDataBundle, "Bundle should contain LMM data"); return presentValue((CapFloorIbor) instrument, (LiborMarketModelDisplacedDiffusionDataBundle) curves); } }