示例#1
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);
            }
        }
示例#2
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;
            }
        }
示例#3
0
        /// <summary>
        /// Prepare for valuation anything that is dependent upon the scenario.
        /// </summary>
        public override void PreValue(PriceFactorList factors)
        {
            base.PreValue(factors);

            var deal = (BondLendingBase)fDeal;

            if (string.IsNullOrEmpty(deal.Issuer))
            {
                return;
            }

            fSurvivalProb = factors.GetInterface <ISurvivalProb>(string.IsNullOrEmpty(deal.Survival_Probability) ? deal.Issuer : deal.Survival_Probability);
        }
        /// <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;
        }
        /// <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]);
                }
            }
        }
        /// <summary>
        /// Prepare for valuation anything that is dependent upon the scenario.
        /// </summary>
        /// <param name="factors">Price factors.</param>
        public override void PreValue(PriceFactorList factors)
        {
            base.PreValue(factors);

            IInflationCashflowListDeal deal = (IInflationCashflowListDeal)Deal;

            fIsDefaultNever  = !NeedCreditRating();
            fCreditRating    = NeedCreditRating()                      ? factors.Get <CreditRating>(deal.Issuer)                       : null;
            fRecoveryRate    = NeedRecoveryRate()                      ? factors.Get <RecoveryRate>(GetRecoveryRateID())               : null;
            fSurvivalProb    = NeedSurvivalProb()                      ? factors.GetInterface <ISurvivalProb>(GetSurvivalProbID())     : null;
            fInflationRate   = !string.IsNullOrEmpty(deal.Index)       ? factors.GetInterface <IInflationRate>(deal.Index)             : null;
            fRepoRate        = !string.IsNullOrEmpty(deal.Repo_Rate)   ? factors.GetInterface <IInterestRate>(deal.Repo_Rate)          : fDiscountRate;
            fIndexVolatility = deal is InflationOptionCashflowListDeal?factors.GetInterface <IPriceIndexVolatility>(GetPriceIndexVolatility()) : null;
        }
示例#7
0
        /// <summary>
        /// Prepare for valuation anything that is dependent upon the scenario.
        /// </summary>
        /// <param name="factors">Price factors.</param>
        public override void PreValue(PriceFactorList factors)
        {
            base.PreValue(factors);

            BondOptionDeal deal = (BondOptionDeal)Deal;

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

            fCreditRating = needRating ? factors.Get <CreditRating>(deal.Issuer) : null;
            fRecoveryRate = needRecovery ? factors.Get <RecoveryRate>(string.IsNullOrEmpty(deal.Recovery_Rate) ? deal.Issuer : deal.Recovery_Rate) : null;
            fSurvivalProb = needSurvival ? factors.GetInterface <ISurvivalProb>(string.IsNullOrEmpty(deal.Survival_Probability) ? deal.Issuer : deal.Survival_Probability) : null;
        }
        /// <summary>
        /// Value the deal using the cashflow list.
        /// </summary>
        /// <param name="pv">Present value to be updated.</param>
        /// <param name="cash">Realised cash to be updated.</param>
        public void Value(Vector pv, Vector cash, double baseDate, double valueDate, Vector settlementDate, IInterestRate discount,
                          IInterestRate forecast, IInterestRate repo, IInterestRateVol interestRateVol, IInterestYieldVol interestYieldVol,
                          ISurvivalProb survivalProb, ISACCRResult saccrResult, IIntraValuationDiagnosticsWriter intraValuationDiagnosticsWriter)
        {
            CFFixedListDeal deal = (CFFixedListDeal)Deal;

            pv.Clear();
            if (cash != null)
            {
                cash.Clear();
            }

            deal.Cashflows.Value(pv, cash, baseDate, valueDate, settlementDate, discount, survivalProb, intraValuationDiagnosticsWriter, fCutoffDate);
            ApplySign(pv, cash, fBuySellSign);
        }
        /// <summary>
        /// Single date valuation function.
        /// </summary>
        public void Value(Vector pv, Vector cash, double baseDate, double valueDate, Vector settlementDate, IInterestRate discount,
                          IInterestRate forecast, IInterestRate repo, IInterestRateVol interestRateVol, IInterestYieldVol interestYieldVol,
                          ISurvivalProb survivalProb, ISACCRResult saccrResult, IIntraValuationDiagnosticsWriter intraValuationDiagnosticsWriter)
        {
            FixedCashflowBaseDeal deal = (FixedCashflowBaseDeal)fDeal;
            double payDate             = deal.Payment_Date;

            if (payDate < valueDate)
            {
                return;
            }

            using (var cache = Vector.CacheLike(pv))
            {
                Vector amount = cache.Get(fAmount);
                if (settlementDate != null)
                {
                    amount.MultiplyBy(settlementDate < payDate);
                }

                if (payDate == valueDate)
                {
                    pv.Assign(amount);
                    if (cash != null)
                    {
                        cash.Assign(amount);
                    }
                }
                else
                {
                    double t    = CalcUtils.DaysToYears(valueDate - baseDate);
                    double tPay = CalcUtils.DaysToYears(payDate - baseDate);
                    if (survivalProb != null)
                    {
                        pv.Assign(amount * discount.Get(t, tPay) * survivalProb.Get(t, tPay));
                    }
                    else
                    {
                        pv.Assign(amount * discount.Get(t, tPay));
                    }
                }
            }
        }
        /// <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());
            }
        }
示例#11
0
 protected abstract void SurvivalProbability(Vector vout, PriceFactorList factors, ISurvivalProb SP, double t1, double t2);
示例#12
0
        /// <summary>
        /// Value the deal using the cashflow list.
        /// </summary>
        /// <param name="pv">Present value to be updated.</param>
        /// <param name="cash">Realised cash to be updated.</param>
        public void Value(Vector pv, Vector cash, double baseDate, double valueDate, Vector settlementDate, IInterestRate discount,
                          IInterestRate forecast, IInterestRate repo, IInterestRateVol interestRateVol, IInterestYieldVol interestYieldVol,
                          ISurvivalProb survivalProb, ISACCRResult saccrResult, IIntraValuationDiagnosticsWriter intraValuationDiagnosticsWriter)
        {
            CFFixedInterestListDeal deal = (CFFixedInterestListDeal)Deal;

            pv.Clear();
            if (cash != null)
            {
                cash.Clear();
            }

            deal.Cashflows.Value(pv, cash, null, baseDate, valueDate, settlementDate, discount, survivalProb, fFxRate, fRateFxRate, intraValuationDiagnosticsWriter, fCutoffDate);

            using (var cache = Vector.CacheLike(pv))
            {
                Vector sp = cache.Get(1.0);

                double dealSettlementDate = deal.Settlement_Date;
                double t       = CalcUtils.DaysToYears(valueDate - baseDate);
                double tSettle = CalcUtils.DaysToYears(dealSettlementDate - baseDate);

                if (Use_Survival_Probability == YesNo.Yes && survivalProb != null)
                {
                    survivalProb.GetValue(sp, t, tSettle);
                    fRecoveryList.Value(pv, baseDate, valueDate, discount, survivalProb, intraValuationDiagnosticsWriter);
                }

                if (valueDate < dealSettlementDate)
                {
                    // Forward deal before settlement date
                    if (deal.Is_Defaultable == YesNo.No)
                    {
                        pv.Assign((pv / discount.Get(t, tSettle) - fSettlementAmount) * repo.Get(t, tSettle));
                    }
                    else
                    {
                        pv.Subtract(fAccruedInterest * discount.Get(t, tSettle) * sp + (fSettlementAmount - fAccruedInterest) * repo.Get(t, tSettle));
                    }
                }
                else if (valueDate == dealSettlementDate)
                {
                    // Forward deal at settlement date
                    pv.Subtract(fSettlementAmount);
                    if (cash != null)
                    {
                        if (deal.Settlement_Style == SettlementType.Cash)
                        {
                            cash.Assign(pv);
                        }
                        else
                        {
                            cash.Subtract(fSettlementAmount);
                        }
                    }
                }
            }

            pv.AssignProduct(fBuySellSign, pv);
            if (cash != null)
            {
                cash.AssignProduct(fBuySellSign, cash);
            }
        }
示例#13
0
 /// <summary>
 /// Returns the recovery rate to be used for pricing.
 /// </summary>
 protected override double PricingRecoveryRate(ISurvivalProb sp)
 {
     return(sp.GetRecoveryRate());
 }
示例#14
0
 protected override void SurvivalProbability(Vector vout, PriceFactorList factors, ISurvivalProb SP, double t1, double t2)
 {
     SP.GetValue(vout, t1, t2);
 }
示例#15
0
 /// <summary>
 /// Returns the recovery rate to be used for pricing.
 /// </summary>
 protected abstract double PricingRecoveryRate(ISurvivalProb sp);
示例#16
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);
            }
        }
示例#17
0
        /// <summary>
        /// Value the deal using the cashflow list.
        /// </summary>
        public void Value(Vector pv, Vector cash, double baseDate, double valueDate, Vector settlementDate, IInterestRate discount,
                          IInterestRate forecast, IInterestRate repo, IInterestRateVol interestRateVol, IInterestYieldVol interestYieldVol,
                          ISurvivalProb survivalProb, ISACCRResult saccrResult, IIntraValuationDiagnosticsWriter intraValuationDiagnosticsWriter)
        {
            var deal = (CFFloatingInterestListDeal)Deal;

            pv.Clear();
            if (cash != null)
            {
                cash.Clear();
            }

            bool valued = false;

            if (Use_Survival_Probability == YesNo.Yes && survivalProb != null)
            {
                fRecoveryList.Value(pv, baseDate, valueDate, discount, survivalProb, intraValuationDiagnosticsWriter);
            }
            else if (!fForecastIsForeign && fCharacteristics.IsStandardPayoff && fCharacteristics.IsStandardLibor && fCashflows.Compounding_Method != CompoundingMethod.Exponential)
            {
                if (fCharacteristics.HasSwaplet && !fCharacteristics.HasOptionlet)
                {
                    ValueSwap(pv, cash, baseDate, valueDate, settlementDate, discount, forecast, intraValuationDiagnosticsWriter);
                    valued = true;
                }
                else if (fCharacteristics.HasOptionlet && !fCharacteristics.HasSwaplet && fCashflows.Compounding_Method == CompoundingMethod.None)
                {
                    fCashflows.ValueCap(pv, cash, baseDate, valueDate, settlementDate, discount, forecast,
                                        fForecastRateVol, saccrResult, intraValuationDiagnosticsWriter, fCutoffDate);
                    valued = true;
                }
            }

            if (!valued)
            {
                // Use general cashflow list valuation
                if (fCashflows.Averaging_Method == AveragingMethod.Average_Rate)
                {
                    fCashflows.ValueAverageRate(pv, cash, baseDate, valueDate, settlementDate, discount, forecast, fForecastRateVol, fForecastYieldVol,
                                                fFxRate, fForecastFxRate, fForecastFxVol, fForecastFxCorrel, survivalProb, intraValuationDiagnosticsWriter, fCutoffDate);
                }
                else
                {
                    fCashflows.Value(pv, cash, baseDate, valueDate, settlementDate, discount, forecast, fDiscountRateVol, fDiscountYieldVol, interestRateVol, interestYieldVol,
                                     fFxRate, fForecastFxRate, fForecastFxVol, fForecastFxCorrel, fForecastDiscountCorrel, survivalProb, intraValuationDiagnosticsWriter, fCutoffDate);
                }
            }

            double dealSettlementDate = deal.Settlement_Date;

            if (valueDate <= dealSettlementDate)
            {
                using (var cache = Vector.CacheLike(pv))
                {
                    Vector accruedInterest = cache.Get();
                    fCashflows.CalculateAccrual(accruedInterest, baseDate, dealSettlementDate, false, deal.AccrualHolidayCalendar(), forecast);
                    Vector settlementAmount = cache.Get(deal.Settlement_Amount);
                    if (deal.Settlement_Amount_Is_Clean == YesNo.Yes)
                    {
                        settlementAmount.Add(accruedInterest);
                    }

                    if (valueDate < dealSettlementDate)
                    {
                        // Forward deal before settlement date
                        double t       = CalcUtils.DaysToYears(valueDate - baseDate);
                        double tSettle = CalcUtils.DaysToYears(dealSettlementDate - baseDate);
                        if (deal.Is_Defaultable == YesNo.No)
                        {
                            pv.Assign((pv / discount.Get(t, tSettle) - settlementAmount) * repo.Get(t, tSettle));
                        }
                        else
                        {
                            pv.Subtract(accruedInterest * discount.Get(t, tSettle) + (settlementAmount - accruedInterest) * repo.Get(t, tSettle));
                        }
                    }
                    else if (valueDate == dealSettlementDate)
                    {
                        // Forward deal at settlement date
                        pv.Subtract(settlementAmount);
                        if (cash != null)
                        {
                            if (deal.Settlement_Style == SettlementType.Cash)
                            {
                                cash.Assign(pv);
                            }
                            else
                            {
                                cash.Subtract(settlementAmount);
                            }
                        }
                    }
                }
            }

            pv.AssignProduct(fBuySellSign, pv);
            if (cash != null)
            {
                cash.AssignProduct(fBuySellSign, cash);
            }
        }