Пример #1
0
        /// <inheritdoc />
        public override void HeadNodeInitialize(PriceFactorList factors, BaseTimeGrid baseTimes, RequiredResults requiredResults)
        {
            base.HeadNodeInitialize(factors, baseTimes, requiredResults);

            var deal = (SwaptionBaseDeal)Deal;

            // Call HeadNodeInitialize on leg models to create time grid on leg models.
            fItems.HeadNodeInitialize(factors, baseTimes, requiredResults);

            SwaptionBaseValuation.SetCashflowLists(null, deal, ref fFixedCashflowList, ref fFloatCashflowList);

            Debug.Assert(fFloatCashflowList != null && fFixedCashflowList != null, "One or both of the underlying swap legs are null.");

            // Calculate fixed interest cashflows
            fFixedCashflowList.CalculateInterest(factors.BaseDate);

            // Add to valuation time grid
            bool cashRequired = requiredResults.CashRequired();

            fT.Add(deal.Option_Expiry_Date, true);
            if (deal.Settlement_Style == SettlementType.Physical)
            {
                fT.AddPayDates(fFixedCashflowList, cashRequired);
                fT.AddPayDates(fFloatCashflowList, cashRequired);
            }
            else
            {
                fT.AddPayDate(deal.Settlement_Date, cashRequired);
            }
        }
Пример #2
0
        /// <summary>
        /// Prepare for valuation anything that is not dependent upon the scenario.
        /// </summary>
        public override void PreCloneInitialize(PriceFactorList factors, BaseTimeGrid baseTimes, RequiredResults requiredResults)
        {
            base.PreCloneInitialize(factors, baseTimes, requiredResults);

            CallableBondForward deal = (CallableBondForward)Deal;

            double           firstCallDate   = deal.First_Call_Date;
            double           lastCallDate    = deal.Last_Call_Date;
            double           baseDate        = factors.BaseDate;
            double           issueDate       = deal.Issue_Date;
            double           settlementDate  = deal.Settlement_Date;
            double           priceDate       = Math.Max(baseDate, settlementDate + 1.0); // bond cashflows before priceDate do not contribute to bond price
            double           maturityDate    = deal.Bond_Maturity_Date;
            double           couponInterval  = deal.Coupon_Interval;
            double           notional        = deal.Notional;
            IHolidayCalendar holidayCalendar = deal.GetHolidayCalendar();

            DateGenerationParams dateGenerationParams = new DateGenerationParams
            {
                EffectiveDate         = issueDate,
                MaturityDate          = maturityDate,
                AccrualDayCount       = deal.Accrual_Day_Count,
                FirstCouponDate       = deal.First_Coupon_Date,
                PenultimateCouponDate = deal.Penultimate_Coupon_Date,
                Amortisation          = deal.Amortisation,
                CouponPeriod          = couponInterval,
                Principal             = notional,
                PrincipalExchange     = PrincipalExchange.Start_Maturity,
                AccrualCalendar       = holidayCalendar
            };

            CashflowListDetail detail = CashflowGeneration.GenerateCashflowListDetail(dateGenerationParams);

            // Collect reset dates as we loop.
            var resetDates = new DateList(detail.Coupon_Details.Count);

            // Create cashflow list
            fCashflowList             = new CFFixedInterestList();
            fCashflowList.Compounding = YesNo.No;

            foreach (CouponDetail couponDetail in detail.Coupon_Details)
            {
                if (couponDetail.Payment_Date < priceDate)
                {
                    continue;
                }

                foreach (AccrualDetail accrualDetail in couponDetail.Accrual_Details)
                {
                    resetDates.Add(accrualDetail.Accrual_Start_Date);

                    if (couponDetail.Payment_Date < priceDate)
                    {
                        continue;
                    }

                    var cashflow = new CFFixedInterest
                    {
                        Payment_Date          = couponDetail.Payment_Date,
                        Notional              = accrualDetail.Notional,
                        Accrual_Start_Date    = accrualDetail.Accrual_Start_Date,
                        Accrual_End_Date      = accrualDetail.Accrual_End_Date,
                        Accrual_Year_Fraction = accrualDetail.Accrual_Year_Fraction,
                        Rate = deal.Coupon_Rate * Percentage.PercentagePoint,
                        Accrual_Day_Count = deal.Accrual_Day_Count,
                        Discounted        = YesNo.No
                    };

                    fCashflowList.Items.Add(cashflow);
                }
            }

            IRBaseDealSkin.ApplyRateSchedule(fCashflowList.Items, deal.Coupon_Rate_Schedule, Percentage.PercentagePoint, holidayCalendar, DateAdjustmentMethod.Modified_Following);

            // Calculate fixed interest cashflows.
            fCashflowList.CalculateInterest(baseDate);

            fFixedCashflowList = PrincipalCashflows(priceDate, issueDate, maturityDate, PrincipalExchange.Start_Maturity, notional, deal.Amortisation, 1.0);

            fSettlementAmount = 0.0;
            fAccrued          = 0.0;
            bool payDatesRequired = requiredResults.CashRequired();

            if (settlementDate >= baseDate)
            {
                double settlementPrincipal = CFFixedInterestListValuation.GetPrincipal(fCashflowList, settlementDate);
                fSettlementAmount = settlementPrincipal * deal.Price * Percentage.PercentagePoint;

                for (int i = 0; i < fCashflowList.Items.Count; ++i)
                {
                    CFFixedInterest cashflow = fCashflowList[i];

                    if (cashflow.Accrual_Start_Date >= settlementDate)
                    {
                        break;
                    }

                    if (settlementDate < cashflow.Accrual_End_Date)
                    {
                        fAccrued += cashflow.Interest() * (settlementDate - cashflow.Accrual_Start_Date) / (cashflow.Accrual_End_Date - cashflow.Accrual_Start_Date);
                    }
                }

                if (deal.Price_Is_Clean == YesNo.Yes)
                {
                    fSettlementAmount += fAccrued; // add accrued interest
                }
                fT.AddPayDate(settlementDate, payDatesRequired);
            }

            // Add the floating and fixed cashflow dates to the time grid.
            fT.AddPayDates <CFFixedInterest>(fCashflowList, payDatesRequired);
            fT.AddPayDates <CFFixed>(fFixedCashflowList, payDatesRequired);

            // We only need an option pricer if callable on or after the settlement date.
            fSwaptionPricer = null;
            if (lastCallDate >= settlementDate)
            {
                // Snap call dates to grid of reset dates and
                // ensure that first call date is on or after settlement date
                int iLast = resetDates.IndexOfNextDate(lastCallDate);
                lastCallDate = resetDates[iLast];
                int iFirst = resetDates.IndexOfNextDate(firstCallDate);

                while ((iFirst < resetDates.Count - 1) && (resetDates[iFirst] < settlementDate))
                {
                    // move first exercise date forward
                    iFirst++;
                }

                firstCallDate = resetDates[iFirst];
                int      paySign      = deal.Call_Put == OptionType.Put ? +1 : -1;
                RateList exerciseFees = new RateList();

                foreach (Rate price in deal.Call_Prices)
                {
                    Rate fee = new Rate();
                    fee.Value = paySign * (Percentage.OverPercentagePoint - price.Value);
                    fee.Date  = price.Date;
                    exerciseFees.Add(fee);
                }

                var amortisation = AllocateAmortisationToPaymentDates <CFFixedInterest>(deal.Amortisation, fCashflowList.Items);

                fSwaptionPricer = new SwaptionPricer(issueDate, maturityDate, couponInterval, couponInterval,
                                                     deal.Accrual_Day_Count, holidayCalendar, DayCount.ACT_365, holidayCalendar, firstCallDate, lastCallDate, baseDate,
                                                     paySign, paySign, 0.0, null, notional, amortisation, deal.Coupon_Rate, null, deal.Coupon_Rate_Schedule, exerciseFees,
                                                     null, OptionStyle2.Bermudan, Max_Nodes, Step_Size, fT, true, requiredResults.CashRequired());
            }

            if (NeedSurvivalProb())
            {
                fRecoveryList = new CFRecoveryList();
                fRecoveryList.PopulateRecoveryCashflowList(baseDate, settlementDate, fCashflowList);
            }
        }