Пример #1
0
        /// <summary>
        /// Calculate a valuation profile for the deal for the current scenario.
        /// </summary>
        public override void Value(ValuationResults valuationResults, PriceFactorList factors, BaseTimeGrid baseTimes)
        {
            PreValue(factors);

            var deal = (CFListBaseDeal <TCashflowList>)fDeal;

            double baseDate = factors.BaseDate;

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

            double endDate = deal.EndDate();

            using (IntraValuationDiagnosticsHelper.StartDeal(fIntraValuationDiagnosticsWriter, fDeal))
            {
                using (var outerCache = Vector.Cache(factors.NumScenarios))
                {
                    Vector defaultDate = fCreditRating != null?outerCache.Get(CalcUtils.DateTimeMaxValueAsDouble) : null;

                    var  defaultedBeforeBaseDate = CreditRating.DefaultedBeforeBaseDate(fCreditRating, baseDate);
                    bool collectCash             = ValueOnCashflowDates();

                    var saccrResult = SACCRResultFactory.Create(valuationResults, deal.GetDealReferenceProvider().DealReference,
                                                                () => new SACCROptionResult(factors.NumScenarios));

                    VectorEngine.For(tgi, () =>
                    {
                        using (var cache = Vector.Cache(factors.NumScenarios))
                        {
                            Vector pv   = cache.GetClear();
                            Vector cash = collectCash ? cache.GetClear() : null;

                            if (!defaultedBeforeBaseDate)
                            {
                                using (IntraValuationDiagnosticsHelper.StartCashflowsOnDate(fIntraValuationDiagnosticsWriter, tgi.Date))
                                {
                                    using (IntraValuationDiagnosticsHelper.StartCashflows(fIntraValuationDiagnosticsWriter, fFxRate, tgi.T, deal))
                                    {
                                        Value(pv, cash, baseDate, tgi.Date, saccrResult, fIntraValuationDiagnosticsWriter);
                                        IntraValuationDiagnosticsHelper.AddCashflowsPV(fIntraValuationDiagnosticsWriter, pv);
                                    }
                                }

                                if (fCreditRating != null)
                                {
                                    UpdateDefaultDate(fCreditRating, tgi.Date, tgi.T, defaultDate);
                                    GetDefaultValue(baseDate, tgi.Date, defaultDate, fRecoveryRate, pv, cash);
                                }
                            }

                            result.AppendVector(tgi.Date, pv * fFxRate.Get(tgi.T));

                            if (!cashAccumulators.Ignore && cash != null)
                            {
                                // Realise all value as cash on deal end date
                                if (tgi.Date == endDate)
                                {
                                    cash.Assign(pv);
                                }

                                cashAccumulators.Accumulate(fFxRate, tgi.Date, cash);
                            }
                        }
                    });

                    if (!cashAccumulators.Ignore && !collectCash)
                    {
                        CollectCashflows(cashAccumulators, baseDate, fT.fHorizon);

                        // Consolidate and net in order to avoid getting Net incoming and outgoing cashflows with the same payment date,
                        // e.g. for compounding swaps with both positive and negative rates.
                        cashAccumulators.ConsolidateAndNet(fCurrency, factors);
                    }

                    result.Complete(fT);
                }
            }
        }
        /// <summary>
        /// Calculate valuation profiles.
        /// </summary>
        public override void Value(ValuationResults valuationResults, PriceFactorList factors, BaseTimeGrid baseTimes)
        {
            PreValue(factors);

            var    result          = valuationResults.Profile;
            var    cashAccumulator = valuationResults.Cash;
            var    accruedResults  = valuationResults.Results <AccruedInterest>();
            var    deal            = (IInflationCashflowListDeal)Deal;
            double sign            = deal.Buy_Sell == BuySell.Buy ? 1.0 : -1.0;
            var    cashflows       = deal.GetCashflows();
            var    calendar        = deal.GetHolidayCalendar();
            double baseDate        = factors.BaseDate;
            var    tgi             = new TimeGridIterator(fT);

            CalculateMetrics(valuationResults, factors, deal);

            using (IntraValuationDiagnosticsHelper.StartDeal(fIntraValuationDiagnosticsWriter, fDeal))
            {
                using (var cache = Vector.Cache(factors.NumScenarios))
                {
                    Vector defaultDate = null;

                    if (!fIsDefaultNever)
                    {
                        defaultDate = fCreditRating != null?cache.Get(CalcUtils.DateTimeMaxValueAsDouble) : null;
                    }

                    Vector pv              = cache.GetClear();
                    Vector cash            = cashAccumulator.Ignore ? null : cache.Get();
                    Vector accruedInterest = cache.GetClear();

                    VectorEngine.For(tgi, () =>
                    {
                        if (!fIsDefaultNever && CreditRating.DefaultedBeforeBaseDate(fCreditRating, baseDate))
                        {
                            result.AppendVector(tgi.Date, pv);
                            return(LoopAction.Break);
                        }

                        using (IntraValuationDiagnosticsHelper.StartCashflowsOnDate(fIntraValuationDiagnosticsWriter, tgi.Date))
                        {
                            using (IntraValuationDiagnosticsHelper.StartCashflows(fIntraValuationDiagnosticsWriter, fFxRate, tgi.T, fDeal))
                            {
                                cashflows.Value(pv, cash, baseDate, tgi.Date, deal.Settlement_Date, fInflationRate, fIndexVolatility,
                                                fDiscountRate, fRepoRate, fSurvivalProb, sign, fIntraValuationDiagnosticsWriter);
                                IntraValuationDiagnosticsHelper.AddCashflowsPV(fIntraValuationDiagnosticsWriter, pv);

                                if (fRecoveryCashflowList != null && fRecoveryCashflowList.Items.Count > 0)
                                {
                                    fRecoveryCashflowList.Value(pv, cash, baseDate, tgi.Date, deal.Settlement_Date, fDiscountRate, fRepoRate, fInflationRate, fSurvivalProb, sign);
                                }

                                // Temporary fix up to avoid calculating default when we know the model doesn't support default
                                if (!fIsDefaultNever)
                                {
                                    UpdateDefaultDate(fCreditRating, tgi.Date, tgi.T, defaultDate);
                                    GetDefaultValue(baseDate, tgi.Date, defaultDate, fInflationRate, fIndexVolatility, fRepoRate, pv, cash);
                                }

                                result.AppendVector(tgi.Date, fFxRate.Get(tgi.T) * pv);

                                if (cash != null)
                                {
                                    cashAccumulator.Accumulate(fFxRate, tgi.Date, cash);
                                }

                                if (accruedResults != null)
                                {
                                    cashflows.CalculateAccrual(accruedInterest, baseDate, tgi.Date, accruedResults.AccrueFromToday, calendar, fInflationRate, fIndexVolatility, sign);
                                    accruedResults.SetValue(tgi.Date, accruedInterest);
                                }
                                else if (fIntraValuationDiagnosticsWriter.Level > IntraValuationDiagnosticsLevel.None)
                                {
                                    cashflows.CalculateAccrual(accruedInterest, baseDate, tgi.Date, false, calendar, fInflationRate, fIndexVolatility, sign);
                                }

                                IntraValuationDiagnosticsHelper.AddCashflowsAccruedInterest(fIntraValuationDiagnosticsWriter, accruedInterest);
                            }
                        }

                        return(LoopAction.Continue);
                    });

                    // On investment horizon or a bond forward's Settlement Date, the deal value is liquidated as cash.
                    double endDate = Deal.EndDate();
                    if (cash != null && endDate <= fT.fHorizon)
                    {
                        // If endDate on a payment date, cashflow has already been accummulated (as cash), otherwise is 0.
                        // Value liquidated is the value of the pv remaining after accummulating the cashflow.
                        cash.AssignDifference(pv, cash);
                        cashAccumulator.Accumulate(fFxRate, endDate, cash);
                    }
                }

                result.Complete(fT);
            }
        }