/// <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); var deal = (CFFloatingInterestListDeal)Deal; // Set up cashflow list fCashflows.SetUseConvexityCorrection(Convexity_Correction == YesNo.Yes); fCashflows.SetUseQuantoCorrection(Quanto_Correction == YesNo.Yes); fCashflows.SetFasterAveraging(Faster_Averaging_Valuation == YesNo.Yes); fCashflows.SetOISCashflowGroupSize(OIS_Cashflow_Group_Size); fCashflows.SetConvexityLowRateCutoff(Convexity_Low_Rate_Cutoff); fCashflows.SetOISRateRounding(OIS_Rate_Rounding); double baseDate = factors.BaseDate; fCharacteristics = fCashflows.Analyze(baseDate); if (fCharacteristics.IsOIS) { fCashflows.InitializeFastOISCalculation(baseDate); } if (fCharacteristics.IsVanillaSwap) { fCashflows.CalculateAmounts(baseDate); } // Add to valuation time grid bool payDatesRequired = ValueOnCashflowDates() && requiredResults.CashRequired(); fT.AddPayDates(fCashflows, payDatesRequired); double settlementDate = deal.Settlement_Date; if (settlementDate > 0.0) { fT.AddPayDate(settlementDate, payDatesRequired); } if (Use_Settlement_Offset == YesNo.Yes && settlementDate != 0.0) { fCutoffDate = 0.0; } if (deal.Investment_Horizon > 0.0) { fT.AddPayDate(deal.Investment_Horizon, payDatesRequired); } if (Use_Survival_Probability == YesNo.Yes) { fRecoveryList = new CFRecoveryList(); fRecoveryList.PopulateRecoveryCashflowList(baseDate, settlementDate, fCashflows); } }
/// <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); CFFixedInterestListDeal deal = (CFFixedInterestListDeal)Deal; // Set up cashflow list deal.Cashflows.CalculateInterest(factors.BaseDate); // Add to valuation time grid bool payDatesRequired = ValueOnCashflowDates() && requiredResults.CashRequired(); fT.AddPayDates <CFFixedInterest>(deal.Cashflows, payDatesRequired); double baseDate = factors.BaseDate; double settlementDate = deal.Settlement_Date; if (settlementDate >= baseDate) { fT.AddPayDate(settlementDate, payDatesRequired); var accrualCalendar = deal.GetHolidayCalendar(); fAccruedInterest = deal.Cashflows.CalculateAccrual(settlementDate, false, accrualCalendar); fSettlementAmount = deal.Settlement_Amount; if (deal.Settlement_Amount_Is_Clean == YesNo.Yes) { fSettlementAmount += fAccruedInterest; } } // Settlement date takes precedence. if (Use_Settlement_Offset == YesNo.Yes && settlementDate != 0.0) { fCutoffDate = 0.0; } if (deal.Investment_Horizon > 0.0) { fT.AddPayDate(deal.Investment_Horizon, payDatesRequired); } if (Use_Survival_Probability == YesNo.Yes) { fRecoveryList = new CFRecoveryList(); fRecoveryList.PopulateRecoveryCashflowList(baseDate, settlementDate, deal.Cashflows); } }
/// <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); } }