Пример #1
0
        /// <summary>
        /// Output Intra-Valuation Diagnostics (Base correlation at Attachment and Detachment)
        /// </summary>
        public override void AddIntraValuationDiagnostics(IIntraValuationDiagnosticsWriter intraValuationDiagnosticsWriter,
                                                          CDOValuationParameters parameters, Vector adjustedAttachment, Vector adjustedDetachment, Vector remainingPool, double valueTime, double tPay)
        {
            if (intraValuationDiagnosticsWriter.Level == IntraValuationDiagnosticsLevel.None)
            {
                return;
            }

            using (var cache = Vector.CacheLike(adjustedAttachment))
            {
                var    paramsCDO     = (CDOBottomUpValuationParameters)parameters;
                Vector rhoAttachment = cache.Get();
                Vector rhoDetachment = cache.Get();

                paramsCDO.IndexCDO.GetBaseCorrelation(rhoAttachment, adjustedAttachment, remainingPool, valueTime, tPay);
                paramsCDO.IndexCDO.GetBaseCorrelation(rhoDetachment, adjustedDetachment, remainingPool, valueTime, tPay);

                IntraValuationDiagnosticsHelper.AddBaseCorrelation(intraValuationDiagnosticsWriter, rhoAttachment, rhoDetachment);
            }
        }
Пример #2
0
 /// <summary>
 /// Output Intra-Valuation Diagnostics
 /// </summary>
 public virtual void AddIntraValuationDiagnostics(IIntraValuationDiagnosticsWriter intraValuationDiagnosticsWriter, CDOValuationParameters parameters,
                                                  Vector adjustedAttachment, Vector adjustedDetachment, Vector remainingPool, double valueTime, double tPay)
 {
 }
Пример #3
0
        /// <summary>
        /// Valuation method.
        /// </summary>
        public override void Value(ValuationResults valuationResults, PriceFactorList factors, BaseTimeGrid baseTimes)
        {
            CDOValuationParameters parameters = GetValuationParameters(factors);

            double scale       = (fDeal.Buy_Sell == BuySell.Buy) ? +fDeal.Principal : -fDeal.Principal;
            double trancheSize = fDeal.Detachment - fDeal.Attachment;

            if (trancheSize < CalcUtils.TINY)
            {
                return;
            }

            double tUpfront = CalcUtils.DaysToYears(fDeal.Upfront_Date - factors.BaseDate);

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

            using (IntraValuationDiagnosticsHelper.StartDeal(fIntraValuationDiagnosticsWriter, Deal))
            {
                VectorEngine.For(tgi, () =>
                {
                    using (var cache = Vector.Cache(factors.NumScenarios))
                    {
                        Vector npv = cache.Get();
                        Vector expectedWritedownPremiumNotional = cache.Get();
                        Vector expectedLoss          = cache.Get();
                        Vector expectedRecovery      = cache.Get();
                        Vector discountFactor        = cache.Get();
                        Vector realizedIndexLoss     = cache.Get();
                        Vector realizedIndexRecovery = cache.Get();
                        Vector adjustedAttachment    = cache.Get();
                        Vector adjustedDetachment    = cache.Get();
                        Vector trancheRemainder      = cache.Get();

                        // Handle upfront payment
                        if (fDeal.Upfront_Date >= tgi.Date)
                        {
                            npv.Assign(scale * parameters.DF.Get(tgi.T, tUpfront) * fDeal.Upfront_Amount);
                        }
                        else
                        {
                            npv.Clear();
                        }

                        // reinitialise running variables
                        expectedWritedownPremiumNotional.Clear();
                        expectedLoss.Clear();
                        expectedRecovery.Clear();
                        discountFactor.Assign(parameters.DF.Get(tgi.T, tgi.T));

                        if (accumulator != null && tgi.Date == fDeal.Upfront_Date)
                        {
                            accumulator.Accumulate(parameters.X, tgi.Date, fDeal.Upfront_Amount);
                        }

                        // Check for realized loss and recovery and adjust the attachment and detachment accordingly
                        parameters.RealizedLoss(realizedIndexLoss, realizedIndexRecovery, tgi.T, fDeal.Payoff_Is_Digital == YesNo.Yes, fDeal.Digital_Payoff_Percentage);

                        adjustedDetachment.Assign(VectorMath.Max(0.0, VectorMath.Min(1.0 - realizedIndexRecovery, fDeal.Detachment) - realizedIndexLoss));
                        adjustedAttachment.Assign(VectorMath.Max(0.0, VectorMath.Min(1.0 - realizedIndexRecovery, fDeal.Attachment) - realizedIndexLoss));

                        trancheRemainder.Assign((adjustedDetachment - adjustedAttachment) / trancheSize);

                        if (adjustedDetachment.MaxElement() > CalcUtils.TINY)
                        {
                            // Diagnostics
                            double sumDefaultAccrual = 0;
                            double sumPVPremium      = 0;
                            double sumPVProtection   = 0;

                            bool needDiagnostics = tgi.T == 0.0 && fIntraValuationDiagnosticsWriter.Level > IntraValuationDiagnosticsLevel.None;

                            using (needDiagnostics ? IntraValuationDiagnosticsHelper.StartCDO(fIntraValuationDiagnosticsWriter, tgi.Date, fDeal.Principal) : null)
                            {
                                // Value future coupon periods
                                VectorEngine.For(0, PayDates.Count, i =>
                                {
                                    if (PayDates[i] < tgi.Date)
                                    {
                                        return(LoopAction.Continue);
                                    }

                                    double tPay = CalcUtils.DaysToYears(PayDates[i] - factors.BaseDate);

                                    using (var innerCache = Vector.CacheLike(npv))
                                    {
                                        Vector oldExpectedLoss   = innerCache.Get(expectedLoss);
                                        Vector oldDiscountFactor = innerCache.Get(discountFactor);
                                        Vector oldExpectedWritedownPremiumNotional = innerCache.Get(expectedWritedownPremiumNotional);

                                        Vector expectedLossAttachment     = innerCache.Get();
                                        Vector expectedLossDetachment     = innerCache.Get();
                                        Vector premiumLeg                 = innerCache.Get();
                                        Vector defaultLeg                 = innerCache.Get();
                                        Vector accruedInDefault           = innerCache.Get();
                                        Vector expectedRecoveryAttachment = innerCache.Get();
                                        Vector expectedRecoveryDetachment = innerCache.Get();
                                        Vector avgDiscountFactor          = innerCache.Get();
                                        Vector pv = innerCache.Get();

                                        // Get the expected loss and recovery for the tranche detachment and attachment
                                        parameters.ExpectedLossAndRecovery(expectedLossDetachment, expectedRecoveryDetachment, tgi.T, tPay, adjustedDetachment, realizedIndexLoss, realizedIndexRecovery);
                                        parameters.ExpectedLossAndRecovery(expectedLossAttachment, expectedRecoveryAttachment, tgi.T, tPay, adjustedAttachment, realizedIndexLoss, realizedIndexRecovery);

                                        expectedLoss.Assign((expectedLossDetachment - expectedLossAttachment) / trancheSize);
                                        expectedRecovery.Assign((expectedRecoveryDetachment - expectedRecoveryAttachment) / trancheSize);
                                        expectedWritedownPremiumNotional.Assign(expectedLoss + expectedRecovery);

                                        // Premium leg approximation: Accrued in default pays half the accrued. Remove expected loss and recovery (top down writeoff)
                                        premiumLeg.Assign(fDeal.Spread * (trancheRemainder - expectedWritedownPremiumNotional) * Accruals[i]);
                                        accruedInDefault.Assign(fDeal.Spread * (expectedWritedownPremiumNotional - oldExpectedWritedownPremiumNotional) * 0.5 * Accruals[i]);

                                        // Default leg approximation: account for default with bullet payment at end of period
                                        defaultLeg.Assign(expectedLoss - oldExpectedLoss);

                                        // Convention: bought CDO pays the premium to the buyer
                                        discountFactor.Assign(parameters.DF.Get(tgi.T, tPay));
                                        avgDiscountFactor.Assign(0.5 * (discountFactor + oldDiscountFactor));

                                        pv.Assign(scale * (premiumLeg * discountFactor + (accruedInDefault - defaultLeg) * avgDiscountFactor));
                                        npv.Add(pv);

                                        if (accumulator != null && tgi.T == tPay)
                                        {
                                            accumulator.Accumulate(parameters.X, tgi.Date, scale * (premiumLeg + accruedInDefault - defaultLeg));
                                        }

                                        if (needDiagnostics)
                                        {
                                            using (var innerCache1 = Vector.CacheLike(npv))
                                            {
                                                Vector expectedPremium        = innerCache1.Get(scale * premiumLeg);
                                                Vector expectedDefaultAccrual = innerCache1.Get(scale * accruedInDefault);
                                                Vector expectedDefaultLoss    = innerCache1.Get(scale * defaultLeg);

                                                Vector pvDefaultAccrual = innerCache1.Get(expectedDefaultAccrual * avgDiscountFactor);
                                                Vector pvPremium        = innerCache1.Get(expectedPremium * discountFactor);
                                                Vector pvProctection    = innerCache1.Get(-expectedDefaultLoss * avgDiscountFactor);

                                                // accumulate sums
                                                if (i >= 0)
                                                {
                                                    sumDefaultAccrual += pvDefaultAccrual[0];
                                                    sumPVPremium      += pvPremium[0];
                                                    sumPVProtection   += pvProctection[0];
                                                }

                                                using (IntraValuationDiagnosticsHelper.StartCashflow(fIntraValuationDiagnosticsWriter, PayDates[i]))
                                                {
                                                    var remainingPool = cache.Get(1.0 - realizedIndexLoss - realizedIndexRecovery);
                                                    AddIntraValuationDiagnostics(fIntraValuationDiagnosticsWriter, parameters, adjustedAttachment, adjustedDetachment,
                                                                                 remainingPool, tgi.T, tPay);
                                                    IntraValuationDiagnosticsHelper.AddDetailedCDOCashflow(fIntraValuationDiagnosticsWriter,
                                                                                                           expectedPremium, expectedRecovery, expectedDefaultAccrual, expectedDefaultLoss, discountFactor, pv);
                                                }
                                            }
                                        }
                                    }

                                    return(LoopAction.Continue);
                                });

                                if (needDiagnostics)
                                {
                                    IntraValuationDiagnosticsHelper.AddSummaryCDOAmounts(fIntraValuationDiagnosticsWriter, npv, sumDefaultAccrual,
                                                                                         sumPVPremium, sumPVProtection);
                                }
                            }

                            result.AppendVector(tgi.Date, npv * parameters.X.Get(tgi.T));
                        }
                    }
                });
            }

            // After maturity
            result.Complete(fT);
        }