Exemplo n.º 1
0
        /// <summary>
        /// Prepare for valuation anything that is dependent upon the scenario.
        /// </summary>
        public override void PreValue(PriceFactorList factors)
        {
            base.PreValue(factors);
            BondFutureOption deal = (BondFutureOption)Deal;

            fInterestYieldVol = InterestVolBase.GetYieldVol(factors, deal.Yield_Volatility, fCurrency);

            var bfb = (BondFuturesBasis)fFuturesBasis;

            GenerateCTD(factors.BaseDate, bfb.CTD_Issue_Date, bfb.CTD_Maturity_Date, bfb.CTD_Coupon_Interval, bfb.CTD_First_Coupon_Date, bfb.CTD_Penultimate_Coupon_Date, bfb.CTD_Day_Count, Deal.GetHolidayCalendar(), bfb.CTD_Coupon_Rate, bfb.CTD_Conversion_Factor);

            if (NeedRating(Respect_Default, deal.Issuer))
            {
                fCreditRating = factors.Get <CreditRating>(deal.Issuer);
                fRecoveryRate = factors.Get <RecoveryRate>(InterestRateUtils.GetRateId(deal.Recovery_Rate, deal.Issuer));
            }
            else
            {
                fCreditRating = null;
                fRecoveryRate = null;
            }

            if (NeedSurvivalProbability(Use_Survival_Probability, deal.Issuer))
            {
                fSurvivalProb = factors.GetInterface <ISurvivalProb>(InterestRateUtils.GetRateId(deal.Survival_Probability, deal.Issuer));
            }
            else
            {
                fSurvivalProb = null;
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Register price factors.
        /// </summary>
        public override void RegisterFactors(PriceFactorList factors, ErrorList errors)
        {
            base.RegisterFactors(factors, errors);

            BondOptionDeal deal = (BondOptionDeal)Deal;

            InterestVolBase.RegisterInterestYieldVol(factors, deal.Yield_Volatility, fCurrency);

            bool needRating   = Respect_Default == YesNo.Yes && !string.IsNullOrEmpty(deal.Issuer);
            bool needSurvival = Use_Survival_Probability == YesNo.Yes && !string.IsNullOrEmpty(deal.Issuer);
            bool needRecovery = needRating;

            if (needRating)
            {
                factors.Register <CreditRating>(deal.Issuer);
            }

            if (needRecovery)
            {
                factors.Register <RecoveryRate>(string.IsNullOrEmpty(deal.Recovery_Rate) ? deal.Issuer : deal.Recovery_Rate);
            }

            if (needSurvival)
            {
                factors.RegisterInterface <ISurvivalProb>(string.IsNullOrEmpty(deal.Survival_Probability) ? deal.Issuer : deal.Survival_Probability);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Prepare for valuation anything that is dependent upon the scenario.
        /// </summary>
        public override void PreValue(PriceFactorList factors)
        {
            base.PreValue(factors);

            CallableBondForward deal = (CallableBondForward)Deal;

            fInterestYieldVol = InterestVolBase.GetYieldVol(factors, deal.Yield_Volatility, fCurrency);

            fNeedsCreditRating = NeedCreditRating();
            fCreditRating      = NeedCreditRating() ? factors.Get <CreditRating>(deal.Issuer)                                                                               : null;
            fRecoveryRate      = NeedRecovery()     ? factors.Get <RecoveryRate>(string.IsNullOrEmpty(deal.Recovery_Rate) ? deal.Issuer : deal.Recovery_Rate)               : null;
            fSurvivalProb      = NeedSurvivalProb() ? factors.GetInterface <ISurvivalProb>(string.IsNullOrEmpty(deal.Survival_Probability) ? deal.Issuer : deal.Survival_Probability) : null;
        }
Exemplo n.º 4
0
        /// <summary>
        /// Prepare for valuation.
        /// </summary>
        public override void PreValue(PriceFactorList factors)
        {
            var deal = (CFFloatingInterestListDeal)Deal;

            base.PreValue(factors);

            bool quanto    = fForecastIsForeign && fCharacteristics.HasQuanto && Quanto_Correction == YesNo.Yes;
            bool convexity = !fCharacteristics.IsStandardLibor && Convexity_Correction == YesNo.Yes;

            // volatility surfaces for forecast rate
            if (fCharacteristics.HasCms)
            {
                fForecastYieldVol = InterestVolBase.GetYieldVol(factors, deal.Forecast_Rate_Swaption_Volatility, fForecastCurrency);
            }

            if (fCharacteristics.HasLibor && (fCharacteristics.HasOptionlet || convexity || quanto))
            {
                fForecastRateVol = InterestVolBase.GetRateVol(factors, deal.Forecast_Rate_Cap_Volatility, fForecastCurrency);
            }

            // volatility surfaces for discount rate
            if (convexity)
            {
                // Discount rate volatility and correlation for convexity correction
                if (fCharacteristics.HasCms)
                {
                    fDiscountYieldVol = InterestVolBase.GetYieldVol(factors, deal.Discount_Rate_Swaption_Volatility, fCurrency);
                }

                if (fCharacteristics.HasLibor)
                {
                    fDiscountRateVol = InterestVolBase.GetRateVol(factors, deal.Discount_Rate_Cap_Volatility, fCurrency);
                }
            }

            if (fForecastIsForeign)
            {
                // Get factor for translation from forecast rate currency to settlement currency for cashflows with FX reset date
                if (fCharacteristics.HasFXReset)
                {
                    fForecastFxRate = factors.GetInterface <IFxRate>(fForecastCurrency);
                }

                if (quanto)
                {
                    fForecastFxVol          = FXVolHelper.Get(factors, fForecastCurrency, fCurrency);
                    fForecastFxCorrel       = CorrelationHelper.Get(factors, typeof(InterestRate), fForecastCurrency, null, typeof(FxRate), fForecastCurrency, fCurrency);
                    fForecastDiscountCorrel = CorrelationHelper.Get(factors, typeof(InterestRate), fForecastCurrency, null, typeof(InterestRate), fCurrency, null);
                }
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Register price factors used in valuation.
        /// </summary>
        public override void RegisterFactors(PriceFactorList factors, ErrorList errors)
        {
            base.RegisterFactors(factors, errors);

            var deal = (CFEquityFloatingInterestListDeal)Deal;

            deal.GetDealHelper().RegisterFactors(factors, errors);

            fEquityCurrency = deal.Equity_Currency;
            factors.RegisterInterface <IFxRate>(fEquityCurrency);

            fEquityPayoffCurrency = string.IsNullOrEmpty(deal.Equity_Payoff_Currency) ? fEquityCurrency : deal.Equity_Payoff_Currency;

            if (fEquityPayoffCurrency != fEquityCurrency)
            {
                factors.RegisterInterface <IFxRate>(fEquityPayoffCurrency);
            }

            // Get characteristics
            EquityCashflowListCharacteristics characteristics = deal.Cashflows.Analyze(factors.BaseDate);
            bool quanto = fForecastIsForeign && Quanto_Correction == YesNo.Yes;

            if (characteristics.fHasLibor)
            {
                if ((!characteristics.fIsStandardLibor && Convexity_Correction == YesNo.Yes) || quanto)
                {
                    var forecastRateVol = InterestVolBase.RegisterInterestRateVol(factors, deal.Forecast_Rate_Cap_Volatility, fForecastCurrency);
                    InterestVolBase.Validate(deal, forecastRateVol, ProbabilityDistribution.Lognormal, errors);
                }

                if (!characteristics.fIsStandardLibor && Convexity_Correction == YesNo.Yes)
                {
                    var discountRateVol = InterestVolBase.RegisterInterestRateVol(factors, deal.Discount_Rate_Cap_Volatility, fCurrency);
                    InterestVolBase.Validate(deal, discountRateVol, ProbabilityDistribution.Lognormal, errors);
                }
            }

            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);
            }

            deal.Cashflows.RegisterFactorsValidate(factors.BaseDate, deal.GetEquityPayoffType() == PayoffType.Compo, deal.IsCrossCurrency(), errors);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Register price factors.
        /// </summary>
        public override void RegisterFactors(PriceFactorList factors, ErrorList errors)
        {
            BondFutureOption deal = (BondFutureOption)Deal;

            base.RegisterFactors(factors, errors);
            InterestVolBase.RegisterInterestYieldVol(factors, deal.Yield_Volatility, fCurrency);

            if (NeedRating(Respect_Default, deal.Issuer))
            {
                factors.Register <CreditRating>(deal.Issuer);

                // register realized recovery rate.
                factors.Register <RecoveryRate>(InterestRateUtils.GetRateId(deal.Recovery_Rate, deal.Issuer));
            }

            if (NeedSurvivalProbability(Use_Survival_Probability, deal.Issuer))
            {
                factors.RegisterInterface <ISurvivalProb>(InterestRateUtils.GetRateId(deal.Survival_Probability, deal.Issuer));
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Register price factors.
        /// </summary>
        public override void RegisterFactors(PriceFactorList factors, ErrorList errors)
        {
            base.RegisterFactors(factors, errors);

            CallableBondForward deal = (CallableBondForward)Deal;

            InterestVolBase.RegisterInterestYieldVol(factors, deal.Yield_Volatility, deal.Currency);

            if (NeedCreditRating())
            {
                factors.Register <CreditRating>(deal.Issuer);
            }

            if (NeedRecovery())
            {
                factors.Register <RecoveryRate>(string.IsNullOrEmpty(deal.Recovery_Rate) ? deal.Issuer : deal.Recovery_Rate);
            }

            if (NeedSurvivalProb())
            {
                factors.RegisterInterface <ISurvivalProb>(string.IsNullOrEmpty(deal.Survival_Probability) ? deal.Issuer : deal.Survival_Probability);
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Prepare for valuation.
        /// </summary>
        public override void PreValue(PriceFactorList factors)
        {
            base.PreValue(factors);
            var deal = (CFEquityFloatingInterestListDeal)Deal;

            deal.GetDealHelper().PreValueAsset(out fEquity, out fEquityVol, ref fEquityQuantoCompo, factors);

            // Get FX rate price factors
            fEquityCurrency       = deal.Equity_Currency;
            fEquityPayoffCurrency = string.IsNullOrEmpty(deal.Equity_Payoff_Currency) ? fEquityCurrency : deal.Equity_Payoff_Currency;
            fEquityFXRate         = factors.GetInterface <IFxRate>(fEquityCurrency);
            fEquityPayoffFXRate   = fEquityPayoffCurrency != fEquityCurrency?factors.GetInterface <IFxRate>(fEquityPayoffCurrency) : fEquityFXRate;

            bool quanto = fForecastIsForeign && Quanto_Correction == YesNo.Yes;

            if (fCharacteristics.fHasLibor)
            {
                // volatility surfaces for forecast rate
                if ((!fCharacteristics.fIsStandardLibor && Convexity_Correction == YesNo.Yes) || quanto)
                {
                    fForecastRateVol = InterestVolBase.GetRateVol(factors, deal.Forecast_Rate_Cap_Volatility, fForecastCurrency);
                }

                // volatility surfaces for discount rate
                if (!fCharacteristics.fIsStandardLibor && Convexity_Correction == YesNo.Yes)
                {
                    fDiscountRateVol = InterestVolBase.GetRateVol(factors, deal.Discount_Rate_Cap_Volatility, fCurrency);
                }
            }

            if (quanto)
            {
                fForecastFXVol          = FXVolHelper.Get(factors, fForecastCurrency, fCurrency);
                fForecastFXCorrel       = CorrelationHelper.Get(factors, typeof(InterestRate), fForecastCurrency, null, typeof(FxRate), fForecastCurrency, fCurrency);
                fForecastDiscountCorrel = CorrelationHelper.Get(factors, typeof(InterestRate), fForecastCurrency, null, typeof(InterestRate), fCurrency, null);
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Calculate valuation profiles.
        /// </summary>
        public override void Value(ValuationResults valuationResults, PriceFactorList factors, BaseTimeGrid baseTimes)
        {
            PreValue(factors);

            TimeGridIterator tgi              = new TimeGridIterator(fT);
            PVProfiles       result           = valuationResults.Profile;
            CashAccumulators cashAccumulators = valuationResults.Cash;

            BondOptionDeal deal = (BondOptionDeal)Deal;

            double baseDate  = factors.BaseDate;
            double notional  = deal.Notional;
            double interval  = deal.Coupon_Interval;
            double buySign   = (deal.Buy_Sell == BuySell.Buy) ? +1 : -1;
            double paySign   = (deal.Option_Type == OptionType.Call) ? +1 : -1;
            double coupon    = Percentage.PercentagePoint * deal.Coupon_Rate;
            double tExpiry   = CalcUtils.DaysToYears(deal.Expiry_Date - baseDate);
            double tMaturity = CalcUtils.DaysToYears(deal.Bond_Maturity_Date - baseDate);

            IInterestYieldVol interestYieldVol = InterestVolBase.GetYieldVol(factors, deal.Yield_Volatility, fCurrency);

            if ((deal.Amortisation) != null && (deal.Amortisation.Count > 0))
            {
                notional = deal.Amortisation.GetPrincipal(notional, deal.Expiry_Date);
            }

            bool respectDefault = Respect_Default == YesNo.Yes && fCreditRating != null;

            using (IntraValuationDiagnosticsHelper.StartDeal(fIntraValuationDiagnosticsWriter, Deal))
            {
                using (var pricerCache = Vector.Cache(factors.NumScenarios))
                {
                    Vector defaultTime        = null;
                    Vector bondIsAlive        = null;
                    Vector historicalRecovery = null;

                    if (respectDefault)
                    {
                        defaultTime        = pricerCache.Get();
                        bondIsAlive        = pricerCache.Get(1.0);
                        historicalRecovery = pricerCache.GetClear();

                        fCreditRating.DefaultTime(defaultTime);
                    }

                    var defaultedBeforeBaseDate = respectDefault && CreditRating.DefaultedBeforeBaseDate(fCreditRating, baseDate);

                    VectorEngine.For(tgi, () =>
                    {
                        using (IntraValuationDiagnosticsHelper.StartValuation(fIntraValuationDiagnosticsWriter, tgi.Date))
                        {
                            using (var cache = Vector.Cache(factors.NumScenarios))
                            {
                                Vector optionValue      = cache.GetClear();
                                Vector stdDev           = cache.Get(); // Std.Dev of Price
                                Vector stdDevYield      = cache.Get(); //Std.Dev of Yield
                                Vector price            = cache.Get();
                                Vector yield            = cache.Get();
                                Vector macaulayDuration = cache.Get();
                                Vector bondValue        = cache.Get();
                                Vector df  = cache.Get();
                                Vector dfr = fRepoIsDiscount ? null : cache.Get();

                                if (defaultedBeforeBaseDate)
                                {
                                    result.AppendVector(tgi.Date, optionValue);
                                    return(LoopAction.Break);
                                }

                                // This BondPrice function returns the value of the bond cashflows after ExpiryDate, including accrual, discounted back to T.date
                                double accrual, cash;
                                PricingFunctions.BondPrice(bondValue, out accrual, out cash, baseDate, tgi.Date, deal.Expiry_Date, deal.Issue_Date, deal.Bond_Maturity_Date, notional, coupon, fPayDates, fAccruals, fDiscountRate, deal.Amortisation, fPrincipals, fFinalPrincipal, fSurvivalProb, +1.0);

                                // Now check scenario by scenario for defaults, overwriting bondValue as necessary
                                if (respectDefault)
                                {
                                    AdjustBondValueForDefault(notional, tExpiry, bondValue, bondIsAlive, historicalRecovery, defaultTime, tgi.T, fDiscountRate, fRecoveryRate);
                                }

                                // convert price and duration to forward (tExpiry) basis
                                if (tgi.Date == deal.Expiry_Date)
                                {
                                    optionValue.Assign(buySign * VectorMath.Max(0.0, paySign * (bondValue - notional * fStrike)));
                                    cashAccumulators.Accumulate(fFxRate, tgi.Date, optionValue);
                                }
                                else
                                {
                                    fDiscountRate.GetValue(df, tgi.T, tExpiry);

                                    if (fRepoIsDiscount)
                                    {
                                        dfr = df;
                                    }
                                    else
                                    {
                                        fRepoRate.GetValue(dfr, tgi.T, tExpiry);
                                    }

                                    // Need yield and duration to convert yield vol to price vol.
                                    PricingFunctions.BondForwardPriceAndAdjustedMacaulayDuration(price, macaulayDuration, tgi.T, tExpiry, tMaturity, coupon, interval, df, fDiscountRate, fSurvivalProb);
                                    PricingFunctions.BondYieldFromPrice(yield, tExpiry, tMaturity, coupon, interval, price);

                                    // Calculate Modified Duration from Macaulay Duration.
                                    Vector modifiedDuration = cache.GetClear();
                                    PricingFunctions.GetModifiedDuration(modifiedDuration, macaulayDuration, yield, interval);

                                    // Calculate Std.Dev of Yield and Price
                                    interestYieldVol.GetStdDev(stdDevYield, tgi.T, yield, fStrikeYield, tExpiry, tMaturity - tExpiry);
                                    stdDev.Assign(modifiedDuration * stdDevYield);

                                    if (interestYieldVol.GetDistributionType() == ProbabilityDistribution.Lognormal)
                                    {
                                        stdDev.MultiplyBy(yield);
                                    }

                                    price.AssignQuotient(bondValue, df);
                                    PricingFunctions.BlackFunction(optionValue, deal.Option_Type, price, notional * fStrike, stdDev);

                                    optionValue.MultiplyBy(buySign * dfr);

                                    if (fIntraValuationDiagnosticsWriter.Level > IntraValuationDiagnosticsLevel.None)
                                    {
                                        // Add Intra-valuation Diagnostics
                                        using (var volatilitiesAtDateStore = IntraValuationDiagnosticsHelper.CreateVolatilitiesAtDateStore(fIntraValuationDiagnosticsWriter, factors.NumScenarios))
                                            using (var volatilitiesYieldAtDateStore = IntraValuationDiagnosticsHelper.CreateVolatilitiesAtDateStore(fIntraValuationDiagnosticsWriter, factors.NumScenarios))
                                            {
                                                volatilitiesAtDateStore.Add(tgi.Date, tgi.TimeGrid.fEndDate, stdDev);
                                                volatilitiesYieldAtDateStore.Add(tgi.Date, tgi.TimeGrid.fEndDate, stdDevYield);
                                                IntraValuationDiagnosticsHelper.AddBondOptionProperties(fIntraValuationDiagnosticsWriter, price, dfr, bondValue, accrual,
                                                                                                        volatilitiesAtDateStore, volatilitiesYieldAtDateStore);
                                                IntraValuationDiagnosticsHelper.AddCashflowsPV(fIntraValuationDiagnosticsWriter, optionValue);
                                            }
                                    }
                                }

                                result.AppendVector(tgi.Date, fFxRate.Get(tgi.T) * optionValue);
                                return(LoopAction.Continue);
                            }
                        }
                    });
                }

                result.Complete(fT);
            }
        }
        /// <summary>
        /// Prepare for valuation.
        /// </summary>
        public override void PreValue(PriceFactorList factors)
        {
            base.PreValue(factors);

            CFGeneralInterestSpreadListDeal deal = (CFGeneralInterestSpreadListDeal)Deal;

            // Get spread flow characteristics
            SpreadCashflowListCharacteristics spreadCashflowCharacteristics = fCashflows.ValuationPriceFactorDependencies(factors.BaseDate, fCurrency, fForecastCurrency, fForecast2Currency);

            // vols for first forecast rate
            if (spreadCashflowCharacteristics.NeedForecast1YieldVol)
            {
                fForecast1YieldVol = InterestVolBase.GetYieldVol(factors, deal.Forecast_Rate1_Swaption_Volatility, fForecastCurrency);
            }

            if (spreadCashflowCharacteristics.NeedForecast1RateVol)
            {
                fForecast1RateVol = InterestVolBase.GetRateVol(factors, deal.Forecast_Rate1_Cap_Volatility, fForecastCurrency);
            }

            // vols for second forecast rate
            if (spreadCashflowCharacteristics.NeedForecast2YieldVol)
            {
                fForecast2YieldVol = InterestVolBase.GetYieldVol(factors, deal.Forecast_Rate2_Swaption_Volatility, fForecast2Currency);
            }

            if (spreadCashflowCharacteristics.NeedForecast2RateVol)
            {
                fForecast2RateVol = InterestVolBase.GetRateVol(factors, deal.Forecast_Rate2_Cap_Volatility, fForecast2Currency);
            }

            // vols for discount rate
            if (spreadCashflowCharacteristics.NeedDiscountYieldVol)
            {
                fDiscountYieldVol = InterestVolBase.GetYieldVol(factors, deal.Discount_Rate_Swaption_Volatility, fCurrency);
            }

            if (spreadCashflowCharacteristics.NeedDiscountRateVol)
            {
                fDiscountRateVol = InterestVolBase.GetRateVol(factors, deal.Discount_Rate_Cap_Volatility, fCurrency);
            }

            bool convexity = spreadCashflowCharacteristics.NeedDiscountYieldVol || spreadCashflowCharacteristics.NeedDiscountRateVol;

            if (fForecastCurrency != fCurrency)
            {
                if (Quanto_Correction == YesNo.Yes)
                {
                    // fx vol, fx/ir correl and forecast/discount correl
                    fFx1Vol             = FXVolHelper.Get(factors, fForecastCurrency, fCurrency);
                    fForecast1Fx1Correl = CorrelationHelper.Get(factors, typeof(InterestRate), fForecastCurrency, null, typeof(FxRate), fForecastCurrency, fCurrency);
                }

                if (convexity)
                {
                    fForecast1DiscountCorrel = CorrelationHelper.Get(factors, typeof(InterestRate), fCurrency, null, typeof(InterestRate), fForecastCurrency, null);
                }
            }

            if (fForecast2Currency != fCurrency)
            {
                if (Quanto_Correction == YesNo.Yes)
                {
                    // fx vol, fx/ir correl and forecast/discount correl
                    fFx2Vol             = FXVolHelper.Get(factors, fForecast2Currency, fCurrency);
                    fForecast2Fx2Correl = CorrelationHelper.Get(factors, typeof(InterestRate), fForecast2Currency, null, typeof(FxRate), fForecast2Currency, fCurrency);
                }

                if (convexity)
                {
                    fForecast2DiscountCorrel = CorrelationHelper.Get(factors, typeof(InterestRate), fCurrency, null, typeof(InterestRate), fForecast2Currency, null);
                }
            }

            if (spreadCashflowCharacteristics.NeedForecast1Forecast2Correlation)
            {
                if (fForecastCurrency == fForecast2Currency)
                {
                    // correl between forecast rates in same currency
                    fForecast1Forecast2Correls = factors.Get <CMSRateCorrelations>(fForecastCurrency);
                }
                else
                {
                    fForecast1Forecast2Correl = CorrelationHelper.Get(factors, typeof(InterestRate), fForecastCurrency, null, typeof(InterestRate), fForecast2Currency, null);
                }
            }
        }
        /// <summary>
        /// Register price factors.
        /// </summary>
        public override void RegisterFactors(PriceFactorList factors, ErrorList errors)
        {
            base.RegisterFactors(factors, errors);

            CFGeneralInterestSpreadListDeal deal = (CFGeneralInterestSpreadListDeal)Deal;

            // Collect registered volatility price factors to check they have the same distribution type
            var volPriceFactors = new List <IInterestVol>();

            // Get spread flow characteristics
            SpreadCashflowListCharacteristics spreadCashflowCharacteristics = deal.Cashflows.ValuationPriceFactorDependencies(factors.BaseDate, fCurrency, fForecastCurrency, fForecast2Currency);

            // register volatility surfaces for forecast rate1
            if (spreadCashflowCharacteristics.NeedForecast1YieldVol)
            {
                volPriceFactors.Add(InterestVolBase.RegisterInterestYieldVol(factors, deal.Forecast_Rate1_Swaption_Volatility, fForecastCurrency));
            }

            if (spreadCashflowCharacteristics.NeedForecast1RateVol)
            {
                volPriceFactors.Add(InterestVolBase.RegisterInterestRateVol(factors, deal.Forecast_Rate1_Cap_Volatility, fForecastCurrency));
            }

            // register volatility surfaces for forecast rate2
            if (spreadCashflowCharacteristics.NeedForecast2YieldVol)
            {
                volPriceFactors.Add(InterestVolBase.RegisterInterestYieldVol(factors, deal.Forecast_Rate2_Swaption_Volatility, fForecast2Currency));
            }

            if (spreadCashflowCharacteristics.NeedForecast2RateVol)
            {
                volPriceFactors.Add(InterestVolBase.RegisterInterestRateVol(factors, deal.Forecast_Rate2_Cap_Volatility, fForecast2Currency));
            }

            // vol surfaces for discount rate
            if (spreadCashflowCharacteristics.NeedDiscountYieldVol)
            {
                volPriceFactors.Add(InterestVolBase.RegisterInterestYieldVol(factors, deal.Discount_Rate_Swaption_Volatility, fCurrency));
            }

            if (spreadCashflowCharacteristics.NeedDiscountRateVol)
            {
                volPriceFactors.Add(InterestVolBase.RegisterInterestRateVol(factors, deal.Discount_Rate_Cap_Volatility, fCurrency));
            }

            bool convexity = spreadCashflowCharacteristics.NeedDiscountYieldVol || spreadCashflowCharacteristics.NeedDiscountRateVol;

            if (fForecastCurrency != fCurrency)
            {
                if (Quanto_Correction == YesNo.Yes)
                {
                    // fx vol, fx/ir correl and forecast/discount correl
                    FXVolHelper.Register(factors, fForecastCurrency, fCurrency);
                    CorrelationHelper.Register(factors, typeof(IInterestRate), fForecastCurrency, null, typeof(IFxRate), fForecastCurrency, fCurrency);
                }

                if (convexity)
                {
                    CorrelationHelper.Register(factors, typeof(IInterestRate), fCurrency, null, typeof(IInterestRate), fForecastCurrency, null);
                }
            }

            if (fForecast2Currency != fCurrency)
            {
                if (Quanto_Correction == YesNo.Yes)
                {
                    // fx vol, fx/ir correl and forecast/discount correl
                    FXVolHelper.Register(factors, fForecast2Currency, fCurrency);
                    CorrelationHelper.Register(factors, typeof(IInterestRate), fForecast2Currency, null, typeof(IFxRate), fForecast2Currency, fCurrency);
                }

                if (convexity)
                {
                    CorrelationHelper.Register(factors, typeof(IInterestRate), fCurrency, null, typeof(IInterestRate), fForecast2Currency, null);
                }
            }

            if (spreadCashflowCharacteristics.NeedForecast1Forecast2Correlation)
            {
                if (fForecastCurrency == fForecast2Currency)
                {
                    // correl between forecast rates in same currency
                    factors.Register <CMSRateCorrelations>(fForecastCurrency);
                }
                else
                {
                    CorrelationHelper.Register(factors, typeof(IInterestRate), fForecastCurrency, null, typeof(IInterestRate), fForecast2Currency, null);
                }
            }

            if (volPriceFactors.Select(pf => pf.GetDistributionType()).Distinct().Count() > 1)
            {
                Deal.AddToErrors(errors, "Volatility price factors must have the same distribution type.");
            }

            ValidateUnnecessaryVolatilities(deal, spreadCashflowCharacteristics, errors);
        }
Exemplo n.º 12
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);
        }