Ejemplo n.º 1
0
        /// <summary>
        /// Value the fixed and floating legs of the swap.
        /// </summary>
        private void ValueFixedAndFloatingLegs(TimeGridIterator tgi, Vector fixedPv, Vector fixedCash, double baseDate, Vector floatPv, Vector floatCash)
        {
            using (IntraValuationDiagnosticsHelper.StartCashflowsOnDate(fIntraValuationDiagnosticsWriter, tgi.Date))
            {
                using (IntraValuationDiagnosticsHelper.StartSwaptionCashflows(fIntraValuationDiagnosticsWriter, fFxRate, tgi.T,
                                                                              CashflowType.FixedLeg, fSwaptionDeal.Floating_Margin))
                {
                    // Calculate value of fixed side
                    fixedPv.Clear();
                    fixedCash.Clear();
                    fFixedCashflowList.Value(fixedPv, fixedCash, null, baseDate, tgi.Date, null, fDiscountRate, null, null, null, fIntraValuationDiagnosticsWriter, 0.0);
                    IntraValuationDiagnosticsHelper.AddCashflowsPV(fIntraValuationDiagnosticsWriter, fixedPv);
                }

                using (IntraValuationDiagnosticsHelper.StartSwaptionCashflows(fIntraValuationDiagnosticsWriter, fFxRate, tgi.T,
                                                                              CashflowType.FloatingLeg, fSwaptionDeal.Floating_Margin))
                {
                    // Calculate value of floating side
                    floatPv.Clear();
                    floatCash.Clear();
                    fFloatCashflowList.ValueSwap(floatPv, floatCash, null, baseDate, tgi.Date, null, 0.0, fDiscountRate, fForecastRate, false, fIntraValuationDiagnosticsWriter);
                    IntraValuationDiagnosticsHelper.AddCashflowsPV(fIntraValuationDiagnosticsWriter, floatPv);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Value the deal.
        /// </summary>
        public override void Value(ValuationResults valuationResults, PriceFactorList factors, BaseTimeGrid baseTimes)
        {
            PreValue(factors);

            CallableBondForward deal = (CallableBondForward)Deal;

            double baseDate       = factors.BaseDate;
            double settlementDate = deal.Settlement_Date;
            double tSettle        = CalcUtils.DaysToYears(settlementDate - baseDate);

            TimeGridIterator tgi = new TimeGridIterator(fT);

            PVProfiles      result  = valuationResults.Profile;
            AccruedInterest accrued = valuationResults.Results <AccruedInterest>();

            var intraValuationDiagnosticsWriter =
                IntraValuationDiagnosticsWriterFactory.GetOrCreate(IntraValuationDiagnosticsLevel.None);

            using (var outerCache = Vector.Cache(factors.NumScenarios))
            {
                // SwapOptionPricerObject is null when there are no valid exercise dates.
                SwaptionPricer.WorkingArrays arrays = fSwaptionPricer != null?fSwaptionPricer.PreValue(fDiscountRate, outerCache) : null;

                Vector tExercise = outerCache.Get(double.PositiveInfinity);                    // time of exercise
                int    numberScenariosExercised = 0;

                Vector defaultDate = fCreditRating != null?outerCache.Get(CalcUtils.DateTimeMaxValueAsDouble) : null;

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

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

                        if (defaultedBeforeBaseDate || numberScenariosExercised == factors.NumScenarios)
                        {
                            // already defaulted before base date or All scenarios exercised
                            result.AppendVector(tgi.Date, pv);
                            return(LoopAction.Break);
                        }
                        else
                        {
                            // Value of the bond cashflows after the settlement.
                            fCashflowList.Value(pv, cash, null, baseDate, tgi.Date, null, fDiscountRate, fSurvivalProb, null,
                                                null, intraValuationDiagnosticsWriter, 0.0);

                            // Add the value of the principal and amortization cashflows.
                            fFixedCashflowList.Value(pv, cash, baseDate, tgi.Date, null, fDiscountRate, fSurvivalProb,
                                                     intraValuationDiagnosticsWriter, 0.0);

                            if (fSurvivalProb != null)
                            {
                                fRecoveryList.Value(pv, baseDate, tgi.Date, fDiscountRate, fSurvivalProb,
                                                    intraValuationDiagnosticsWriter);
                            }

                            if (fNeedsCreditRating)
                            {
                                UpdateDefaultDate(fCreditRating, tgi.Date, tgi.T, defaultDate);
                            }

                            // Add/subtract value of option
                            if (fSwaptionPricer != null)
                            {
                                using (var innerCache = Vector.Cache(factors.NumScenarios))
                                {
                                    Vector optionPv       = innerCache.Get();
                                    Vector exerciseStrike = innerCache.GetClear();    // strike of underlying at exercise
                                    Vector exerciseFee    = innerCache.GetClear();    // fee paid on exercise
                                    fSwaptionPricer.Value(optionPv, tgi.T, fDiscountRate, fInterestYieldVol, fSurvivalProb, arrays, tExercise,
                                                          exerciseStrike, exerciseFee, Early_Exercise_Today == YesNo.Yes, ref numberScenariosExercised);

                                    // Ignore optionality if in default.
                                    if (fNeedsCreditRating)
                                    {
                                        optionPv.AssignConditional(defaultDate > tgi.Date, optionPv, 0.0);
                                    }

                                    pv.Add(optionPv);
                                }
                            }

                            if (tgi.Date < settlementDate)
                            {
                                // Forward deal before settlement date
                                if (deal.Is_Defaultable == YesNo.No)
                                {
                                    pv.Assign((pv / fDiscountRate.Get(tgi.T, tSettle) - fSettlementAmount) * fRepoRate.Get(tgi.T, tSettle));
                                }
                                else
                                {
                                    pv.Subtract((fSettlementAmount - fAccrued) * fRepoRate.Get(tgi.T, tSettle) + fAccrued * fDiscountRate.Get(tgi.T, tSettle));   // discount accrued with bond rate; accrued interest must cancel
                                }
                            }
                            else if (tgi.Date == settlementDate)
                            {
                                // Forward deal at settlement date
                                pv.Subtract(fSettlementAmount);
                                cash.Subtract(fSettlementAmount);
                            }

                            if (deal.IsForward())
                            {
                                // Cash settled forward
                                if (tgi.Date == settlementDate)
                                {
                                    cash.Assign(pv);
                                }
                                else
                                {
                                    cash.Clear();
                                }
                            }
                            else if (tgi.Date >= settlementDate)
                            {
                                using (var innerCache = Vector.Cache(factors.NumScenarios))
                                {
                                    Vector afterExercise  = innerCache.Get(tExercise < tgi.T);
                                    Vector beforeExercise = innerCache.Get(tExercise > tgi.T);

                                    Vector exercisedToday = innerCache.GetClear();
                                    exercisedToday.Assign(afterExercise.Or(beforeExercise));
                                    exercisedToday.Assign(!exercisedToday);

                                    double callAmount = deal.Notional * Percentage.PercentagePoint * deal.Call_Prices.GetRate(tgi.Date);

                                    // Before exercise: pv is bondPV + optionPv and cash is bondCash.
                                    // On exercise: pv and cash are bondCash + callAmount.
                                    // After exercise: pv and cash are zero.
                                    cash.AssignConditional(exercisedToday, cash + callAmount, beforeExercise * cash);
                                    pv.AssignConditional(exercisedToday, cash, beforeExercise * pv);
                                }
                            }

                            // Apply leg sign to results
                            int buySellSign = deal.Buy_Sell == BuySell.Buy ? +1 : -1;
                            ApplySign(pv, cash, buySellSign);

                            if (fNeedsCreditRating)
                            {
                                Vector beforeExercise      = cache.Get(tExercise > tgi.T);
                                Vector modifiedDefaultDate = cache.Get();

                                // If default occurs after the call option has been exercise, default is irrelevant.
                                // If default occurs on the same date that the call option is exercised, the assumption
                                // is that the bond has been paid back in full, otherwise it wouldn''t be considered exercised.
                                modifiedDefaultDate.AssignConditional(beforeExercise, defaultDate, double.PositiveInfinity);
                                GetDefaultValue(baseDate, tgi.Date, modifiedDefaultDate, fRecoveryRate, pv, cash);
                            }

                            valuationResults.Cash.Accumulate(fFxRate, tgi.Date, cash);
                            result.AppendVector(tgi.Date, pv * fFxRate.Get(tgi.T));

                            if (accrued != null)
                            {
                                accrued.SetValue(tgi.Date, fCashflowList.CalculateAccrual(tgi.Date, accrued.AccrueFromToday, fDeal.GetHolidayCalendar()) * buySellSign);
                            }
                        }
                    }

                    return(LoopAction.Continue);
                });
            }

            result.Complete(fT);
        }