示例#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;
            }
        }
        public ActionResult ClearingInvestment(string investmentGuid, string endTime, double gains, string accountingTime)
        {
            return(ActionUtils.Json(() =>
            {
                CommUtils.AssertHasContent(investmentGuid, "Investment guid不能为空");
                CommUtils.AssertHasContent(endTime, "[到期时间]不能为空");
                CommUtils.AssertHasContent(accountingTime, "[到账时间]不能为空");
                CommUtils.Assert(gains <= 1000000000000, "[收益金额]不能大于10,000亿元");
                CommUtils.Assert(gains >= -1000000000000, "[收益金额]不能小于-10,000亿元");

                var valEndTime = DateTime.Parse(endTime);
                var valAccountingTime = DateTime.Parse(accountingTime);
                CommUtils.Assert(DateTime.Compare(valAccountingTime, valEndTime) >= 0, "[到账时间]不能小于[到期时间]");

                var investment = m_dbAdapter.Investment.GetInvestment(investmentGuid);
                CommUtils.Assert(DateTime.Compare(valEndTime, investment.StartTime) > 0, "[到期时间]必须大于[开始时间]");
                CommUtils.Assert(!(gains <0 && System.Math.Abs(gains)> investment.Money), "[收益金额]不能亏损超过[投资金额]");

                investment.Gains = gains;
                investment.EndTime = valEndTime;
                investment.AccountingTime = valAccountingTime;
                investment.Yield = InterestRateUtils.CalculateYield(investment.Gains.Value, investment.Money, investment.EndTime, investment.StartTime);
                var result = m_dbAdapter.Investment.UpdateInvestment(investment);

                return ActionUtils.Success(result);
            }));
        }
示例#3
0
        /// <summary>
        /// Prepare for valuation.
        /// </summary>
        public override void PreValue(PriceFactorList factors)
        {
            base.PreValue(factors);

            SetModelParameters(fItems);

            PreValueDeals(fItems, factors);

            CallableStructuredDeal deal = (CallableStructuredDeal)Deal;

            // Set volatility price factors if they have been registered by model or underlying deals
            InterestVol.TryGet <IInterestRateVol>(factors, deal.Forecast_Rate_Cap_Volatility, fForecastCurrency, out fInterestRateVol);
            InterestVol.TryGet <IInterestYieldVol>(factors, deal.Forecast_Rate_Swaption_Volatility, fForecastCurrency, out fInterestYieldVol);

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

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

            if (needSurvival)
            {
                fSurvivalProb = factors.GetInterface <ISurvivalProb>(string.IsNullOrEmpty(deal.Survival_Probability) ? deal.Issuer : deal.Survival_Probability);
            }
        }
示例#4
0
        /// <summary>
        /// Register price factors used in valuation.
        /// </summary>
        public override void RegisterFactors(PriceFactorList factors, ErrorList errors)
        {
            base.RegisterFactors(factors, errors);

            if (!string.IsNullOrEmpty(fForecastCurrency) && fForecastCurrency != fCurrency)
            {
                errors.Add(ErrorLevel.Error, "Settlement currency (Currency) and currency of Forecast_Rate must be the same");
            }

            SetModelParameters(fItems);
            ValidateModels(fItems, errors);

            fItems.RegisterFactors(factors, errors);

            CallableStructuredDeal deal = (CallableStructuredDeal)fDeal;

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

            if (needRating)
            {
                factors.Register <CreditRating>(deal.Issuer);
                factors.Register <RecoveryRate>(InterestRateUtils.GetRateId(deal.Recovery_Rate, deal.Issuer));
            }

            if (needSurvival)
            {
                factors.RegisterInterface <ISurvivalProb>(string.IsNullOrEmpty(deal.Survival_Probability) ? deal.Issuer : deal.Survival_Probability);
            }
        }
示例#5
0
        /// <summary>
        /// Get price factors.
        /// </summary>
        private void PreValue(PriceFactorList factors)
        {
            var deal = (CalendarSpreadOption)Deal;

            // Get forward price samples.
            fForwardSample = factors.Get <ForwardPriceSample>(deal.Sampling_Type);

            // Get ReferencePrice price factors.
            fReferencePrice1 = factors.GetInterface <IReferencePrice>(deal.Reference_Type);
            fReferencePrice2 = factors.GetInterface <IReferencePrice>(deal.Reference_Type);

            // Get ReferenceVol price factors.
            // Default to Reference Type if Reference Vol Type is not set.
            if (string.IsNullOrEmpty(deal.Reference_Vol_Type))
            {
                fReferenceVol1 = factors.Get <ReferenceVol>(deal.Reference_Type);
                fReferenceVol2 = factors.Get <ReferenceVol>(deal.Reference_Type);
            }
            else
            {
                fReferenceVol1 = factors.Get <ReferenceVol>(deal.Reference_Vol_Type);
                fReferenceVol2 = factors.Get <ReferenceVol>(deal.Reference_Vol_Type);
            }

            // Get correlation price factor based on the ID of the forward price.
            fCorrelations = factors.Get <ForwardPriceCorrelations>(fReferencePrice1.GetForwardPrice());

            // Get FX rate price factors.
            fFxRate            = factors.GetInterface <IFxRate>(deal.Currency);
            fFxPayoffRate      = factors.GetInterface <IFxRate>(deal.DealCurrency());
            fPriceFactorFxRate = factors.GetInterface <IFxRate>(fReferencePrice1.DomesticCurrency());

            // Get discount rate price factor.
            fDiscountRate = factors.GetInterface <IInterestRate>(InterestRateUtils.GetRateId(deal.Discount_Rate, deal.Currency));
        }
示例#6
0
 /// <summary>
 /// Register price factors.
 /// </summary>
 public override void RegisterFactors(PriceFactorList factors, ErrorList errors)
 {
     factors.Register <DiscountRate>(InterestRateUtils.GetRateId(fDeal.Discount_Rate, fDeal.Currency));
     factors.RegisterInterface <IFxRate>(fDeal.Currency);
     factors.RegisterInterface <IExpectedLoss>(fDeal.Reference_Index);
     factors.RegisterInterface <IRealizedLoss>(fDeal.Reference_Index);
 }
        public ActionResult ModifyInvestment(string investmentGuid, string name, string description,
                                             double money, string yieldDue, double?gains, string startTime, string endTime, string accountingTime)
        {
            return(ActionUtils.Json(() =>
            {
                ValidateUtils.Name(name, "投资标的");
                CommUtils.AssertHasContent(startTime, "[开始时间]不能为空");
                CommUtils.AssertHasContent(endTime, "[到期时间]不能为空");
                CommUtils.Assert(money <= 1000000000000, "[投资金额]不能大于10,000亿元");
                CommUtils.Assert(money > 0, "[投资金额]必须大于0元");

                var valStartTime = DateTime.Parse(startTime);
                var valEndTime = DateTime.Parse(endTime);
                CommUtils.Assert(DateTime.Compare(valEndTime, valStartTime) > 0, "[到期时间]必须大于[开始时间]");

                var investment = m_dbAdapter.Investment.GetInvestment(investmentGuid);
                investment.Name = name;
                investment.Description = description;
                investment.Money = money;
                investment.StartTime = valStartTime;
                investment.EndTime = valEndTime;
                investment.YieldDue = null;

                if (investment.Gains.HasValue)
                {
                    CommUtils.AssertNotNull(gains, "[收益金额]不能为空");
                    CommUtils.AssertHasContent(accountingTime, "[到账时间]不能为空");
                    CommUtils.Assert(gains <= 1000000000000, "[收益金额]不能大于10,000亿元");
                    CommUtils.Assert(gains >= -1000000000000, "[收益金额]不能小于-10,000亿元");
                    CommUtils.Assert(!(gains <0 && System.Math.Abs(gains.Value)> investment.Money), "[收益金额]不能亏损超过[投资金额]");

                    var valAccountingTime = DateTime.Parse(accountingTime);
                    CommUtils.Assert(DateTime.Compare(valAccountingTime, valEndTime) >= 0, "[到账时间]不能小于[到期时间]");

                    investment.AccountingTime = valAccountingTime;
                    investment.Gains = gains;
                    investment.Yield = InterestRateUtils.CalculateYield(investment.Gains.Value, investment.Money, investment.EndTime, investment.StartTime);
                }

                if (!string.IsNullOrWhiteSpace(yieldDue) && yieldDue != "-")
                {
                    var percentValue = 0.0;
                    if (yieldDue.Contains('%'))
                    {
                        CommUtils.Assert(double.TryParse(yieldDue.Substring(0, yieldDue.Length - 1), out percentValue), "预计收益率必须为数字");
                    }
                    else
                    {
                        CommUtils.Assert(double.TryParse(yieldDue, out percentValue), "预计收益率必须为数字");
                    }
                    CommUtils.Assert(percentValue >= 365.00 * (-1) / (valEndTime - valStartTime).TotalDays, "预计收益率过低,请重新填写");
                    investment.YieldDue = percentValue / 100;
                }

                var result = m_dbAdapter.Investment.UpdateInvestment(investment);
                return ActionUtils.Success(result);
            }));
        }
示例#8
0
        public ActionResult Index(string projectGuid, string paymentDay)
        {
            var projectLogicModel = new ProjectLogicModel(CurrentUserName, projectGuid);
            var project           = projectLogicModel.Instance;

            var datasetSchedule = projectLogicModel.DealSchedule.GetByPaymentDay(DateUtils.ParseDigitDate(paymentDay));

            CommUtils.AssertNotNull(datasetSchedule.Dataset.Instance,
                                    "Dataset数据加载失败,projectGuid=[" + projectGuid + "] paymentDay=[" + paymentDay + "]");
            var dataset = datasetSchedule.Dataset.Instance;

            var notes      = m_dbAdapter.Dataset.GetNotes(project.ProjectId);
            var cnabsNotes = projectLogicModel.Notes;
            var noteDict   = Toolkit.GetNoteDictionary(project, notes, cnabsNotes);

            var dealSchedule     = NancyUtils.GetDealSchedule(project.ProjectId);
            var noteDatas        = m_dbAdapter.Dataset.GetNoteDatas(dataset.DatasetId);
            var datasetViewModel = Toolkit.GetDatasetViewModel(dataset, dealSchedule.PaymentDates, noteDict, noteDatas);


            var             datasetFolder    = m_dbAdapter.Dataset.GetDatasetFolder(project, dataset.AsOfDate);
            VariablesHelper helper           = new VariablesHelper(datasetFolder);
            var             variables        = helper.GetVariablesByDate(dataset.PaymentDate.Value);
            var             rateResetRecords = InterestRateUtils.RateResetRecords(variables);

            //计算当期浮动利率
            datasetViewModel.NoteDatas.ForEach(x => x.CurrentCouponRate = InterestRateUtils.CalculateCurrentCouponRate(x.NoteInfo.CouponString, rateResetRecords));

            var viewModel = new CashflowDatasetViewModel();

            viewModel.Dataset     = datasetViewModel;
            viewModel.ProjectGuid = projectGuid;

            //添加今天之前所有已上传模型的支付日
            var nowDate = DateTime.Today;

            viewModel.ValidPaymentDays = datasetSchedule.SelectPaymentDates(
                x => x.PaymentDate <= nowDate &&
                x.Dataset != null && x.Dataset.Instance != null);

            if (project.CnabsDealId.HasValue)
            {
                viewModel.AllPaymentDays = m_dbAdapter.Model.GetPaymentDates(project.CnabsDealId.Value);
            }
            else
            {
                if (projectLogicModel.DealSchedule.Instanse != null)
                {
                    viewModel.AllPaymentDays = projectLogicModel.DealSchedule.Instanse.PaymentDates.ToList();
                }
                else
                {
                    viewModel.AllPaymentDays = new List <DateTime>();
                }
            }

            return(View(viewModel));
        }
示例#9
0
        /// <summary>
        /// Register price factors.
        /// </summary>
        public override void RegisterFactors(PriceFactorList factors, ErrorList errors)
        {
            var deal = (SwaptionDeal)Deal;

            // Get underlying cashflow lists
            SwaptionBaseValuation.SetCashflowLists(errors, deal, ref fFixedCashflowList, ref fFloatCashflowList);

            if (!IsVanillaSwaption())
            {
                Deal.AddToErrors(errors, ErrorLevel.Error, "The Hull White swaption valuation model is for vanilla swaptions only.");
            }

            // Register deal currency
            factors.RegisterInterface <IFxRate>(deal.Currency);

            // Register discount rate
            var    discountId           = InterestRateUtils.GetRateId(deal.Discount_Rate, deal.Currency);
            string discountRateCurrency = DiscountRate.Register(factors, discountId).GetCurrency();

            if (!string.IsNullOrEmpty(discountRateCurrency) && discountRateCurrency != deal.Currency)
            {
                errors.Add(ErrorLevel.Error, "Settlement currency (Currency) and currency of Discount_Rate must be the same");
            }

            // Register forecast rate
            var forecastId           = InterestRateUtils.GetRateId(deal.Forecast_Rate, discountId);
            var forecastRateCurrency = factors.RegisterInterface <IInterestRate>(forecastId).GetCurrency();

            if (forecastRateCurrency != deal.Currency)
            {
                errors.Add(ErrorLevel.Error, "Settlement currency (Currency) and currency of Forecast_Rate must be the same");
            }

            // Register the HW model parameters
            fModelParametersId = string.IsNullOrWhiteSpace(Model_Parameters) ? forecastId : Model_Parameters;

            factors.Register <HullWhite1FactorModelParameters>(fModelParametersId);

            // Check that floating cashflow list is standard enough to be valued by ValueSwap
            if (fFloatCashflowList == null || fFixedCashflowList == null)
            {
                errors.Add(ErrorLevel.Error, "Deal must contain exactly one floating and one fixed leg.");
            }
            else
            {
                var characteristics = fFloatCashflowList.Analyze(factors.BaseDate);
                if (!characteristics.HasSwaplet || characteristics.HasOptionlet ||
                    !characteristics.IsStandardPayoff || characteristics.HasCms || !characteristics.IsStandardLibor ||
                    fFloatCashflowList.Compounding_Method != CompoundingMethod.None || fFixedCashflowList.Compounding == YesNo.Yes)
                {
                    errors.Add(ErrorLevel.Error, "Underlying swap has non-standard floating cashflows.");
                }
            }
        }
示例#10
0
        /// <summary>
        /// Constructor.
        /// </summary>
        public CreditValuationParameters(DealCreditBase deal, CreditBaseValuation valuation, PriceFactorList factors, VectorScopedCache.Scope cache)
        {
            DF          = DiscountRate.Get(factors, InterestRateUtils.GetRateId(deal.Discount_Rate, deal.Currency));
            X           = factors.GetInterface <IFxRate>(deal.Currency);
            SP          = factors.GetInterface <ISurvivalProb>(string.IsNullOrEmpty(deal.Survival_Probability) ? deal.Name : deal.Survival_Probability);
            RR          = null;
            CR          = null;
            DefaultTime = null;
            Weights     = null;
            NamesDefaultedBeforeBaseDate = null;

            if (valuation.Respect_Default == YesNo.Yes)
            {
                List <string> names = new List <string>();
                if (deal.ProtectionReferenceType() == DealCreditBase.ReferenceType.Single_Name)
                {
                    names.Add(deal.Name);
                    Weights = new double[] { 1.0 };
                }
                else
                {
                    IndexCDSPool indexCds = factors.Get <IndexCDSPool>(deal.Name);
                    Weights = new double[indexCds.Names.Count];
                    for (int i = 0; i < indexCds.Names.Count; ++i)
                    {
                        names.Add(indexCds.Names[i].Name);
                        Weights[i] = indexCds.Names[i].Weight;
                    }
                }

                if (valuation.RequiresRecoveryOnDefault())
                {
                    RR = new RecoveryRate[names.Count];
                    for (int i = 0; i < names.Count; ++i)
                    {
                        RR[i] = factors.Get <RecoveryRate>(string.IsNullOrEmpty(deal.Recovery_Rate) ? names[i] : deal.Recovery_Rate);
                    }
                }

                CR = new CreditRating[names.Count];
                NamesDefaultedBeforeBaseDate = new bool[names.Count];
                DefaultTime = new Vector[names.Count];
                for (int i = 0; i < names.Count; ++i)
                {
                    DefaultTime[i] = cache.Get();
                    CR[i]          = factors.Get <CreditRating>(names[i]);
                    NamesDefaultedBeforeBaseDate[i] = CreditRating.DefaultedBeforeBaseDate(CR[i], factors.BaseDate);
                    CR[i].DefaultTime(DefaultTime[i]);
                }
            }
        }
示例#11
0
        /// <inheritdoc />
        public void PreValue(PriceFactorList factors)
        {
            var deal = (SwaptionDeal)Deal;

            var discountId = InterestRateUtils.GetRateId(deal.Discount_Rate, deal.Currency);
            var forecastId = InterestRateUtils.GetRateId(deal.Forecast_Rate, discountId);

            fModelParameters = factors.Get <HullWhite1FactorModelParameters>(fModelParametersId);

            fFxRate       = factors.GetInterface <IFxRate>(deal.Currency);
            fDiscountRate = DiscountRate.Get(factors, discountId);
            fForecastRate = factors.GetInterface <IInterestRate>(forecastId);

            fQuadrature = new Lazy <GaussHermiteNormalQuadrature>(() => new GaussHermiteNormalQuadrature(30));
        }
示例#12
0
        /// <summary>
        /// Register price factors.
        /// </summary>
        public override void RegisterFactors(PriceFactorList factors, ErrorList errors)
        {
            BondFuture deal = (BondFuture)Deal;

            base.RegisterFactors(factors, errors);

            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));
            }
        }
示例#13
0
        // -----------------------------------------------------------------------------
        // Description: Register price factors
        // -----------------------------------------------------------------------------
        public override void RegisterFactors(PriceFactorList factors, ErrorList errors)
        {
            factors.Register <DiscountRate>(InterestRateUtils.GetRateId(fCreditBaseDeal.Discount_Rate, fCreditBaseDeal.Currency));
            factors.RegisterInterface <IFxRate>(fCreditBaseDeal.Currency);
            factors.RegisterInterface <ISurvivalProb>(string.IsNullOrEmpty(fCreditBaseDeal.Survival_Probability) ? fCreditBaseDeal.Name : fCreditBaseDeal.Survival_Probability);

            if (Respect_Default == YesNo.Yes)
            {
                if (fCreditBaseDeal.ProtectionReferenceType() == DealCreditBase.ReferenceType.Single_Name)
                {
                    factors.Register <CreditRating>(fCreditBaseDeal.Name);
                    if (RequiresRecoveryOnDefault())
                    {
                        factors.Register <RecoveryRate>(string.IsNullOrEmpty(fCreditBaseDeal.Recovery_Rate) ? fCreditBaseDeal.Name : fCreditBaseDeal.Recovery_Rate);
                    }
                }
                else
                {
                    factors.Register <IndexCDSPool>(fCreditBaseDeal.Name);
                }
            }
        }
        /// <summary>
        /// Prepare for valuation anything that is dependent upon the scenario.
        /// </summary>
        public override void PreValue(PriceFactorList factors)
        {
            base.PreValue(factors);

            CFListBaseDeal <TCashflowList> deal = (CFListBaseDeal <TCashflowList>)fDeal;

            if (string.IsNullOrEmpty(fDeal.GetIssuer()))
            {
                return;
            }

            if (UseSurvivalProbability())
            {
                fSurvivalProb = factors.GetInterface <ISurvivalProb>(string.IsNullOrEmpty(deal.GetSurvivalProbability()) ? deal.GetIssuer() : deal.GetSurvivalProbability());
            }

            if (RespectDefault())
            {
                fRecoveryRate = factors.Get <RecoveryRate>(InterestRateUtils.GetRateId(deal.GetRecoveryRate(), deal.GetIssuer()));
                fCreditRating = factors.Get <CreditRating>(deal.GetIssuer());
            }
        }
        public ActionResult GetInvestments(string projectGuid, int?page, int?pageSize)
        {
            return(ActionUtils.Json(() =>
            {
                var project = m_dbAdapter.Project.GetProjectByGuid(projectGuid);
                var investments = m_dbAdapter.Investment.GetInvestmentsByProjectId(project.ProjectId);
                var investmentIds = investments.ConvertAll(x => x.Id).ToList();
                var investmentsOfPage = m_dbAdapter.Investment.GetInvestments(page ?? 1, pageSize ?? 10, investmentIds);
                var result = new
                {
                    Investments = investmentsOfPage.Items.ConvertAll(x => new
                    {
                        guid = x.Guid,
                        name = x.Name,
                        description = Toolkit.ToString(x.Description),
                        money = x.Money.ToString("n2"),
                        gains = (x.Gains.HasValue ? x.Gains.Value.ToString("n2") : "-"),
                        yield = (x.Yield.HasValue ? x.Yield.Value.ToString("P") : "-"),
                        yieldDue = (x.YieldDue.HasValue ? CommUtils.Percent(x.YieldDue.Value, 1) : "-"),
                        gainsDue = x.YieldDue.HasValue ? InterestRateUtils.CalculateGains(x.YieldDue.Value, x.Money, x.EndTime, x.StartTime).ToString("n2") : "-",
                        startTime = Toolkit.DateToString(x.StartTime),
                        endTime = Toolkit.DateToString(x.EndTime),
                        accountingTime = Toolkit.DateToString(x.AccountingTime),
                        status = x.Gains.HasValue ? "Finished" : "Running",
                        reminderInfo = m_dbAdapter.MessageReminding.GetResultByUid(x.Guid),
                    }).ToList(),
                    StatisticInfo = new
                    {
                        totalMoney = investments.Sum(x => x.Money).ToString("n2"),
                        totalGains = investments.Sum(x => x.Gains ?? 0).ToString("n2"),
                        totalCount = investments.Count.ToString("n0"),
                        totalFinished = investments.Sum(x => x.Gains.HasValue ? 1 : 0).ToString("n0"),
                        totalRunning = investments.Sum(x => x.Gains.HasValue ? 0 : 1).ToString("n0")
                    }
                };

                return ActionUtils.Success(result);
            }));
        }
        /// <summary>
        /// Register price factors.
        /// </summary>
        public override void RegisterFactors(PriceFactorList factors, ErrorList errors)
        {
            base.RegisterFactors(factors, errors);

            CFListBaseDeal <TCashflowList> deal = (CFListBaseDeal <TCashflowList>)fDeal;

            if (string.IsNullOrEmpty(fDeal.GetIssuer()))
            {
                return;
            }

            if (UseSurvivalProbability())
            {
                factors.RegisterInterface <ISurvivalProb>(string.IsNullOrEmpty(deal.GetSurvivalProbability()) ? deal.GetIssuer() : deal.GetSurvivalProbability());
            }

            if (RespectDefault())
            {
                factors.Register <RecoveryRate>(InterestRateUtils.GetRateId(deal.GetRecoveryRate(), deal.GetIssuer()));
                factors.Register <CreditRating>(deal.GetIssuer());
            }

            fSettlementOffsetHelper.ValidateHolidayCalendars(factors.CalendarData, errors);
        }
示例#17
0
        /// <summary>
        /// Validate the valuation models of the component deals.
        /// </summary>
        private void ValidateModels(ValuationList models, ErrorList errors)
        {
            const string Messsage = "{0} of underlying deals must be the same as {0} of {1}";

            // Get properties of Callable Structured Deal
            string discount = InterestRateUtils.GetRateId(fDeal.GetDiscountRate(), fDeal.Currency);
            string forecast = InterestRateUtils.GetRateId(fDeal.GetForecastRate(), discount);
            string issuer   = fDeal.GetIssuer();
            string recovery = InterestRateUtils.GetRateId(fDeal.GetRecoveryRate(), issuer);

            foreach (Valuation model in models)
            {
                if (model.Deal.fIgnore)
                {
                    continue;
                }
                else if (model.IsContainer())
                {
                    ValidateModels(model.fItems, errors);
                }
                else if (model.Deal is IRDealBase && model is ISingleDateValuation)
                {
                    IRDealBase underlyingDeal = (IRDealBase)model.Deal;

                    // Currency of underlying must match CSD
                    if (underlyingDeal.Currency != fDeal.Currency)
                    {
                        errors.Add(ErrorLevel.Error, string.Format(Messsage, "Currency", fDeal.GetType().Name));
                    }

                    // Discount_Rate and Forecast_Rate of underlying must either be left blank or match CSD
                    string underlyingDiscount = underlyingDeal.GetDiscountRate();
                    if (!string.IsNullOrEmpty(underlyingDiscount) && underlyingDiscount != discount)
                    {
                        errors.Add(ErrorLevel.Error, string.Format(Messsage, "Discount_Rate", fDeal.GetType().Name));
                    }

                    string underlyingForecast = underlyingDeal.GetForecastRate();
                    if (!string.IsNullOrEmpty(underlyingForecast) && underlyingForecast != forecast)
                    {
                        errors.Add(ErrorLevel.Error, string.Format(Messsage, "Forecast_Rate", fDeal.GetType().Name));
                    }

                    if (Use_Survival_Probability == YesNo.Yes && !string.IsNullOrEmpty(issuer))
                    {
                        // Issue and Recovery_Rate of underlying must either be left blank or match CSD
                        string underlyingIssuer = underlyingDeal.GetIssuer();
                        if (!string.IsNullOrEmpty(underlyingIssuer) && underlyingIssuer != issuer)
                        {
                            errors.Add(ErrorLevel.Error, string.Format(Messsage, "Issuer", fDeal.GetType().Name));
                        }
                    }

                    if (Respect_Default == YesNo.Yes && !string.IsNullOrEmpty(issuer))
                    {
                        string underlyingIssuer   = underlyingDeal.GetIssuer();
                        string underlyingRecovery = InterestRateUtils.GetRateId(underlyingDeal.GetRecoveryRate(), underlyingIssuer);
                        if (!string.IsNullOrEmpty(underlyingRecovery) && underlyingRecovery != recovery)
                        {
                            errors.Add(ErrorLevel.Error, string.Format(Messsage, "Recovery_Rate", fDeal.GetType().Name));
                        }
                    }
                }
                else
                {
                    // Underlying deal type must be IRDealBase and model must support ISingleDateValuation
                    errors.Add(ErrorLevel.Error, string.Format("{0} cannot be used in {1}", model.Deal.GetType().Name, fDeal.GetType().Name));
                }
            }
        }
示例#18
0
        protected override object MakeObjectInstance()
        {
            var logicModel = new ProjectLogicModel(m_userName, m_project);

            var schedule = logicModel.DealSchedule.Instanse;

            var firstNoteAccrualDates = schedule.NoteAccrualDates.First().Value;
            var firstNoteName         = schedule.NoteAccrualDates.First().Key;

            foreach (var key in schedule.NoteAccrualDates.Keys)
            {
                var noteAccrualDates = schedule.NoteAccrualDates[key];
                CommUtils.AssertEquals(firstNoteAccrualDates.Length, noteAccrualDates.Length,
                                       "检测到证券期数不一致,[{0}]={1},[{2}]={3}",
                                       firstNoteName, firstNoteAccrualDates.Length,
                                       key, noteAccrualDates.Length);

                for (int i = 0; i < firstNoteAccrualDates.Length; i++)
                {
                    CommUtils.Assert(firstNoteAccrualDates[i] == noteAccrualDates[i],
                                     "检测到第[{0}]期证券Accrual date不一致,[{1}]={2},[{3}]={4}",
                                     i + 1, firstNoteName, firstNoteAccrualDates[i].ToShortDateString(),
                                     key, noteAccrualDates[i].ToShortDateString());
                }
            }

            //从第N期开始模型数据时,getDealSchedule中不包含前几期的PaymentDate
            List <DateTime> paymentDates = schedule.PaymentDates.ToList();

            if (m_project.CnabsDealId.HasValue)
            {
                paymentDates = m_dbAdapter.Model.GetPaymentDates(m_project.CnabsDealId.Value);
            }

            var datasets    = m_dbAdapter.Dataset.GetDatasetByProjectId(m_project.ProjectId);
            var paymentDate = paymentDates.First(x => x == m_paymentDay);
            var sequence    = paymentDates.FindIndex(x => x == m_paymentDay);

            datasets = datasets.Where(x => x.PaymentDate.HasValue && x.PaymentDate.Value <= paymentDate).ToList();
            var findDatasets = datasets.Where(x => x.PaymentDate.HasValue && x.PaymentDate.Value == paymentDate).ToList();

            findDatasets.Sort((l, r) => l.AsOfDate.CompareTo(r.AsOfDate));
            CommUtils.Assert(findDatasets.Count >= 1, "找不到偿付期为 [{0}] 的数据模型", DateUtils.DateToString(paymentDate));
            var dataset   = findDatasets[0];
            var datasetId = dataset.DatasetId;

            var notes     = m_dbAdapter.Dataset.GetNotes(m_project.ProjectId);
            var noteDatas = m_dbAdapter.Dataset.GetNoteDatas(datasetId);

            //初始化note信息
            List <Note> cnabsNotes = new ProjectLogicModel(m_userName, m_project).Notes;


            var datasetFolder       = m_dbAdapter.Dataset.GetDatasetFolder(m_project, dataset.AsOfDate);
            var variablesCsv        = new VariablesHelper(datasetFolder);
            var futureVariablesPath = Path.Combine(datasetFolder, "FutureVariables.csv");
            var variables           = variablesCsv.GetVariablesByDate(dataset.PaymentDate.Value);
            var rateResetRecords    = InterestRateUtils.RateResetRecords(variables);

            var idrObj = new IncomeDistributionReport();

            idrObj.Sequence          = sequence + 1;
            idrObj.SequenceCN        = idrObj.Sequence.ToCnString();
            idrObj.Security          = new Dictionary <string, PaymentDetail>();
            idrObj.PriorSecurityList = new List <PaymentDetail>();
            idrObj.SubSecurityList   = new List <PaymentDetail>();
            idrObj.SecurityList      = new List <PaymentDetail>();
            idrObj.BeginAccrualDate  = sequence == 0 ? schedule.FirstAccrualDate : schedule.NoteAccrualDates.First().Value[sequence - 1];
            idrObj.EndAccrualDate    = schedule.NoteAccrualDates.First().Value[sequence];
            idrObj.AccrualDateSum    = (idrObj.EndAccrualDate - idrObj.BeginAccrualDate).Days;
            for (int i = 0; i < notes.Count; i++)
            {
                var note = notes[i];
                note.CouponString = InterestRateUtils.CalculateCurrentCouponRate(cnabsNotes[i].CouponString, rateResetRecords);

                var noteData = noteDatas.Single(x => x.NoteId == note.NoteId);

                CommUtils.Assert(noteData.HasValue, "兑付日为[{0}]的偿付期内,证券端现金流类型的工作未核对", paymentDate.ToShortDateString());

                idrObj.Security[note.ShortName] = GeneratePaymentDetail(note, noteData, idrObj.Security.Count + 1);

                if (note.IsEquity)
                {
                    idrObj.SubSecurityList.Add(GeneratePaymentDetail(note, noteData, idrObj.SubSecurityList.Count + 1));
                }
                else
                {
                    idrObj.PriorSecurityList.Add(GeneratePaymentDetail(note, noteData, idrObj.PriorSecurityList.Count + 1));
                }

                idrObj.SecurityList.Add(GeneratePaymentDetail(note, noteData, idrObj.SecurityList.Count(x => x.Money != 0) + 1));
            }

            Func <IEnumerable <PaymentDetail>, PaymentDetail> sum = (values) => new PaymentDetail
            {
                Residual         = values.Sum(x => x.Residual),
                Principal        = values.Sum(x => x.Principal),
                Interest         = values.Sum(x => x.Interest),
                Money            = values.Sum(x => x.Money),
                UnitCount        = values.Sum(x => x.UnitCount),
                SumPaymentAmount = values.Sum(x => x.SumPaymentAmount)
            };

            idrObj.Sum      = sum(idrObj.Security.Values);
            idrObj.SumPrior = sum(idrObj.Security.Values.Where(x => !x.IsEquity));
            idrObj.SumSub   = sum(idrObj.Security.Values.Where(x => x.IsEquity));

            GeneratePercentTable(idrObj, datasets, notes, schedule.PaymentDates);

            idrObj.RepayDetail                       = GenerateRepayDetail(idrObj.SecurityList, x => x.NameCN);
            idrObj.RepayDetailWithHyphen             = GenerateRepayDetail(idrObj.SecurityList, x => x.NameCNHyphen);
            idrObj.RepayDetailWithHyphenByJinTai     = GenerateRepayDetailByJinTai(idrObj.SecurityList, x => x.NameCNHyphen);
            idrObj.RepayPrincipalDetail              = GenerateRepayPrincipalDetail(idrObj.SecurityList);
            idrObj.DenominationDetail                = GenerateDenominationDetail(idrObj.SecurityList);
            idrObj.EquityRegisterDetail              = GenerateEquityRegisterDetail(idrObj.SecurityList, dataset.PaymentDate.Value);
            idrObj.EquityRegisterDetailByJinTai      = GenerateEquityRegisterDetailByJinTai(idrObj.SecurityList, dataset.PaymentDate.Value);
            idrObj.EquityRegisterDetailByZhongGang   = GenerateEquityRegisterDetailByZhongGang(idrObj.SecurityList, dataset.PaymentDate.Value);
            idrObj.EquityRegisterDetailByYingBinGuan = GenerateEquityRegisterDetailByYingBinGuan(idrObj.SecurityList, dataset.PaymentDate.Value);

            idrObj.T = dataset.PaymentDate.Value;

            if (paymentDates.First() == idrObj.T)
            {
                idrObj.PreviousT = schedule.ClosingDate;
            }
            else
            {
                var previousIndex = paymentDates.IndexOf(idrObj.T) - 1;
                idrObj.PreviousT = paymentDates[previousIndex];
            }

            idrObj.DurationDayCount = (idrObj.T - idrObj.PreviousT).Days;

            var t_1 = dataset.PaymentDate.Value.AddDays(-1);

            while (!CalendarCache.IsTradingDay(t_1))
            {
                t_1 = t_1.AddDays(-1);
            }
            idrObj.T_1         = t_1;
            idrObj.Date        = DateTime.Today;
            idrObj.TaskEndTime = m_timeStamp;
            return(idrObj);
        }
示例#19
0
        /// <summary>
        /// Vector valuation function.
        /// </summary>
        public override void Value(ValuationResults valuationResults, PriceFactorList factors, BaseTimeGrid baseTimes)
        {
            PreValue(factors);

            TimeGridIterator         tgi         = new TimeGridIterator(fT);
            PVProfiles               result      = valuationResults.Profile;
            CashAccumulators         accumulator = valuationResults.Cash;
            DealCreditLinkedNoteBase deal        = (DealCreditLinkedNoteBase)fDeal;

            ISurvivalProb SP = GetSurvivalProbability(factors);
            RecoveryRate  RR = GetRecoveryRate(factors);
            CreditRating  CR = GetCreditRating(factors);

            double tEffective    = CalcUtils.DaysToYears(deal.Effective_Date - factors.BaseDate);
            double scale         = (deal.Buy_Sell == BuySell.Buy) ? +deal.Notional_Amount : -deal.Notional_Amount;
            double purchasePrice = Percentage.PercentagePoint * deal.Price;
            double couponRate    = (deal.Coupon_Type == InterestRateType.Fixed) ? Percentage.PercentagePoint * deal.Coupon_Rate : 0.0;
            double couponSpread  = (deal.Coupon_Type == InterestRateType.Fixed) ? 0.0 : BasisPoint.BasisPointValue * deal.Coupon_Spread;
            double indexTenor    = (deal.Index_Tenor > 0.0) ? deal.Index_Tenor : deal.Coupon_Interval;

            using (var cache = Vector.Cache(factors.NumScenarios))
            {
                bool[] hasDefaulted       = (Respect_Default == YesNo.Yes) ? new bool[factors.NumScenarios] : null;
                Vector defaultTime        = (Respect_Default == YesNo.Yes) ? cache.Get() : null;
                Vector historicalRecovery = (Respect_Default == YesNo.Yes) ? cache.GetClear() : null;

                if (hasDefaulted != null && CR != null)
                {
                    DefaultTime(defaultTime, CR);
                }

                Vector npv      = cache.Get();
                Vector cash     = cache.Get();
                Vector pStart   = cache.Get();
                Vector pEnd     = cache.Get();
                Vector amount   = cache.Get();
                Vector recovery = cache.Get();
                Vector dfLast   = cache.Get();
                Vector df       = cache.Get();

                cash.Clear();
                var defaultedBeforeTheBaseDate = Respect_Default == YesNo.Yes &&
                                                 CreditRating.DefaultedBeforeBaseDate(CR, factors.BaseDate);
                while (tgi.Next())
                {
                    if (defaultedBeforeTheBaseDate)
                    {
                        npv.Clear();
                        result.AppendVector(tgi.Date, npv);
                        break;
                    }

                    if (!deal.Principal_Guaranteed && Respect_Default == YesNo.Yes)
                    {
                        RealizedRecoveryRate(recovery, RR, tgi.T);
                    }

                    // Assume defaults are rare and start by valuing under all scenarios without realized defaults

                    // Value of principal repayment
                    SurvivalProbability(pEnd, factors, SP, tgi.T, fT.fLast);
                    fDiscountRate.GetValue(dfLast, tgi.T, fT.fLast);
                    if (deal.Principal_Guaranteed)
                    {
                        npv.Assign(dfLast);
                    }
                    else
                    {
                        npv.Assign(dfLast * pEnd);
                    }
                    if (accumulator != null && tgi.T == fT.fLast)
                    {
                        cash.Assign(npv);
                    }

                    // Value of coupons
                    for (int i = PayDates.Count - 1; i >= 0 && tgi.Date <= PayDates[i]; --i)
                    {
                        double tPay      = CalcUtils.DaysToYears(PayDates[i] - factors.BaseDate);
                        double tReset    = CalcUtils.DaysToYears(ResetDates[i] - factors.BaseDate);
                        double tPrevious = Math.Max(tgi.T, tReset);
                        SurvivalProbability(pStart, factors, SP, tgi.T, tPrevious);

                        if (deal.Coupon_Type == InterestRateType.Floating)
                        {
                            // Forecast a coupon, add the spread
                            InterestRateUtils.LiborRate(amount, fForecastRate, tgi.T, tReset, tReset, tReset + indexTenor, deal.Index_Day_Count);
                            amount.Add(couponSpread);
                            amount.MultiplyBy(Accruals[i]);
                        }
                        else
                        {
                            // Fixed coupon
                            amount.Assign(couponRate * Accruals[i]);
                        }

                        // The value of the coupon if no default
                        npv.Add(amount * fDiscountRate.Get(tgi.T, tPay) * pEnd);
                        if (accumulator != null && tgi.T == tPay)
                        {
                            cash.Assign(amount);
                        }

                        // The recovery value on default - assume guaranteed principal paid at end, recovery paid immediately
                        if (!deal.Principal_Guaranteed)
                        {
                            npv.Add(fDiscountRate.Get(tgi.T, 0.5 * (tPay + tPrevious)) * (pStart - pEnd) * PricingRecoveryRate(SP));
                        }

                        pEnd.DestructiveAssign(pStart);
                    }

                    // Now check for realized default scenario by scenario, overwriting NPV and cash as appropriate
                    if (Respect_Default == YesNo.Yes && defaultTime != null)
                    {
                        if (tgi.T < tEffective)
                        {
                            fDiscountRate.GetValue(df, tgi.T, tEffective);
                        }

                        for (int i = 0; i < npv.Count; ++i)
                        {
                            if (defaultTime[i] > tgi.T)
                            {
                                continue;
                            }

                            if (deal.Principal_Guaranteed)
                            {
                                npv[i] = dfLast[i];   // full principal paid at maturity
                            }
                            else
                            {
                                if (!hasDefaulted[i])
                                {
                                    historicalRecovery[i] = recovery[i];   // record the historical recovery rate
                                }
                                if (tgi.T < tEffective)
                                {
                                    npv[i] = df[i] * historicalRecovery[i];   // The discounted recovery value of the principal will be paid out on the effective date
                                }
                                else if (tgi.T == tEffective || !hasDefaulted[i])
                                {
                                    npv[i] = historicalRecovery[i];           // The full recovery amount is paid out
                                }
                                else
                                {
                                    npv[i] = 0.0;                             // default is in the past but we are after effective date; settlement has already occurred.
                                }
                            }

                            hasDefaulted[i] = true;
                        }
                    }

                    // Value of purchase price
                    if (tgi.T < tEffective)
                    {
                        npv.Add(-purchasePrice * fDiscountRate.Get(tgi.T, tEffective));
                    }
                    else if (tgi.T == tEffective)
                    {
                        npv.Add(-purchasePrice);
                        if (accumulator != null)
                        {
                            cash.Add(-purchasePrice);
                        }
                    }

                    result.AppendVector(tgi.Date, scale * npv * fFxRate.Get(tgi.T));
                    if (accumulator != null)
                    {
                        accumulator.Accumulate(fFxRate, tgi.Date, scale * cash);
                    }
                }

                // After maturity
                result.Complete(fT);
            }
        }
示例#20
0
        /// <summary>
        /// Value the deal from given base date, price factors and time grid.
        /// </summary>
        public void Value(PVProfiles pvResults, CashAccumulators cashResults, double baseDate, IInterestRate discountRate, IInterestRate forecastRate1, IInterestRate forecastRate2, IFxRate fxRate, TimeGrid timeGrid, int numScenarios)
        {
            var tgi  = new TimeGridIterator(timeGrid);
            var deal = (FloatingInterestCashflowInterpolatedDeal)Deal;

            bool   hasRate1          = deal.HasRate1();
            bool   hasRate2          = deal.HasRate2();
            double scale             = deal.Buy_Sell == BuySell.Buy ? +deal.Principal : -deal.Principal;
            double tPay              = CalcUtils.DaysToYears(fPaymentDate - baseDate);
            double tReset            = CalcUtils.DaysToYears(deal.Reset_Date - baseDate);
            double tRateStart        = CalcUtils.DaysToYears(deal.Rate_Start_Date - baseDate);
            double tRateEnd1         = hasRate1 ? CalcUtils.DaysToYears(fRate1EndDate - baseDate) : 0.0;
            double tRateEnd2         = hasRate2 ? CalcUtils.DaysToYears(fRate2EndDate - baseDate) : 0.0;
            double tRateEnd12        = tRateEnd2 - tRateEnd1;                                                                    // Time from rate 1 end date to rate 2 end date.
            double tAccrualEnd       = CalcUtils.DaysToYears(deal.Accrual_End_Date - baseDate);
            double interpCoefficient = Math.Abs(tRateEnd12) >= CalcUtils.MinTime ? (tAccrualEnd - tRateEnd1) / tRateEnd12 : 0.0; // Coefficient used to calculate interpolated rate.

            VectorEngine.For(tgi, () =>
            {
                using (var cache = Vector.Cache(numScenarios))
                {
                    Vector pv = cache.Get();

                    if (tgi.Date <= fPaymentDate && fPaymentDate > fCutoffDate)
                    {
                        Vector interpRate = cache.GetClear();
                        Vector rate1      = cache.GetClear();
                        Vector rate2      = cache.GetClear();

                        if (hasRate1)
                        {
                            if (fKnownResetRate1.HasValue)
                            {
                                rate1.Assign(fKnownResetRate1.Value);
                            }
                            else
                            {
                                InterestRateUtils.LiborRate(rate1, forecastRate1, tgi.T, tReset, tRateStart, tRateEnd1, fRate1YearFraction);
                            }
                        }

                        if (hasRate2)
                        {
                            if (fKnownResetRate2.HasValue)
                            {
                                rate2.Assign(fKnownResetRate2.Value);
                            }
                            else
                            {
                                InterestRateUtils.LiborRate(rate2, forecastRate2, tgi.T, tReset, tRateStart, tRateEnd2, fRate2YearFraction);
                            }
                        }

                        if (hasRate1 && hasRate2)
                        {
                            if (Math.Abs(tRateEnd12) >= CalcUtils.MinTime)
                            {
                                interpRate.Assign(rate1 + interpCoefficient * (rate2 - rate1));
                            }
                            else
                            {
                                interpRate.Assign(0.5 * rate1 + 0.5 * rate2);
                            }
                        }
                        else
                        {
                            interpRate.Assign(hasRate1 ? rate1 : rate2);
                        }

                        // Round the calculated rate, regardless whether the valuation date is before or after the reset date.
                        CFFloatingInterestList.RoundRateTo(deal.Interpolated_Rate_Rounding, interpRate);

                        pv.Assign(scale * (interpRate + deal.Margin) * fAccrualYearFraction);

                        CFFixedList.RoundCashflow(pv, Cashflow_Rounding);

                        if (tgi.Date < fPaymentDate)
                        {
                            pv.MultiplyBy(discountRate.Get(tgi.T, tPay));
                        }
                        else if (tgi.Date == fPaymentDate)
                        {
                            cashResults.Accumulate(fxRate, fPaymentDate, pv);
                        }
                    }
                    else
                    {
                        pv.Clear();
                    }

                    pvResults.AppendVector(tgi.Date, pv * fxRate.Get(tgi.T));
                }
            });

            // After maturity
            pvResults.Complete(timeGrid);
        }
示例#21
0
 protected CDOValuationParameters(DealCDO deal, PriceFactorList factors)
 {
     DF = DiscountRate.Get(factors, InterestRateUtils.GetRateId(deal.Discount_Rate, deal.Currency));
     X  = factors.GetInterface <IFxRate>(deal.Currency);
 }
示例#22
0
        /// <summary>
        /// Register required price factors.
        /// </summary>
        public override void RegisterFactors(PriceFactorList factors, ErrorList errors)
        {
            var deal = (CalendarSpreadOption)Deal;

            // Register forward price factor - using a reference price.
            var referencePrice = factors.RegisterInterface <IReferencePrice>(deal.Reference_Type);

            // Register volatility price factor based on an explicit user-defined property.
            // Default to Reference Type if Reference Vol Type is not set.
            if (string.IsNullOrEmpty(deal.Reference_Vol_Type))
            {
                factors.Register <ReferenceVol>(deal.Reference_Type);
            }
            else
            {
                factors.Register <ReferenceVol>(deal.Reference_Vol_Type);
            }

            // Register FX rate price factors.
            factors.RegisterInterface <IFxRate>(deal.Currency);
            factors.RegisterInterface <IFxRate>(deal.DealCurrency());
            factors.RegisterInterface <IFxRate>(factors.BaseCcyCode);
            factors.RegisterInterface <IFxRate>(referencePrice.DomesticCurrency());

            // Register correlation price factor.
            factors.Register <ForwardPriceCorrelations>(referencePrice.GetForwardPrice());

            // Register forward price sample price factor for reference prices.
            var sample = factors.Register <ForwardPriceSample>(deal.Sampling_Type);

            if (!string.IsNullOrWhiteSpace(sample.Sampling_Convention))
            {
                sample.Prepare();

                // Validate period 1.
                IEnumerable <ContractPeriod> contractPeriods = deal.GetContractPeriods(deal.Period_Start_1, deal.Period_End_1);
                sample.ValidateRange(contractPeriods, "Set 1 of sample dates", deal, errors);

                // Validate period 2.
                contractPeriods = deal.GetContractPeriods(deal.Period_Start_2, deal.Period_End_2);
                sample.ValidateRange(contractPeriods, "Set 2 of sample dates", deal, errors);
            }

            // Register interest rate price factor to get discount factor.
            factors.RegisterInterface <IInterestRate>(deal.Currency);

            // Register interest rate price factor for discount rate currency.
            if (!string.IsNullOrEmpty(deal.Discount_Rate))
            {
                string discountRateCurrency = factors.RegisterInterface <IInterestRate>(InterestRateUtils.GetRateId(deal.Discount_Rate, deal.Currency)).GetCurrency();
                if (!string.IsNullOrEmpty(discountRateCurrency) && discountRateCurrency != deal.Currency)
                {
                    errors.Add(ErrorLevel.Error, "Currency and currency of Discount_Rate must be the same");
                }
            }
        }
示例#23
0
        /// <summary>
        /// Value a caplet or floorlet under the 1 factor Hull-White model.
        /// </summary>
        public override void Value(Vector pv, Vector cash, double baseDate, double valueDate, ISACCRResult saccrResult,
                                   IIntraValuationDiagnosticsWriter intraValuationDiagnosticsWriter)
        {
            int count = fCashflows.Count();

            bool forecastIsDiscount = ReferenceEquals(fForecastRate, fDiscountRate);

            // time of dfStart and dfEnd
            double tDfStart = double.NegativeInfinity;
            double tDfEnd   = double.NegativeInfinity;

            using (var cache = Vector.CacheLike(pv))
            {
                // Shared between loops
                Vector dfStart = cache.Get();
                Vector dfEnd   = cache.Get();

                VectorEngine.For(0, count, LoopDirection.Backwards, i =>
                {
                    using (var innerCache = Vector.CacheLike(pv))
                    {
                        CFFloatingInterest cashflow = fCashflows[i];

                        if (cashflow.Payment_Date < valueDate || cashflow.Payment_Date <= fCutoffDate)
                        {
                            return(LoopAction.Break);
                        }

                        Vector rate   = innerCache.Get();
                        Vector dfPay  = innerCache.Get();
                        Vector stdDev = innerCache.GetClear();
                        Vector amount = innerCache.GetClear();

                        GeneralCashflowProperties properties = fCashflows.GetCashflowProperties(i);

                        double tPay    = CalcUtils.DaysToYears(cashflow.Payment_Date - baseDate);
                        bool haveDfPay = false;
                        if (forecastIsDiscount && tPay == tDfStart)
                        {
                            dfPay.Assign(dfStart);
                            haveDfPay = true;
                        }

                        using (IntraValuationDiagnosticsHelper.StartCashflow(intraValuationDiagnosticsWriter))
                            using (var volatilitiesAtDateStore = IntraValuationDiagnosticsHelper.CreateVolatilitiesAtDateStore(intraValuationDiagnosticsWriter, pv.Count))
                            {
                                cashflow.AddPropertiesToIntraValuationDiagnostics(intraValuationDiagnosticsWriter);

                                // Standard Libor implies single reset.
                                var reset = cashflow.Resets.Single();

                                if (reset.IsKnown(baseDate))
                                {
                                    rate.Assign(reset.Known_Rate);
                                }
                                else
                                {
                                    double tValue = CalcUtils.DaysToYears(valueDate - baseDate);
                                    double tReset = CalcUtils.DaysToYears(reset.Reset_Date - baseDate);
                                    double tStart = CalcUtils.DaysToYears(reset.Rate_Start_Date - baseDate);
                                    double tEnd   = CalcUtils.DaysToYears(reset.Rate_End_Date - baseDate);

                                    // Reset is a historical or forward Libor rate.
                                    InterestRateUtils.LiborRate(rate, fForecastRate, tValue, tReset, tStart, tEnd, reset.Rate_Year_Fraction,
                                                                dfStart, ref tDfStart, dfEnd, ref tDfEnd);

                                    if (tReset > tValue)
                                    {
                                        GetStandardDeviation(stdDev, tValue, tReset, tStart, tEnd);
                                        volatilitiesAtDateStore.Add(valueDate, reset.Reset_Date, stdDev);
                                    }
                                }

                                if (!haveDfPay && forecastIsDiscount && tPay == tDfEnd)
                                {
                                    dfPay.Assign(dfEnd);
                                    haveDfPay = true;
                                }

                                // Add swaplet value
                                amount.AddProduct(properties.Swap_Multiplier, rate);

                                double tau = reset.Rate_Year_Fraction;
                                rate.Assign(1.0 + rate * tau);

                                // Add cap and floor option values.
                                AddOptionValue(amount, OptionType.Call, rate, properties.Cap_Strike, stdDev, tau, properties.Cap_Multiplier);
                                AddOptionValue(amount, OptionType.Put, rate, properties.Floor_Strike, stdDev, tau, properties.Floor_Multiplier);

                                amount.Assign(fBuySellSign * (cashflow.Fixed_Amount + cashflow.Notional * (amount + cashflow.Margin) * cashflow.Accrual_Year_Fraction));

                                IntraValuationDiagnosticsHelper.AddImpliedVolatilities(intraValuationDiagnosticsWriter, volatilitiesAtDateStore);
                                CFFixedList.RoundCashflow(amount, Cashflow_Rounding);
                                CFFixedList.UpdatePvAndCash(cashflow, baseDate, valueDate, haveDfPay ? null : fDiscountRate, null, amount,
                                                            dfPay, pv, cash, intraValuationDiagnosticsWriter);
                            }
                    }

                    return(LoopAction.Continue);
                });
            }
        }