示例#1
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value of the Ibor caplet/floorlet period.
        /// <para>
        /// The result is expressed using the currency of the period.
        ///
        /// </para>
        /// </summary>
        /// <param name="period">  the Ibor caplet/floorlet period </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the volatilities </param>
        /// <returns> the present value </returns>
        public virtual CurrencyAmount presentValue(IborCapletFloorletPeriod period, RatesProvider ratesProvider, IborCapletFloorletVolatilities volatilities)
        {
            validate(volatilities);
            Currency currency = period.Currency;

            if (ratesProvider.ValuationDate.isAfter(period.PaymentDate))
            {
                return(CurrencyAmount.of(currency, 0d));
            }
            double  expiry    = volatilities.relativeTime(period.FixingDateTime);
            double  df        = ratesProvider.discountFactor(currency, period.PaymentDate);
            PutCall putCall   = period.PutCall;
            double  strike    = period.Strike;
            double  indexRate = ratesProvider.iborIndexRates(period.Index).rate(period.IborRate.Observation);

            if (expiry < 0d)
            {     // Option has expired already
                double sign   = putCall.Call ? 1d : -1d;
                double payoff = Math.Max(sign * (indexRate - strike), 0d);
                return(CurrencyAmount.of(currency, df * payoff * period.YearFraction * period.Notional));
            }
            double volatility = volatilities.volatility(expiry, strike, indexRate);
            double price      = df * period.YearFraction * volatilities.price(expiry, putCall, strike, indexRate, volatility);

            return(CurrencyAmount.of(currency, price * period.Notional));
        }
示例#2
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value rates sensitivity of the Ibor caplet/floorlet.
        /// <para>
        /// The present value rates sensitivity of the caplet/floorlet is the sensitivity
        /// of the present value to the underlying curves.
        ///
        /// </para>
        /// </summary>
        /// <param name="period">  the Ibor caplet/floorlet period </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the volatilities </param>
        /// <returns> the present value curve sensitivity </returns>
        public virtual PointSensitivityBuilder presentValueSensitivityRates(IborCapletFloorletPeriod period, RatesProvider ratesProvider, IborCapletFloorletVolatilities volatilities)
        {
            validate(volatilities);
            Currency currency = period.Currency;

            if (ratesProvider.ValuationDate.isAfter(period.PaymentDate))
            {
                return(PointSensitivityBuilder.none());
            }
            double  expiry    = volatilities.relativeTime(period.FixingDateTime);
            PutCall putCall   = period.PutCall;
            double  strike    = period.Strike;
            double  indexRate = ratesProvider.iborIndexRates(period.Index).rate(period.IborRate.Observation);
            PointSensitivityBuilder dfSensi = ratesProvider.discountFactors(currency).zeroRatePointSensitivity(period.PaymentDate);

            if (expiry < 0d)
            {     // Option has expired already
                double sign   = putCall.Call ? 1d : -1d;
                double payoff = Math.Max(sign * (indexRate - strike), 0d);
                return(dfSensi.multipliedBy(payoff * period.YearFraction * period.Notional));
            }
            PointSensitivityBuilder indexRateSensiSensi = ratesProvider.iborIndexRates(period.Index).ratePointSensitivity(period.IborRate.Observation);
            double volatility = volatilities.volatility(expiry, strike, indexRate);
            double df         = ratesProvider.discountFactor(currency, period.PaymentDate);
            double factor     = period.Notional * period.YearFraction;
            double fwdPv      = factor * volatilities.price(expiry, putCall, strike, indexRate, volatility);
            double fwdDelta   = factor * volatilities.priceDelta(expiry, putCall, strike, indexRate, volatility);

            return(dfSensi.multipliedBy(fwdPv).combinedWith(indexRateSensiSensi.multipliedBy(fwdDelta * df)));
        }
示例#3
0
 public virtual void test_builder_fail()
 {
     // rate observation missing
     assertThrowsIllegalArg(() => IborCapletFloorletPeriod.builder().notional(NOTIONAL).caplet(STRIKE).build());
     // cap and floor missing
     assertThrowsIllegalArg(() => IborCapletFloorletPeriod.builder().notional(NOTIONAL).iborRate(RATE_COMP).build());
     // cap and floor present
     assertThrowsIllegalArg(() => IborCapletFloorletPeriod.builder().notional(NOTIONAL).caplet(STRIKE).floorlet(STRIKE).iborRate(RATE_COMP).build());
 }
示例#4
0
        public virtual void test_builder_fail()
        {
            // two currencies
            IborCapletFloorletPeriod periodGbp = IborCapletFloorletPeriod.builder().caplet(STRIKE).notional(NOTIONAL).currency(GBP).startDate(LocalDate.of(2011, 6, 17)).endDate(LocalDate.of(2011, 9, 19)).unadjustedStartDate(LocalDate.of(2011, 6, 17)).unadjustedEndDate(LocalDate.of(2011, 9, 17)).paymentDate(LocalDate.of(2011, 9, 21)).iborRate(IborRateComputation.of(EUR_EURIBOR_3M, LocalDate.of(2011, 9, 15), REF_DATA)).yearFraction(0.2611).build();

            assertThrowsIllegalArg(() => ResolvedIborCapFloorLeg.builder().capletFloorletPeriods(PERIOD_1, periodGbp).payReceive(RECEIVE).build());
            // two indices
            IborCapletFloorletPeriod periodLibor = IborCapletFloorletPeriod.builder().caplet(STRIKE).notional(NOTIONAL).currency(EUR).startDate(LocalDate.of(2011, 6, 17)).endDate(LocalDate.of(2011, 9, 19)).unadjustedStartDate(LocalDate.of(2011, 6, 17)).unadjustedEndDate(LocalDate.of(2011, 9, 17)).paymentDate(LocalDate.of(2011, 9, 21)).iborRate(IborRateComputation.of(GBP_LIBOR_3M, LocalDate.of(2011, 9, 15), REF_DATA)).yearFraction(0.2611).build();

            assertThrowsIllegalArg(() => ResolvedIborCapFloorLeg.builder().capletFloorletPeriods(PERIOD_1, periodLibor).payReceive(RECEIVE).build());
        }
示例#5
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Computes the implied volatility of the Ibor caplet/floorlet.
        /// </summary>
        /// <param name="period">  the Ibor caplet/floorlet period </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the volatilities </param>
        /// <returns> the implied volatility </returns>
        public virtual double impliedVolatility(IborCapletFloorletPeriod period, RatesProvider ratesProvider, IborCapletFloorletVolatilities volatilities)
        {
            validate(volatilities);
            double expiry = volatilities.relativeTime(period.FixingDateTime);

            ArgChecker.isTrue(expiry >= 0d, "Option must be before expiry to compute an implied volatility");
            double forward = ratesProvider.iborIndexRates(period.Index).rate(period.IborRate.Observation);
            double strike  = period.Strike;

            return(volatilities.volatility(expiry, strike, forward));
        }
        public virtual void test_resolve_floor()
        {
            IborCapFloorLeg @base = IborCapFloorLeg.builder().calculation(RATE_CALCULATION).floorSchedule(FLOOR).currency(GBP).notional(NOTIONAL).paymentDateOffset(PAYMENT_OFFSET).paymentSchedule(SCHEDULE).payReceive(PAY).build();

            LocalDate[] unadjustedDates        = new LocalDate[] { START, START.plusMonths(3), START.plusMonths(6), START.plusMonths(9), START.plusMonths(12) };
            IborCapletFloorletPeriod[] periods = new IborCapletFloorletPeriod[4];
            for (int i = 0; i < 4; ++i)
            {
                LocalDate start        = BUSS_ADJ.adjust(unadjustedDates[i], REF_DATA);
                LocalDate end          = BUSS_ADJ.adjust(unadjustedDates[i + 1], REF_DATA);
                double    yearFraction = EUR_EURIBOR_3M.DayCount.relativeYearFraction(start, end);
                LocalDate fixingDate   = RATE_CALCULATION.FixingDateOffset.adjust(start, REF_DATA);
                periods[i] = IborCapletFloorletPeriod.builder().floorlet(STRIKES[i]).currency(GBP).startDate(start).endDate(end).unadjustedStartDate(unadjustedDates[i]).unadjustedEndDate(unadjustedDates[i + 1]).paymentDate(PAYMENT_OFFSET.adjust(end, REF_DATA)).notional(-NOTIONALS[i]).iborRate(IborRateComputation.of(EUR_EURIBOR_3M, fixingDate, REF_DATA)).yearFraction(yearFraction).build();
            }
            ResolvedIborCapFloorLeg expected = ResolvedIborCapFloorLeg.builder().capletFloorletPeriods(periods).payReceive(PAY).build();
            ResolvedIborCapFloorLeg computed = @base.resolve(REF_DATA);

            assertEquals(computed, expected);
        }
        public virtual void test_resolve_cap()
        {
            IborRateCalculation rateCalc = IborRateCalculation.builder().index(EUR_EURIBOR_3M).fixingRelativeTo(FixingRelativeTo.PERIOD_END).fixingDateOffset(EUR_EURIBOR_3M.FixingDateOffset).build();
            IborCapFloorLeg     @base    = IborCapFloorLeg.builder().calculation(rateCalc).capSchedule(CAP).notional(NOTIONAL).paymentDateOffset(PAYMENT_OFFSET).paymentSchedule(SCHEDULE).payReceive(RECEIVE).build();

            LocalDate[] unadjustedDates        = new LocalDate[] { START, START.plusMonths(3), START.plusMonths(6), START.plusMonths(9), START.plusMonths(12) };
            IborCapletFloorletPeriod[] periods = new IborCapletFloorletPeriod[4];
            for (int i = 0; i < 4; ++i)
            {
                LocalDate start        = BUSS_ADJ.adjust(unadjustedDates[i], REF_DATA);
                LocalDate end          = BUSS_ADJ.adjust(unadjustedDates[i + 1], REF_DATA);
                double    yearFraction = EUR_EURIBOR_3M.DayCount.relativeYearFraction(start, end);
                periods[i] = IborCapletFloorletPeriod.builder().caplet(CAP.InitialValue).currency(EUR).startDate(start).endDate(end).unadjustedStartDate(unadjustedDates[i]).unadjustedEndDate(unadjustedDates[i + 1]).paymentDate(PAYMENT_OFFSET.adjust(end, REF_DATA)).notional(NOTIONALS[i]).iborRate(IborRateComputation.of(EUR_EURIBOR_3M, rateCalc.FixingDateOffset.adjust(end, REF_DATA), REF_DATA)).yearFraction(yearFraction).build();
            }
            ResolvedIborCapFloorLeg expected = ResolvedIborCapFloorLeg.builder().capletFloorletPeriods(periods).payReceive(RECEIVE).build();
            ResolvedIborCapFloorLeg computed = @base.resolve(REF_DATA);

            assertEquals(computed, expected);
        }
示例#8
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value theta of the Ibor caplet/floorlet period.
        /// <para>
        /// The present value theta is given by the minus of the present value sensitivity to the {@code timeToExpiry}
        /// parameter of the model.
        ///
        /// </para>
        /// </summary>
        /// <param name="period">  the Ibor caplet/floorlet period </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the volatilities </param>
        /// <returns> the present value theta </returns>
        public virtual CurrencyAmount presentValueTheta(IborCapletFloorletPeriod period, RatesProvider ratesProvider, IborCapletFloorletVolatilities volatilities)
        {
            validate(volatilities);
            double   expiry   = volatilities.relativeTime(period.FixingDateTime);
            Currency currency = period.Currency;

            if (expiry < 0d)
            {     // Option has expired already
                return(CurrencyAmount.of(currency, 0d));
            }
            double  forward    = ratesProvider.iborIndexRates(period.Index).rate(period.IborRate.Observation);
            double  strike     = period.Strike;
            double  volatility = volatilities.volatility(expiry, strike, forward);
            PutCall putCall    = period.PutCall;
            double  df         = ratesProvider.discountFactor(currency, period.PaymentDate);
            double  priceTheta = df * period.YearFraction * volatilities.priceTheta(expiry, putCall, strike, forward, volatility);

            return(CurrencyAmount.of(currency, priceTheta * period.Notional));
        }
示例#9
0
        public virtual void test_builder_full()
        {
            IborCapletFloorletPeriod test = IborCapletFloorletPeriod.builder().notional(NOTIONAL).startDate(START).endDate(END).unadjustedStartDate(START_UNADJ).unadjustedEndDate(END_UNADJ).paymentDate(PAYMENT).yearFraction(YEAR_FRACTION).currency(GBP).floorlet(STRIKE).iborRate(RATE_COMP).build();

            assertEquals(test.Floorlet.Value, STRIKE);
            assertEquals(test.Caplet.HasValue, false);
            assertEquals(test.Strike, STRIKE);
            assertEquals(test.StartDate, START);
            assertEquals(test.EndDate, END);
            assertEquals(test.UnadjustedStartDate, START_UNADJ);
            assertEquals(test.UnadjustedEndDate, END_UNADJ);
            assertEquals(test.PaymentDate, PAYMENT);
            assertEquals(test.Currency, GBP);
            assertEquals(test.Notional, NOTIONAL);
            assertEquals(test.IborRate, RATE_COMP);
            assertEquals(test.Index, EUR_EURIBOR_3M);
            assertEquals(test.FixingDateTime, FIXING_TIME_ZONE);
            assertEquals(test.PutCall, PutCall.PUT);
            assertEquals(test.YearFraction, YEAR_FRACTION);
        }
        //-------------------------------------------------------------------------
        public ResolvedIborCapFloorLeg resolve(ReferenceData refData)
        {
            Schedule     adjustedSchedule = paymentSchedule.createSchedule(refData);
            DoubleArray  cap                 = CapSchedule.Present ? capSchedule.resolveValues(adjustedSchedule) : null;
            DoubleArray  floor               = FloorSchedule.Present ? floorSchedule.resolveValues(adjustedSchedule) : null;
            DoubleArray  notionals           = notional.resolveValues(adjustedSchedule);
            DateAdjuster fixingDateAdjuster  = calculation.FixingDateOffset.resolve(refData);
            DateAdjuster paymentDateAdjuster = paymentDateOffset.resolve(refData);

            System.Func <LocalDate, IborIndexObservation>    obsFn        = calculation.Index.resolve(refData);
            ImmutableList.Builder <IborCapletFloorletPeriod> periodsBuild = ImmutableList.builder();
            for (int i = 0; i < adjustedSchedule.size(); i++)
            {
                SchedulePeriod period         = adjustedSchedule.getPeriod(i);
                LocalDate      paymentDate    = paymentDateAdjuster.adjust(period.EndDate);
                LocalDate      fixingDate     = fixingDateAdjuster.adjust((calculation.FixingRelativeTo.Equals(FixingRelativeTo.PERIOD_START)) ? period.StartDate : period.EndDate);
                double         signedNotional = payReceive.normalize(notionals.get(i));
                periodsBuild.add(IborCapletFloorletPeriod.builder().unadjustedStartDate(period.UnadjustedStartDate).unadjustedEndDate(period.UnadjustedEndDate).startDate(period.StartDate).endDate(period.EndDate).iborRate(IborRateComputation.of(obsFn(fixingDate))).paymentDate(paymentDate).notional(signedNotional).currency(currency).yearFraction(period.yearFraction(calculation.DayCount, adjustedSchedule)).caplet(cap != null ? cap.get(i) : null).floorlet(floor != null ? floor.get(i) : null).build());
            }
            return(ResolvedIborCapFloorLeg.builder().capletFloorletPeriods(periodsBuild.build()).payReceive(payReceive).build());
        }
示例#11
0
 internal static IborCapletFloorletPeriod sut2()
 {
     return(IborCapletFloorletPeriod.builder().notional(-NOTIONAL).startDate(START.plusDays(1)).endDate(END.plusDays(1)).floorlet(STRIKE).iborRate(IborRateComputation.of(USD_LIBOR_6M, LocalDate.of(2013, 2, 15), REF_DATA)).build());
 }
示例#12
0
 //-------------------------------------------------------------------------
 internal static IborCapletFloorletPeriod sut()
 {
     return(IborCapletFloorletPeriod.builder().notional(NOTIONAL).startDate(START).endDate(END).caplet(STRIKE).iborRate(RATE_COMP).build());
 }
示例#13
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value sensitivity of the Ibor caplet/floorlet to the rate curves.
        /// <para>
        /// The present value sensitivity is computed in a "sticky model parameter" style, i.e. the sensitivity to the
        /// curve nodes with the SABR model parameters unchanged. This sensitivity does not include a potential
        /// re-calibration of the model parameters to the raw market data.
        ///
        /// </para>
        /// </summary>
        /// <param name="period">  the Ibor caplet/floorlet period </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the volatilities </param>
        /// <returns> the point sensitivity to the rate curves </returns>
        public virtual PointSensitivityBuilder presentValueSensitivityRatesStickyModel(IborCapletFloorletPeriod period, RatesProvider ratesProvider, SabrIborCapletFloorletVolatilities volatilities)
        {
            Currency currency = period.Currency;

            if (ratesProvider.ValuationDate.isAfter(period.PaymentDate))
            {
                return(PointSensitivityBuilder.none());
            }
            double  expiry    = volatilities.relativeTime(period.FixingDateTime);
            PutCall putCall   = period.PutCall;
            double  strike    = period.Strike;
            double  indexRate = ratesProvider.iborIndexRates(period.Index).rate(period.IborRate.Observation);
            PointSensitivityBuilder dfSensi = ratesProvider.discountFactors(currency).zeroRatePointSensitivity(period.PaymentDate);
            double factor = period.Notional * period.YearFraction;

            if (expiry < 0d)
            {     // option expired already, but not yet paid
                double sign   = putCall.Call ? 1d : -1d;
                double payoff = Math.Max(sign * (indexRate - strike), 0d);
                return(dfSensi.multipliedBy(payoff * factor));
            }
            ValueDerivatives        volatilityAdj       = volatilities.volatilityAdjoint(expiry, strike, indexRate);
            PointSensitivityBuilder indexRateSensiSensi = ratesProvider.iborIndexRates(period.Index).ratePointSensitivity(period.IborRate.Observation);
            double df       = ratesProvider.discountFactor(currency, period.PaymentDate);
            double fwdPv    = factor * volatilities.price(expiry, putCall, strike, indexRate, volatilityAdj.Value);
            double fwdDelta = factor * volatilities.priceDelta(expiry, putCall, strike, indexRate, volatilityAdj.Value);
            double fwdVega  = factor * volatilities.priceVega(expiry, putCall, strike, indexRate, volatilityAdj.Value);

            return(dfSensi.multipliedBy(fwdPv).combinedWith(indexRateSensiSensi.multipliedBy(fwdDelta * df + fwdVega * volatilityAdj.getDerivative(0) * df)));
        }
示例#14
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value sensitivity to the SABR model parameters of the Ibor caplet/floorlet.
        /// <para>
        /// The sensitivity of the present value to the SABR model parameters, alpha, beta, rho and nu.
        ///
        /// </para>
        /// </summary>
        /// <param name="period">  the Ibor caplet/floorlet period </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the volatilities </param>
        /// <returns> the point sensitivity to the SABR model parameters </returns>
        public virtual PointSensitivityBuilder presentValueSensitivityModelParamsSabr(IborCapletFloorletPeriod period, RatesProvider ratesProvider, SabrIborCapletFloorletVolatilities volatilities)
        {
            double expiry = volatilities.relativeTime(period.FixingDateTime);

            if (expiry < 0d)
            {     // option expired already
                return(PointSensitivityBuilder.none());
            }
            Currency         currency               = period.Currency;
            PutCall          putCall                = period.PutCall;
            double           strike                 = period.Strike;
            double           indexRate              = ratesProvider.iborIndexRates(period.Index).rate(period.IborRate.Observation);
            double           factor                 = period.Notional * period.YearFraction;
            ValueDerivatives volatilityAdj          = volatilities.volatilityAdjoint(expiry, strike, indexRate);
            DoubleArray      derivative             = volatilityAdj.Derivatives;
            double           df                     = ratesProvider.discountFactor(currency, period.PaymentDate);
            double           vega                   = df * factor * volatilities.priceVega(expiry, putCall, strike, indexRate, volatilityAdj.Value);
            IborCapletFloorletVolatilitiesName name = volatilities.Name;

            return(PointSensitivityBuilder.of(IborCapletFloorletSabrSensitivity.of(name, expiry, ALPHA, currency, vega * derivative.get(2)), IborCapletFloorletSabrSensitivity.of(name, expiry, BETA, currency, vega * derivative.get(3)), IborCapletFloorletSabrSensitivity.of(name, expiry, RHO, currency, vega * derivative.get(4)), IborCapletFloorletSabrSensitivity.of(name, expiry, NU, currency, vega * derivative.get(5))));
        }
示例#15
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value volatility sensitivity of the Ibor caplet/floorlet.
        /// <para>
        /// The present value volatility sensitivity of the caplet/floorlet is the sensitivity
        /// of the present value to the implied volatility.
        /// </para>
        /// <para>
        /// The sensitivity to the implied volatility is also called vega.
        ///
        /// </para>
        /// </summary>
        /// <param name="period">  the Ibor caplet/floorlet period </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the volatilities </param>
        /// <returns> the point sensitivity to the volatility </returns>
        public virtual PointSensitivityBuilder presentValueSensitivityModelParamsVolatility(IborCapletFloorletPeriod period, RatesProvider ratesProvider, IborCapletFloorletVolatilities volatilities)
        {
            validate(volatilities);
            double   expiry   = volatilities.relativeTime(period.FixingDateTime);
            double   strike   = period.Strike;
            Currency currency = period.Currency;

            if (expiry <= 0d)
            {     // Option has expired already or at expiry
                return(PointSensitivityBuilder.none());
            }
            double  forward    = ratesProvider.iborIndexRates(period.Index).rate(period.IborRate.Observation);
            double  volatility = volatilities.volatility(expiry, strike, forward);
            PutCall putCall    = period.PutCall;
            double  df         = ratesProvider.discountFactor(currency, period.PaymentDate);
            double  vega       = df * period.YearFraction * volatilities.priceVega(expiry, putCall, strike, forward, volatility);

            return(IborCapletFloorletSensitivity.of(volatilities.Name, expiry, strike, forward, currency, vega * period.Notional));
        }