예제 #1
0
        /// <inheritdoc />
        protected override void GetDefaultTime(Vector defaultTime, PriceFactorList factors)
        {
            if (fCreditRating != null)
            {
                fCreditRating.DefaultTime(defaultTime);
                return;
            }

            base.GetDefaultTime(defaultTime, factors);
        }
예제 #2
0
 /// <summary>
 /// Return the time of default for the underlying obligor. Allows derived valuation models to
 /// support realized default.
 /// </summary>
 protected void DefaultTime(Vector vout, CreditRating creditRating)
 {
     if (creditRating == null)
     {
         vout.Assign(CreditRating.TimeOfDefault.Never);
     }
     else
     {
         creditRating.DefaultTime(vout);
     }
 }
        /// <summary>
        /// Sets defaultDate to valueDate on the first call for which t >= defaultTime.
        /// </summary>
        /// <remarks>Assumes that defaultDate was initialized to a large date value.</remarks>
        protected static void UpdateDefaultDate(CreditRating creditRating, double valueDate, double t, Vector defaultDate)
        {
            using (var cache = Vector.CacheLike(defaultDate))
            {
                // Get time of default
                Vector defaultTime = cache.Get();
                creditRating.DefaultTime(defaultTime);

                defaultDate.AssignConditional(defaultTime > t, defaultDate, VectorMath.Min(defaultDate, valueDate));
            }
        }
예제 #4
0
        /// <inheritdoc />
        protected override void GetDefaultTime(Vector defaultTime, PriceFactorList factors)
        {
            CreditRating cr = GetCreditRating(factors);

            if (cr != null)
            {
                cr.DefaultTime(defaultTime);
                return;
            }

            base.GetDefaultTime(defaultTime, factors);
        }
예제 #5
0
        /// <summary>
        /// Calculate valuation profiles.
        /// </summary>
        public override void Value(ValuationResults valuationResults, PriceFactorList factors, BaseTimeGrid baseTimes)
        {
            PreValue(factors);

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

            BondOptionDeal deal = (BondOptionDeal)Deal;

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

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

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

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

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

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

                        fCreditRating.DefaultTime(defaultTime);
                    }

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

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

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

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

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

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

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

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

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

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

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

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

                                    optionValue.MultiplyBy(buySign * dfr);

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

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

                result.Complete(fT);
            }
        }