/** * Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.interestrate; import org.threeten.bp.ZonedDateTime; import com.opengamma.analytics.financial.instrument.index.IborIndex; import com.opengamma.analytics.financial.model.interestrate.curve.YieldAndDiscountCurve; import com.opengamma.analytics.financial.provider.description.interestrate.MulticurveProviderInterface; import com.opengamma.analytics.financial.schedule.ScheduleCalculator; import com.opengamma.analytics.util.time.TimeCalculator; import com.opengamma.financial.convention.calendar.Calendar; import com.opengamma.financial.convention.daycount.DayCount; import com.opengamma.util.ArgumentChecker; /** * Utils function related to YieldAndDiscount curves and MulticurveProvider. */ public class YieldAndDiscountCurveUtils { /** * Computes the forward rate for a given index in a given curve * @param curve The curve. * @param curveDate The curve date. * @param fixingDate The forward rate fixing date. * @param index The Ibor index. * @param cal Calendar used to compute the fixing period of the index. * @return The forward. */ public static double forwardRateFromCurve(final YieldAndDiscountCurve curve, final ZonedDateTime curveDate, final ZonedDateTime fixingDate, final IborIndex index, final Calendar cal) { ArgumentChecker.notNull(curve, "curve"); ArgumentChecker.notNull(curveDate, "curveDate"); ArgumentChecker.notNull(fixingDate, "fixingDate"); ArgumentChecker.notNull(index, "iborIndex"); ArgumentChecker.notNull(cal, "calendar"); final ZonedDateTime fixingPeriodStartDate = ScheduleCalculator.getAdjustedDate(fixingDate, index.getSpotLag(), cal); final double fixingPeriodStartTime = TimeCalculator.getTimeBetween(curveDate, fixingPeriodStartDate); final ZonedDateTime fixingPeriodEndDate = ScheduleCalculator.getAdjustedDate(fixingDate, index, cal); final double fixingPeriodEndTime = TimeCalculator.getTimeBetween(curveDate, fixingPeriodEndDate); final double accrualFixing = index.getDayCount().getDayCountFraction(fixingPeriodStartDate, fixingPeriodEndDate); final double dfStart = curve.getDiscountFactor(fixingPeriodStartTime); final double dfEnd = curve.getDiscountFactor(fixingPeriodEndTime); final double forwardRate = (dfStart / dfEnd - 1.0d) / accrualFixing; return forwardRate; } /** * Computes the forward rate for a given index in a multicurve provider. The curve used to compute the forward is the curve associated to the index. * @param multicurve The curve provider. Should contain the curve related to the index for which the forward rate is requested. * @param curveDate The curve date. * @param fixingDate The forward rate fixing date. * @param index The Ibor index. * @param cal Calendar used to compute the fixing period of the index. * @return The forward. */ public static double forwardRateFromProvider(final MulticurveProviderInterface multicurve, final ZonedDateTime curveDate, final ZonedDateTime fixingDate, final IborIndex index, final Calendar cal) { ArgumentChecker.notNull(multicurve, "multicurve provider"); ArgumentChecker.notNull(curveDate, "curveDate"); ArgumentChecker.notNull(fixingDate, "fixingDate"); ArgumentChecker.notNull(index, "iborIndex"); ArgumentChecker.notNull(cal, "calendar"); final ZonedDateTime fixingPeriodStartDate = ScheduleCalculator.getAdjustedDate(fixingDate, index.getSpotLag(), cal); final double fixingPeriodStartTime = TimeCalculator.getTimeBetween(curveDate, fixingPeriodStartDate); final ZonedDateTime fixingPeriodEndDate = ScheduleCalculator.getAdjustedDate(fixingDate, index, cal); final double fixingPeriodEndTime = TimeCalculator.getTimeBetween(curveDate, fixingPeriodEndDate); final double accrualFixing = index.getDayCount().getDayCountFraction(fixingPeriodStartDate, fixingPeriodEndDate); final double forwardRate = multicurve.getSimplyCompoundForwardRate(index, fixingPeriodStartTime, fixingPeriodEndTime, accrualFixing); return forwardRate; } /** * Compute the zero coupon for a given payment date. * @param curve The curve. * @param curveDate The curve date. * @param payDate The payment date. * @param dc The day count convention. * @param paymentPerYear Number of payment per year for a period payment. If paymentPerYear<=0, a continuously compounded rate is computed. * @return The rate */ public static double zeroCouponRate(final YieldAndDiscountCurve curve, final ZonedDateTime curveDate, final ZonedDateTime payDate, final DayCount dc, final int paymentPerYear) { ArgumentChecker.notNull(curve, "curve"); ArgumentChecker.notNull(curveDate, "curveDate"); ArgumentChecker.notNull(payDate, "payDate"); ArgumentChecker.notNull(dc, "dayCount"); final double timeCurve = TimeCalculator.getTimeBetween(curveDate, payDate); final double df = curve.getDiscountFactor(timeCurve); final double timeDc = dc.getDayCountFraction(curveDate, payDate); if (paymentPerYear > 0) { final double rate = paymentPerYear * (Math.pow(df, -1.0 / (paymentPerYear * timeDc)) - 1.0); return rate; } final double rate = -Math.log(df) / timeDc; return rate; } /** * Compute the zero coupon for a given payment date. * @param curve The curve. * @param curveDate The curve date. * @param payDate The payment date. * @return The rate */ public static double discountFactor(final YieldAndDiscountCurve curve, final ZonedDateTime curveDate, final ZonedDateTime payDate) { ArgumentChecker.notNull(curve, "curve"); ArgumentChecker.notNull(curveDate, "curveDate"); ArgumentChecker.notNull(payDate, "payDate"); final double timeCurve = TimeCalculator.getTimeBetween(curveDate, payDate); final double df = curve.getDiscountFactor(timeCurve); return df; } }