コード例 #1
0
        /// <summary>
        /// Calculates the present value of the swaption product.
        /// <para>
        /// The result is expressed using the currency of the swapion.
        ///
        /// </para>
        /// </summary>
        /// <param name="swaption">  the product </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="hwProvider">  the Hull-White model parameter provider </param>
        /// <returns> the present value </returns>
        public virtual CurrencyAmount presentValue(ResolvedSwaption swaption, RatesProvider ratesProvider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider)
        {
            validate(swaption, ratesProvider, hwProvider);
            ResolvedSwap swap       = swaption.Underlying;
            LocalDate    expiryDate = swaption.ExpiryDate;

            if (expiryDate.isBefore(ratesProvider.ValuationDate))
            {     // Option has expired already
                return(CurrencyAmount.of(swap.Legs.get(0).Currency, 0d));
            }
            ResolvedSwapLeg cashFlowEquiv = CashFlowEquivalentCalculator.cashFlowEquivalentSwap(swap, ratesProvider);
            int             nPayments     = cashFlowEquiv.PaymentEvents.size();

            double[] alpha = new double[nPayments];
            double[] discountedCashFlow = new double[nPayments];
            for (int loopcf = 0; loopcf < nPayments; loopcf++)
            {
                NotionalExchange payment      = (NotionalExchange)cashFlowEquiv.PaymentEvents.get(loopcf);
                LocalDate        maturityDate = payment.PaymentDate;
                alpha[loopcf] = hwProvider.alpha(ratesProvider.ValuationDate, expiryDate, expiryDate, maturityDate);
                discountedCashFlow[loopcf] = paymentPricer.presentValueAmount(payment.Payment, ratesProvider);
            }
            double omega = (swap.getLegs(SwapLegType.FIXED).get(0).PayReceive.Pay ? -1d : 1d);
            double kappa = computeKappa(hwProvider, discountedCashFlow, alpha, omega);
            double pv    = 0.0;

            for (int loopcf = 0; loopcf < nPayments; loopcf++)
            {
                pv += discountedCashFlow[loopcf] * NORMAL.getCDF(omega * (kappa + alpha[loopcf]));
            }
            return(CurrencyAmount.of(cashFlowEquiv.Currency, pv * (swaption.LongShort.Long ? 1d : -1d)));
        }
コード例 #2
0
        //-------------------------------------------------------------------------
        public virtual void test_presentValue()
        {
            CurrencyAmount computedRec = PRICER.presentValue(SWAPTION_REC_LONG, RATE_PROVIDER, HW_PROVIDER);
            CurrencyAmount computedPay = PRICER.presentValue(SWAPTION_PAY_SHORT, RATE_PROVIDER, HW_PROVIDER);
            SwapPaymentEventPricer <SwapPaymentEvent> paymentEventPricer = SwapPaymentEventPricer.standard();
            ResolvedSwapLeg cashFlowEquiv = CashFlowEquivalentCalculator.cashFlowEquivalentSwap(RSWAP_REC, RATE_PROVIDER);
            LocalDate       expiryDate    = MATURITY.toLocalDate();
            int             nPayments     = cashFlowEquiv.PaymentEvents.size();

            double[] alpha = new double[nPayments];
            double[] discountedCashFlow = new double[nPayments];
            for (int loopcf = 0; loopcf < nPayments; loopcf++)
            {
                SwapPaymentEvent payment = cashFlowEquiv.PaymentEvents.get(loopcf);
                alpha[loopcf] = HW_PROVIDER.alpha(RATE_PROVIDER.ValuationDate, expiryDate, expiryDate, payment.PaymentDate);
                discountedCashFlow[loopcf] = paymentEventPricer.presentValue(payment, RATE_PROVIDER);
            }
            double omegaPay    = -1d;
            double kappa       = HW_PROVIDER.Model.kappa(DoubleArray.copyOf(discountedCashFlow), DoubleArray.copyOf(alpha));
            double expectedRec = 0.0;
            double expectedPay = 0.0;

            for (int loopcf = 0; loopcf < nPayments; loopcf++)
            {
                expectedRec += discountedCashFlow[loopcf] * NORMAL.getCDF((kappa + alpha[loopcf]));
                expectedPay += discountedCashFlow[loopcf] * NORMAL.getCDF(omegaPay * (kappa + alpha[loopcf]));
            }
            assertEquals(computedRec.Currency, EUR);
            assertEquals(computedRec.Amount, expectedRec, NOTIONAL * TOL);
            assertEquals(computedPay.Currency, EUR);
            assertEquals(computedPay.Amount, expectedPay, NOTIONAL * TOL);
        }
コード例 #3
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value sensitivity to piecewise constant volatility parameters of the Hull-White model.
        /// </summary>
        /// <param name="swaption">  the product </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="hwProvider">  the Hull-White model parameter provider </param>
        /// <returns> the present value Hull-White model parameter sensitivity of the swaption product </returns>
        public virtual DoubleArray presentValueSensitivityModelParamsHullWhite(ResolvedSwaption swaption, RatesProvider ratesProvider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider)
        {
            validate(swaption, ratesProvider, hwProvider);
            ResolvedSwap swap       = swaption.Underlying;
            LocalDate    expiryDate = swaption.ExpiryDate;

            if (expiryDate.isBefore(ratesProvider.ValuationDate))
            {     // Option has expired already
                return(DoubleArray.EMPTY);
            }
            ResolvedSwapLeg cashFlowEquiv = CashFlowEquivalentCalculator.cashFlowEquivalentSwap(swap, ratesProvider);
            int             nPayments     = cashFlowEquiv.PaymentEvents.size();

            double[]   alpha              = new double[nPayments];
            double[][] alphaAdjoint       = new double[nPayments][];
            double[]   discountedCashFlow = new double[nPayments];
            for (int loopcf = 0; loopcf < nPayments; loopcf++)
            {
                NotionalExchange payment    = (NotionalExchange)cashFlowEquiv.PaymentEvents.get(loopcf);
                ValueDerivatives valueDeriv = hwProvider.alphaAdjoint(ratesProvider.ValuationDate, expiryDate, expiryDate, payment.PaymentDate);
                alpha[loopcf]              = valueDeriv.Value;
                alphaAdjoint[loopcf]       = valueDeriv.Derivatives.toArray();
                discountedCashFlow[loopcf] = paymentPricer.presentValueAmount(payment.Payment, ratesProvider);
            }
            double omega   = (swap.getLegs(SwapLegType.FIXED).get(0).PayReceive.Pay ? -1d : 1d);
            double kappa   = computeKappa(hwProvider, discountedCashFlow, alpha, omega);
            int    nParams = alphaAdjoint[0].Length;

            if (Math.Abs(kappa) > 1d / SMALL)
            {     // decays exponentially
                return(DoubleArray.filled(nParams));
            }
            double[] pvSensi = new double[nParams];
            double   sign    = (swaption.LongShort.Long ? 1d : -1d);

            for (int i = 0; i < nParams; ++i)
            {
                for (int loopcf = 0; loopcf < nPayments; loopcf++)
                {
                    pvSensi[i] += sign * discountedCashFlow[loopcf] * NORMAL.getPDF(omega * (kappa + alpha[loopcf])) * omega * alphaAdjoint[loopcf][i];
                }
            }
            return(DoubleArray.ofUnsafe(pvSensi));
        }
コード例 #4
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value sensitivity of the swaption product.
        /// <para>
        /// The present value sensitivity of the product is the sensitivity of the present value to
        /// the underlying curves.
        ///
        /// </para>
        /// </summary>
        /// <param name="swaption">  the product </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="hwProvider">  the Hull-White model parameter provider </param>
        /// <returns> the point sensitivity to the rate curves </returns>
        public virtual PointSensitivityBuilder presentValueSensitivityRates(ResolvedSwaption swaption, RatesProvider ratesProvider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider)
        {
            validate(swaption, ratesProvider, hwProvider);
            ResolvedSwap swap       = swaption.Underlying;
            LocalDate    expiryDate = swaption.ExpiryDate;

            if (expiryDate.isBefore(ratesProvider.ValuationDate))
            {     // Option has expired already
                return(PointSensitivityBuilder.none());
            }
            ImmutableMap <Payment, PointSensitivityBuilder> cashFlowEquivSensi = CashFlowEquivalentCalculator.cashFlowEquivalentAndSensitivitySwap(swap, ratesProvider);
            ImmutableList <Payment> list = cashFlowEquivSensi.Keys.asList();
            ImmutableList <PointSensitivityBuilder> listSensi = cashFlowEquivSensi.values().asList();
            int nPayments = list.size();

            double[] alpha = new double[nPayments];
            double[] discountedCashFlow = new double[nPayments];
            for (int loopcf = 0; loopcf < nPayments; loopcf++)
            {
                Payment payment = list.get(loopcf);
                alpha[loopcf] = hwProvider.alpha(ratesProvider.ValuationDate, expiryDate, expiryDate, payment.Date);
                discountedCashFlow[loopcf] = paymentPricer.presentValueAmount(payment, ratesProvider);
            }
            double omega = (swap.getLegs(SwapLegType.FIXED).get(0).PayReceive.Pay ? -1d : 1d);
            double kappa = computeKappa(hwProvider, discountedCashFlow, alpha, omega);
            PointSensitivityBuilder point = PointSensitivityBuilder.none();

            for (int loopcf = 0; loopcf < nPayments; loopcf++)
            {
                Payment payment = list.get(loopcf);
                double  cdf     = NORMAL.getCDF(omega * (kappa + alpha[loopcf]));
                point = point.combinedWith(paymentPricer.presentValueSensitivity(payment, ratesProvider).multipliedBy(cdf));
                if (!listSensi.get(loopcf).Equals(PointSensitivityBuilder.none()))
                {
                    point = point.combinedWith(listSensi.get(loopcf).multipliedBy(cdf * ratesProvider.discountFactor(payment.Currency, payment.Date)));
                }
            }
            return(swaption.LongShort.Long ? point : point.multipliedBy(-1d));
        }