Beispiel #1
0
        /// <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);
        }
Beispiel #2
0
        /// <summary>
        /// Warn of unnecessary volatility surface definitions.
        /// </summary>
        /// <remarks>
        /// Test differently if the cap and swaption volatility definitions are the same or
        /// distinct because they may have been set by a single property or two distinct ones.
        /// </remarks>
        private static void ValidateUnnecessaryVolatilities(CFFloatingInterestListDeal deal, VolatilityRequirements requirements, ErrorList errors)
        {
            if (deal.Discount_Rate_Cap_Volatility == deal.Discount_Rate_Swaption_Volatility)
            {
                if (!requirements.NeedDiscountRateVol && !requirements.NeedDiscountYieldVol && !string.IsNullOrEmpty(deal.Discount_Rate_Cap_Volatility))
                {
                    deal.AddToErrors(errors, ErrorLevel.Info, $"Unnecessary {nameof(deal.Discount_Rate_Cap_Volatility)} and {nameof(deal.Discount_Rate_Swaption_Volatility)} {deal.Discount_Rate_Cap_Volatility}.");
                }
            }
            else
            {
                if (!requirements.NeedDiscountRateVol && !string.IsNullOrEmpty(deal.Discount_Rate_Cap_Volatility))
                {
                    deal.AddToErrors(errors, ErrorLevel.Info, $"Unnecessary {nameof(deal.Discount_Rate_Cap_Volatility)} {deal.Discount_Rate_Cap_Volatility}.");
                }

                if (!requirements.NeedDiscountYieldVol && !string.IsNullOrEmpty(deal.Discount_Rate_Swaption_Volatility))
                {
                    deal.AddToErrors(errors, ErrorLevel.Info, $"Unnecessary {nameof(deal.Discount_Rate_Swaption_Volatility)} {deal.Discount_Rate_Swaption_Volatility}.");
                }
            }

            if (deal.Forecast_Rate_Cap_Volatility == deal.Forecast_Rate_Swaption_Volatility)
            {
                if (!requirements.NeedForecastRateVol && !requirements.NeedForecastYieldVol && !string.IsNullOrEmpty(deal.Forecast_Rate_Cap_Volatility))
                {
                    deal.AddToErrors(errors, ErrorLevel.Info, $"Unnecessary {nameof(deal.Forecast_Rate_Cap_Volatility)} and {nameof(deal.Forecast_Rate_Swaption_Volatility)} {deal.Forecast_Rate_Cap_Volatility}.");
                }
            }
            else
            {
                if (!requirements.NeedForecastRateVol && !string.IsNullOrEmpty(deal.Forecast_Rate_Cap_Volatility))
                {
                    deal.AddToErrors(errors, ErrorLevel.Info, $"Unnecessary {nameof(deal.Forecast_Rate_Cap_Volatility)} {deal.Forecast_Rate_Cap_Volatility}.");
                }

                if (!requirements.NeedForecastYieldVol && !string.IsNullOrEmpty(deal.Forecast_Rate_Swaption_Volatility))
                {
                    deal.AddToErrors(errors, ErrorLevel.Info, $"Unnecessary {nameof(deal.Forecast_Rate_Swaption_Volatility)} {deal.Forecast_Rate_Swaption_Volatility}.");
                }
            }
        }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
        /// <summary>
        /// Calculate valuation metrics requested by the Base Valuation calculation.
        /// </summary>
        private void CalculateMetrics(ValuationResults valuationResults, PriceFactorList factors, CFFloatingInterestListDeal deal)
        {
            var results = valuationResults.Results <ValuationMetrics>();

            if (results == null)
            {
                return;
            }

            if (results.IsMetricRequested(ValuationMetricConstants.AccruedInterest))
            {
                using (var cache = Vector.Cache(factors.NumScenarios))
                {
                    double?parameter       = results.GetMetricParameter(ValuationMetricParameterConstants.AccrueFromToday);
                    bool   accrueFromToday = parameter.HasValue && parameter.Value == 1.0;
                    Vector accruedInterest = cache.GetClear();
                    fCashflows.CalculateAccrual(accruedInterest, factors.BaseDate, factors.BaseDate, accrueFromToday, deal.AccrualHolidayCalendar(), fForecastRate);
                    double buySellSign = deal.Buy_Sell == BuySell.Buy ? 1.0 : -1.0;
                    results.SetMetricValue(ValuationMetricConstants.AccruedInterest, new ValuationId(this), buySellSign * accruedInterest[0]);
                }
            }
        }