Example #1
0
        //-------------------------------------------------------------------------
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @ImmutableValidator private void validate()
        private void validate()
        {
            ArgChecker.inOrderOrEqual(deliveryDate, underlyingSwap.StartDate, "deliveryDate", "startDate");
            ArgChecker.isFalse(underlyingSwap.CrossCurrency, "underlying swap must not be cross currency");
            foreach (ResolvedSwapLeg swapLeg in underlyingSwap.Legs)
            {
                if (swapLeg.Type.Equals(SwapLegType.FIXED))
                {
                    ArgChecker.isTrue(swapLeg.PayReceive.Receive, "underlying must be receiver swap");
                }
                foreach (SwapPaymentEvent @event in swapLeg.PaymentEvents)
                {
                    ArgChecker.isTrue(@event is NotionalExchange, "PaymentEvent must be NotionalExchange");
                    NotionalExchange notioanlEvent = (NotionalExchange)@event;
                    ArgChecker.isTrue(Math.Abs(notioanlEvent.PaymentAmount.Amount) == 1d, "notional of underlying swap must be unity");
                }
                foreach (SwapPaymentPeriod period in swapLeg.PaymentPeriods)
                {
                    ArgChecker.isTrue(period is NotionalPaymentPeriod, "PaymentPeriod must be NotionalPaymentPeriod");
                    NotionalPaymentPeriod notioanlPeriod = (NotionalPaymentPeriod)period;
                    ArgChecker.isTrue(Math.Abs(notioanlPeriod.NotionalAmount.Amount) == 1d, "notional of underlying swap must be unity");
                }
            }
            ArgChecker.inOrderOrEqual(lastTradeDate, deliveryDate, "lastTradeDate", "deliveryDate");
        }
Example #2
0
        /// <summary>
        /// Computes cash flow equivalent of Ibor leg.
        /// <para>
        /// The return type is {@code ResolvedSwapLeg} in which individual payments are
        /// represented in terms of {@code NotionalExchange}.
        ///
        /// </para>
        /// </summary>
        /// <param name="iborLeg">  the Ibor leg </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <returns> the cash flow equivalent </returns>
        public static ResolvedSwapLeg cashFlowEquivalentIborLeg(ResolvedSwapLeg iborLeg, RatesProvider ratesProvider)
        {
            ArgChecker.isTrue(iborLeg.Type.Equals(SwapLegType.IBOR), "Leg type should be IBOR");
            ArgChecker.isTrue(iborLeg.PaymentEvents.Empty, "PaymentEvent should be empty");
            IList <NotionalExchange> paymentEvents = new List <NotionalExchange>();

            foreach (SwapPaymentPeriod paymentPeriod in iborLeg.PaymentPeriods)
            {
                ArgChecker.isTrue(paymentPeriod is RatePaymentPeriod, "rate payment should be RatePaymentPeriod");
                RatePaymentPeriod ratePaymentPeriod = (RatePaymentPeriod)paymentPeriod;
                ArgChecker.isTrue(ratePaymentPeriod.AccrualPeriods.size() == 1, "rate payment should not be compounding");
                RateAccrualPeriod    rateAccrualPeriod = ratePaymentPeriod.AccrualPeriods.get(0);
                CurrencyAmount       notional          = ratePaymentPeriod.NotionalAmount;
                LocalDate            paymentDate       = ratePaymentPeriod.PaymentDate;
                IborIndexObservation obs             = ((IborRateComputation)rateAccrualPeriod.RateComputation).Observation;
                IborIndex            index           = obs.Index;
                LocalDate            fixingStartDate = obs.EffectiveDate;
                double           fixingYearFraction  = obs.YearFraction;
                double           beta     = (1d + fixingYearFraction * ratesProvider.iborIndexRates(index).rate(obs)) * ratesProvider.discountFactor(paymentPeriod.Currency, paymentPeriod.PaymentDate) / ratesProvider.discountFactor(paymentPeriod.Currency, fixingStartDate);
                double           ycRatio  = rateAccrualPeriod.YearFraction / fixingYearFraction;
                NotionalExchange payStart = NotionalExchange.of(notional.multipliedBy(beta * ycRatio), fixingStartDate);
                NotionalExchange payEnd   = NotionalExchange.of(notional.multipliedBy(-ycRatio), paymentDate);
                paymentEvents.Add(payStart);
                paymentEvents.Add(payEnd);
            }
            ResolvedSwapLeg leg = ResolvedSwapLeg.builder().paymentEvents(paymentEvents).payReceive(PayReceive.RECEIVE).type(SwapLegType.OTHER).build();

            return(leg);
        }
Example #3
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)));
        }
Example #4
0
        //-------------------------------------------------------------------------
        // creates a simple provider
        private SimpleRatesProvider createProvider(NotionalExchange ne)
        {
            LocalDate paymentDate = ne.PaymentDate;
            double    paymentTime = DAY_COUNT.relativeYearFraction(VAL_DATE, paymentDate);
            Currency  currency    = ne.Currency;

            DiscountFactors mockDf = mock(typeof(DiscountFactors));

            when(mockDf.discountFactor(paymentDate)).thenReturn(DISCOUNT_FACTOR);
            ZeroRateSensitivity sens = ZeroRateSensitivity.of(currency, paymentTime, -DISCOUNT_FACTOR * paymentTime);

            when(mockDf.zeroRatePointSensitivity(paymentDate)).thenReturn(sens);
            SimpleRatesProvider prov = new SimpleRatesProvider(VAL_DATE, mockDf);

            prov.DayCount = DAY_COUNT;
            return(prov);
        }
Example #5
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));
        }
Example #6
0
        /// <summary>
        /// Computes cash flow equivalent of fixed leg.
        /// <para>
        /// The return type is {@code ResolvedSwapLeg} in which individual payments are
        /// represented in terms of {@code NotionalExchange}.
        ///
        /// </para>
        /// </summary>
        /// <param name="fixedLeg">  the fixed leg </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <returns> the cash flow equivalent </returns>
        public static ResolvedSwapLeg cashFlowEquivalentFixedLeg(ResolvedSwapLeg fixedLeg, RatesProvider ratesProvider)
        {
            ArgChecker.isTrue(fixedLeg.Type.Equals(SwapLegType.FIXED), "Leg type should be FIXED");
            ArgChecker.isTrue(fixedLeg.PaymentEvents.Empty, "PaymentEvent should be empty");
            IList <NotionalExchange> paymentEvents = new List <NotionalExchange>();

            foreach (SwapPaymentPeriod paymentPeriod in fixedLeg.PaymentPeriods)
            {
                ArgChecker.isTrue(paymentPeriod is RatePaymentPeriod, "rate payment should be RatePaymentPeriod");
                RatePaymentPeriod ratePaymentPeriod = (RatePaymentPeriod)paymentPeriod;
                ArgChecker.isTrue(ratePaymentPeriod.AccrualPeriods.size() == 1, "rate payment should not be compounding");
                RateAccrualPeriod rateAccrualPeriod = ratePaymentPeriod.AccrualPeriods.get(0);
                double            factor            = rateAccrualPeriod.YearFraction * ((FixedRateComputation)rateAccrualPeriod.RateComputation).Rate;
                CurrencyAmount    notional          = ratePaymentPeriod.NotionalAmount.multipliedBy(factor);
                LocalDate         paymentDate       = ratePaymentPeriod.PaymentDate;
                NotionalExchange  pay = NotionalExchange.of(notional, paymentDate);
                paymentEvents.Add(pay);
            }
            ResolvedSwapLeg leg = ResolvedSwapLeg.builder().paymentEvents(paymentEvents).payReceive(PayReceive.RECEIVE).type(SwapLegType.OTHER).build();

            return(leg);
        }
Example #7
0
        private IList <ZeroRateSensitivity> dscSensitivityFD(RatesProvider provider, NotionalExchange @event, double eps)
        {
            Currency      currency       = @event.Currency;
            LocalDate     paymentDate    = @event.PaymentDate;
            double        discountFactor = provider.discountFactor(currency, paymentDate);
            double        paymentTime    = DAY_COUNT.relativeYearFraction(VAL_DATE, paymentDate);
            RatesProvider provUp         = mock(typeof(RatesProvider));
            RatesProvider provDw         = mock(typeof(RatesProvider));

            when(provUp.ValuationDate).thenReturn(VAL_DATE);
            when(provUp.discountFactor(currency, paymentDate)).thenReturn(discountFactor * Math.Exp(-eps * paymentTime));
            when(provDw.ValuationDate).thenReturn(VAL_DATE);
            when(provDw.discountFactor(currency, paymentDate)).thenReturn(discountFactor * Math.Exp(eps * paymentTime));
            DiscountingNotionalExchangePricer pricer = DiscountingNotionalExchangePricer.DEFAULT;
            double pvUp = pricer.presentValue(@event, provUp);
            double pvDw = pricer.presentValue(@event, provDw);
            double res  = 0.5 * (pvUp - pvDw) / eps;
            IList <ZeroRateSensitivity> zeroRateSensi = new List <ZeroRateSensitivity>();

            zeroRateSensi.Add(ZeroRateSensitivity.of(currency, paymentTime, res));
            return(zeroRateSensi);
        }