/// <summary>
        /// Calculates the strike.
        /// </summary>
        /// <param name="fixedLeg">  the fixed leg </param>
        /// <returns> the strike </returns>
        protected internal virtual double calculateStrike(ResolvedSwapLeg fixedLeg)
        {
            SwapPaymentPeriod paymentPeriod = fixedLeg.PaymentPeriods.get(0);

            ArgChecker.isTrue(paymentPeriod is RatePaymentPeriod, "Payment period must be RatePaymentPeriod");
            RatePaymentPeriod ratePaymentPeriod = (RatePaymentPeriod)paymentPeriod;
            // compounding is caught when par rate is computed
            RateComputation rateComputation = ratePaymentPeriod.AccrualPeriods.get(0).RateComputation;

            ArgChecker.isTrue(rateComputation is FixedRateComputation, "Swap leg must be fixed leg");
            return(((FixedRateComputation)rateComputation).Rate);
        }
Example #2
0
        // find the notional
        private CurrencyAmount buildLegNotional(ResolvedSwapLeg leg)
        {
            // check for NotionalPaymentPeriod
            SwapPaymentPeriod firstPaymentPeriod = leg.PaymentPeriods.get(0);

            if (firstPaymentPeriod is NotionalPaymentPeriod)
            {
                NotionalPaymentPeriod pp = (NotionalPaymentPeriod)firstPaymentPeriod;
                return(pp.NotionalAmount.positive());
            }
            return(NOT_FOUND);
        }
Example #3
0
        /// <summary>
        /// Computes the derivative of the conventional cash annuity with respect to the yield from a swap leg.
        /// <para>
        /// The computation is relevant only for standard swaps with constant notional and regular payments.
        /// The swap leg must be a fixed leg. However, this is not checked internally.
        ///
        /// </para>
        /// </summary>
        /// <param name="fixedLeg">  the fixed leg of the swap </param>
        /// <param name="yield">  the yield </param>
        /// <returns> the cash annuity </returns>
        public virtual ValueDerivatives annuityCashDerivative(ResolvedSwapLeg fixedLeg, double yield)
        {
            int nbFixedPeriod = fixedLeg.PaymentPeriods.size();
            SwapPaymentPeriod paymentPeriod = fixedLeg.PaymentPeriods.get(0);

            ArgChecker.isTrue(paymentPeriod is RatePaymentPeriod, "payment period should be RatePaymentPeriod");
            RatePaymentPeriod ratePaymentPeriod = (RatePaymentPeriod)paymentPeriod;
            int              nbFixedPaymentYear = (int)(long)Math.Round(1d / ratePaymentPeriod.DayCount.yearFraction(ratePaymentPeriod.StartDate, ratePaymentPeriod.EndDate), MidpointRounding.AwayFromZero);
            double           notional           = Math.Abs(ratePaymentPeriod.Notional);
            ValueDerivatives annuityUnit        = annuityCash1(nbFixedPaymentYear, nbFixedPeriod, yield);

            return(ValueDerivatives.of(annuityUnit.Value * notional, annuityUnit.Derivatives.multipliedBy(notional)));
        }
Example #4
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Computes the conventional cash annuity from a swap leg.
        /// <para>
        /// The computation is relevant only for standard swaps with constant notional and regular payments.
        /// The swap leg must be a fixed leg. However, this is not checked internally.
        ///
        /// </para>
        /// </summary>
        /// <param name="fixedLeg">  the fixed leg of the swap </param>
        /// <param name="yield">  the yield </param>
        /// <returns> the cash annuity </returns>
        public virtual double annuityCash(ResolvedSwapLeg fixedLeg, double yield)
        {
            int nbFixedPeriod = fixedLeg.PaymentPeriods.size();
            SwapPaymentPeriod paymentPeriod = fixedLeg.PaymentPeriods.get(0);

            ArgChecker.isTrue(paymentPeriod is RatePaymentPeriod, "payment period should be RatePaymentPeriod");
            RatePaymentPeriod ratePaymentPeriod = (RatePaymentPeriod)paymentPeriod;
            int    nbFixedPaymentYear           = (int)(long)Math.Round(1d / ratePaymentPeriod.DayCount.yearFraction(ratePaymentPeriod.StartDate, ratePaymentPeriod.EndDate), MidpointRounding.AwayFromZero);
            double notional    = Math.Abs(ratePaymentPeriod.Notional);
            double annuityCash = notional * this.annuityCash(nbFixedPaymentYear, nbFixedPeriod, yield);

            return(annuityCash);
        }
Example #5
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Computes the par rate for swaps with a fixed leg.
        /// <para>
        /// The par rate is the common rate on all payments of the fixed leg for which the total swap present value is 0.
        /// </para>
        /// <para>
        /// At least one leg must be a fixed leg. The par rate will be computed with respect to the first fixed leg
        /// in which all the payments are fixed payments with a unique accrual period (no compounding) and no FX reset.
        /// If the fixed leg is compounding, the par rate is computed only when the number of fixed coupon payments is 1 and
        /// accrual factor of each sub-period is 1
        ///
        /// </para>
        /// </summary>
        /// <param name="swap">  the product </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the par rate </returns>
        public virtual double parRate(ResolvedSwap swap, RatesProvider provider)
        {
            // find fixed leg
            ResolvedSwapLeg fixedLeg    = this.fixedLeg(swap);
            Currency        ccyFixedLeg = fixedLeg.Currency;
            // other payments (not fixed leg coupons) converted in fixed leg currency
            double otherLegsConvertedPv = 0.0;

            foreach (ResolvedSwapLeg leg in swap.Legs)
            {
                if (leg != fixedLeg)
                {
                    double pvLocal = legPricer.presentValueInternal(leg, provider);
                    otherLegsConvertedPv += (pvLocal * provider.fxRate(leg.Currency, ccyFixedLeg));
                }
            }
            double fixedLegEventsPv = legPricer.presentValueEventsInternal(fixedLeg, provider);

            if (fixedLeg.PaymentPeriods.size() > 1)
            {     // try multiperiod par-rate
                  // PVBP
                double pvbpFixedLeg = legPricer.pvbp(fixedLeg, provider);
                // Par rate
                return(-(otherLegsConvertedPv + fixedLegEventsPv) / pvbpFixedLeg);
            }
            SwapPaymentPeriod firstPeriod = fixedLeg.PaymentPeriods.get(0);

            ArgChecker.isTrue(firstPeriod is RatePaymentPeriod, "PaymentPeriod must be instance of RatePaymentPeriod");
            RatePaymentPeriod payment = (RatePaymentPeriod)firstPeriod;

            if (payment.AccrualPeriods.size() == 1)
            {     // no compounding
                  // PVBP
                double pvbpFixedLeg = legPricer.pvbp(fixedLeg, provider);
                // Par rate
                return(-(otherLegsConvertedPv + fixedLegEventsPv) / pvbpFixedLeg);
            }
            // try Compounding
            Triple <bool, int, double> fixedCompounded = checkFixedCompounded(fixedLeg);

            ArgChecker.isTrue(fixedCompounded.First, "Swap should have a fixed leg and for one payment it should be based on compunding witout spread.");
            double notional = payment.Notional;
            double df       = provider.discountFactor(ccyFixedLeg, payment.PaymentDate);

            return(Math.Pow(-(otherLegsConvertedPv + fixedLegEventsPv) / (notional * df) + 1.0d, 1.0 / fixedCompounded.Second) - 1.0d);
        }