/// <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> /// Returns true if the cashflow list consists of vanilla swaplets, caplets and floorlets. /// </summary> private bool IsValidCashflowList(PriceFactorList factors, CFFloatingInterestListDeal deal) { // Get characteristics using cashflow list from the original deal. CashflowListCharacteristics characteristics = deal.Cashflows.Analyze(factors.BaseDate); bool isCompounding = deal.Cashflows.Compounding_Method != CompoundingMethod.None; return(!fForecastIsForeign && characteristics.IsStandardPayoff && characteristics.IsStandardLibor && !isCompounding); }
/// <summary> /// Register price factors used in valuation. /// </summary> public override void RegisterFactors(PriceFactorList factors, ErrorList errors) { base.RegisterFactors(factors, errors); CFFloatingInterestListDeal deal = (CFFloatingInterestListDeal)Deal; // Deal validation specific to CFFloatingInterestListValuation foreach (var cashflow in deal.Cashflows) { if (!cashflow.Resets.Any()) { continue; } var lastResetDate = cashflow.Resets.Last().Reset_Date; if (cashflow.FX_Reset_Date > 0.0 && cashflow.FX_Reset_Date < lastResetDate) { errors.Add(ErrorLevel.Warning, string.Format("Quanto adjustments for cashflow paying on {0} are not supported when the FX reset date {1} is before interest rate reset date {2}", cashflow.Payment_Date, cashflow.FX_Reset_Date, lastResetDate)); } } // Get characteristics CashflowListCharacteristics characteristics = deal.Cashflows.Analyze(factors.BaseDate); bool quanto = fForecastIsForeign && characteristics.HasQuanto && Quanto_Correction == YesNo.Yes; bool convexity = !characteristics.IsStandardLibor && Convexity_Correction == YesNo.Yes; var requirements = new VolatilityRequirements( characteristics.HasCms, characteristics.HasLibor && (characteristics.HasOptionlet || convexity || quanto), characteristics.HasCms && convexity, characteristics.HasLibor && convexity); // Collect registered volatility price factors to check they have the same distribution type var volPriceFactors = new List <IInterestVol>(); // register forecast rate volatility surfaces if (requirements.NeedForecastYieldVol) { volPriceFactors.Add(InterestVolBase.RegisterInterestYieldVol(factors, deal.Forecast_Rate_Swaption_Volatility, fForecastCurrency)); } if (requirements.NeedForecastRateVol) { volPriceFactors.Add(InterestVolBase.RegisterInterestRateVol(factors, deal.Forecast_Rate_Cap_Volatility, fForecastCurrency)); } if (requirements.NeedDiscountYieldVol) { volPriceFactors.Add(InterestVolBase.RegisterInterestYieldVol(factors, deal.Discount_Rate_Swaption_Volatility, fCurrency)); } if (requirements.NeedDiscountRateVol) { volPriceFactors.Add(InterestVolBase.RegisterInterestRateVol(factors, deal.Discount_Rate_Cap_Volatility, fCurrency)); } if (fForecastIsForeign) { // Register factor for translation from forecast rate currency to settlement currency for cashflows with FX reset date if (characteristics.HasFXReset) { factors.RegisterInterface <IFxRate>(fForecastCurrency); } if (quanto) { FXVolHelper.Register(factors, fForecastCurrency, fCurrency); CorrelationHelper.Register(factors, typeof(IInterestRate), fForecastCurrency, null, typeof(IFxRate), fForecastCurrency, fCurrency); CorrelationHelper.Register(factors, typeof(IInterestRate), fForecastCurrency, null, typeof(IInterestRate), fCurrency, null); } } if (volPriceFactors.Select(pf => pf.GetDistributionType()).Distinct().Count() > 1) { deal.AddToErrors(errors, "Volatility price factors must have the same distribution type."); } ValidateUnnecessaryVolatilities(deal, requirements, errors); }