Exemple #1
0
        /// <summary>
        /// Calculate vector valuation profile and vector realised cash profile.
        /// </summary>
        public override void Value(ValuationResults valuationResults, PriceFactorList factors, BaseTimeGrid baseTimes)
        {
            PreValue(factors);

            CalcUtils.CreateDealProfilesIfRequired(valuationResults, fItems, factors);

            double paySign = fSwaptionDeal.Payer_Receiver == PayerReceiver.Payer ? +1 : -1;
            double buySign = fSwaptionDeal.Buy_Sell == BuySell.Buy         ? +1 : -1;

            bool isCashSettled       = fSwaptionDeal.Settlement_Style == SettlementType.Cash;
            bool isPhysicallySettled = fSwaptionDeal.Settlement_Style == SettlementType.Physical;
            bool cashRequired        = !valuationResults.Cash.Ignore;

            TimeGridIterator tgi = new TimeGridIterator(fT);

            PVProfiles result = valuationResults.Profile;

            using (IntraValuationDiagnosticsHelper.StartDeal(fIntraValuationDiagnosticsWriter, Deal))
            {
                using (var outerCache = Vector.Cache(factors.NumScenarios))
                {
                    Vector pv             = outerCache.Get();
                    Vector exerciseWeight = outerCache.GetClear();
                    Vector cash           = cashRequired ? outerCache.GetClear() : null;

                    // For a cash settled swaption, Settlement amount to be paid on Settlement Date.
                    Vector settlementCash = isCashSettled ? outerCache.GetClear() : null;

                    VectorEngine.For(tgi, () =>
                    {
                        // Work out the PV
                        if (tgi.Date < fSwaptionDeal.Option_Expiry_Date)
                        {
                            ValueBeforeExpiry(pv, factors, isCashSettled, tgi);
                        }
                        else
                        {
                            ValueOnOrAfterExpiry(pv, exerciseWeight, settlementCash, cash, factors, isCashSettled, isPhysicallySettled, cashRequired, tgi, paySign);
                        }

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

                        if (cashRequired)
                        {
                            valuationResults.Cash.Accumulate(fFxRate, tgi.Date, buySign * cash);
                        }
                    });
                }

                result.Complete(fT);
            }
        }
Exemple #2
0
        /// <summary>
        /// Generic Deal Valuation - derived objects override the ValueFn() method.
        /// </summary>
        public override void Value(ValuationResults valuationResults, PriceFactorList factors, BaseTimeGrid baseTimes)
        {
            PreValue(factors);

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

            fTimeToSettlement = CalcUtils.DaysToYears(deal.Settlement_Date - factors.BaseDate);
            fPeriodEnd1       = CalcUtils.DaysToYears(deal.Period_End_1 - factors.BaseDate);
            fPeriodEnd2       = CalcUtils.DaysToYears(deal.Period_End_2 - factors.BaseDate);

            // The time to expiry is the time to the end of the first expiring contract.
            fTimeToExpiry = CalcUtils.DaysToYears(deal.Period_End_1 - factors.BaseDate);

            using (var cache = Vector.Cache(factors.NumScenarios))
            {
                EnergySpreadOptionPricer pricer1 = GetEnergyOptionPricer(fForwardSample,
                                                                         fReferencePrice1,
                                                                         fReferenceVol1,
                                                                         factors.BaseDate,
                                                                         fPeriodEnd1,
                                                                         deal.Period_Start_1,
                                                                         deal.Period_End_1,
                                                                         deal.Realized_Average_1,
                                                                         deal.Realized_Average_Date_1,
                                                                         cache);

                EnergySpreadOptionPricer pricer2 = GetEnergyOptionPricer(fForwardSample,
                                                                         fReferencePrice2,
                                                                         fReferenceVol2,
                                                                         factors.BaseDate,
                                                                         fPeriodEnd2,
                                                                         deal.Period_Start_2,
                                                                         deal.Period_End_2,
                                                                         deal.Realized_Average_2,
                                                                         deal.Realized_Average_Date_2,
                                                                         cache);

                Vector pv               = cache.Get();
                Vector realizedPrice1   = cache.Get();
                Vector realizedPrice2   = cache.Get();
                Vector unrealizedPrice1 = cache.Get();
                Vector unrealizedPrice2 = cache.Get();
                Vector vol1             = cache.Get();
                Vector vol2             = cache.Get();
                Vector correlation      = cache.Get();
                Vector discountFactor   = cache.Get();

                // Calculate correlation between forward prices for two different (dereferenced) maturities (e.g. Apr2012 and Jan2013).
                TDate forwardDate1 = fReferencePrice1.GetPriceDate(deal.Period_End_1, 0);
                TDate forwardDate2 = fReferencePrice2.GetPriceDate(deal.Period_End_2, 0);
                fCorrelations.GetValue(correlation, tgi.T, forwardDate1, forwardDate2);

                while (tgi.Next())
                {
                    pv.Clear();

                    if (tgi.T <= fTimeToExpiry)
                    {
                        // Get unrealised reference forward prices (which also age the pricer to time t and update the realized average at time t)
                        pricer1.GetUnrealizedPrice(tgi.T, unrealizedPrice1);
                        pricer2.GetUnrealizedPrice(tgi.T, unrealizedPrice2);

                        // Get the realized averages for both reference prices.
                        pricer1.GetRealizedPrice(realizedPrice1);
                        pricer2.GetRealizedPrice(realizedPrice2);

                        int numSamples1           = pricer1.GetNumSamples();
                        int numRealizedSamples1   = pricer1.GetNumRealizedSamples();
                        int numUnrealizedSamples1 = pricer1.GetNumUnrealizedSamples();

                        int numSamples2           = pricer2.GetNumSamples();
                        int numRealizedSamples2   = pricer2.GetNumRealizedSamples();
                        int numUnrealizedSamples2 = pricer2.GetNumUnrealizedSamples();

                        // Modify the strike
                        Vector kStar = cache.Get(deal.Strike_Price
                                                 - realizedPrice1 * numRealizedSamples1 / numSamples1
                                                 + realizedPrice2 * numRealizedSamples2 / numSamples2);
                        Vector refPriceStar1 = cache.Get(unrealizedPrice1 * numUnrealizedSamples1 / numSamples1);
                        Vector refPriceStar2 = cache.Get(unrealizedPrice2 * numUnrealizedSamples2 / numSamples2);

                        // Get ATM volatilities of the forward price at different maturities (given as time in years with respect to base date).
                        pricer1.GetVol(tgi.T, unrealizedPrice2, vol1);
                        pricer2.GetVol(tgi.T, unrealizedPrice1, vol2);

                        // value is intrinsic - pricing with volatility 0 and realized price if there are no future sample.
                        if (numUnrealizedSamples1 == 0)
                        {
                            vol1.Clear();
                        }

                        // value is intrinsic - pricing with volatility 0 and realized price if there are no future sample.
                        if (numUnrealizedSamples2 == 0)
                        {
                            vol2.Clear();
                        }

                        // CSO pricing: exp(-rT) * E{max(F1(T) - F2(T) - K, 0)}
                        // For the European CSO,  we set multiplier1 = sign, multiplier2 = -sign, constant = -sign * strike,
                        // where sign = +1 for a call and -1 for a put in the SpreadOptionBS function.
                        double rootTime = Math.Sqrt(fTimeToExpiry - tgi.T);
                        Vector volStar1 = cache.Get(vol1 * rootTime);
                        Vector volStar2 = cache.Get(vol2 * rootTime);
                        PricingFunctions.SpreadOptionBS(pv, fCallPutSign, -fCallPutSign, cache.Get(-fCallPutSign * kStar), fCallPutSign,
                                                        refPriceStar1, refPriceStar2, kStar, volStar1, volStar2, correlation);

                        // The option itself cannot be worth less than zero (for long positions).
                        // However, due to that the Bjerksund & Stensland is a type of non-optimal exercise, it is possible to end up with negative PV via
                        // its pricing formula.
                        pv.AssignMax(pv, 0.0);

                        // Discount payment made at settlement date
                        pv.MultiplyBy(fScale * fDiscountRate.Get(tgi.T, fTimeToSettlement));
                    }

                    // Cash settlement at settlement date
                    if (tgi.T == fTimeToSettlement && accumulator != null && !accumulator.Ignore)
                    {
                        accumulator.Accumulate(fFxPayoffRate, tgi.Date, pv);
                    }

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

                result.Complete(fT);
            }
        }
Exemple #3
0
        /// <summary>
        /// Value the deal from given base date, price factors and time grid.
        /// </summary>
        public void Value(PVProfiles pvResults, CashAccumulators cashResults, double baseDate, IInterestRate discountRate, IInterestRate forecastRate1, IInterestRate forecastRate2, IFxRate fxRate, TimeGrid timeGrid, int numScenarios)
        {
            var tgi  = new TimeGridIterator(timeGrid);
            var deal = (FloatingInterestCashflowInterpolatedDeal)Deal;

            bool   hasRate1          = deal.HasRate1();
            bool   hasRate2          = deal.HasRate2();
            double scale             = deal.Buy_Sell == BuySell.Buy ? +deal.Principal : -deal.Principal;
            double tPay              = CalcUtils.DaysToYears(fPaymentDate - baseDate);
            double tReset            = CalcUtils.DaysToYears(deal.Reset_Date - baseDate);
            double tRateStart        = CalcUtils.DaysToYears(deal.Rate_Start_Date - baseDate);
            double tRateEnd1         = hasRate1 ? CalcUtils.DaysToYears(fRate1EndDate - baseDate) : 0.0;
            double tRateEnd2         = hasRate2 ? CalcUtils.DaysToYears(fRate2EndDate - baseDate) : 0.0;
            double tRateEnd12        = tRateEnd2 - tRateEnd1;                                                                    // Time from rate 1 end date to rate 2 end date.
            double tAccrualEnd       = CalcUtils.DaysToYears(deal.Accrual_End_Date - baseDate);
            double interpCoefficient = Math.Abs(tRateEnd12) >= CalcUtils.MinTime ? (tAccrualEnd - tRateEnd1) / tRateEnd12 : 0.0; // Coefficient used to calculate interpolated rate.

            VectorEngine.For(tgi, () =>
            {
                using (var cache = Vector.Cache(numScenarios))
                {
                    Vector pv = cache.Get();

                    if (tgi.Date <= fPaymentDate && fPaymentDate > fCutoffDate)
                    {
                        Vector interpRate = cache.GetClear();
                        Vector rate1      = cache.GetClear();
                        Vector rate2      = cache.GetClear();

                        if (hasRate1)
                        {
                            if (fKnownResetRate1.HasValue)
                            {
                                rate1.Assign(fKnownResetRate1.Value);
                            }
                            else
                            {
                                InterestRateUtils.LiborRate(rate1, forecastRate1, tgi.T, tReset, tRateStart, tRateEnd1, fRate1YearFraction);
                            }
                        }

                        if (hasRate2)
                        {
                            if (fKnownResetRate2.HasValue)
                            {
                                rate2.Assign(fKnownResetRate2.Value);
                            }
                            else
                            {
                                InterestRateUtils.LiborRate(rate2, forecastRate2, tgi.T, tReset, tRateStart, tRateEnd2, fRate2YearFraction);
                            }
                        }

                        if (hasRate1 && hasRate2)
                        {
                            if (Math.Abs(tRateEnd12) >= CalcUtils.MinTime)
                            {
                                interpRate.Assign(rate1 + interpCoefficient * (rate2 - rate1));
                            }
                            else
                            {
                                interpRate.Assign(0.5 * rate1 + 0.5 * rate2);
                            }
                        }
                        else
                        {
                            interpRate.Assign(hasRate1 ? rate1 : rate2);
                        }

                        // Round the calculated rate, regardless whether the valuation date is before or after the reset date.
                        CFFloatingInterestList.RoundRateTo(deal.Interpolated_Rate_Rounding, interpRate);

                        pv.Assign(scale * (interpRate + deal.Margin) * fAccrualYearFraction);

                        CFFixedList.RoundCashflow(pv, Cashflow_Rounding);

                        if (tgi.Date < fPaymentDate)
                        {
                            pv.MultiplyBy(discountRate.Get(tgi.T, tPay));
                        }
                        else if (tgi.Date == fPaymentDate)
                        {
                            cashResults.Accumulate(fxRate, fPaymentDate, pv);
                        }
                    }
                    else
                    {
                        pv.Clear();
                    }

                    pvResults.AppendVector(tgi.Date, pv * fxRate.Get(tgi.T));
                }
            });

            // After maturity
            pvResults.Complete(timeGrid);
        }
        /// <summary>
        /// Calculate a valuation profile for a range of scenarios.
        /// </summary>
        public override void Value(ValuationResults valuationResults, PriceFactorList factors, BaseTimeGrid baseTimes)
        {
            IAssetPrice price  = GetAssetPrice(factors);
            PVProfiles  result = valuationResults.Profile;

            double scale = fDeal.Units * (fDeal.Buy_Sell == BuySell.Buy ? +1 : -1);

            var tgi = new TimeGridIterator(fT);

            VectorEngine.For(tgi, () => result.AppendVector(tgi.Date, scale * price.Get(tgi.T)));

            result.Complete(fT);

            CashAccumulators cashAccumulators = valuationResults.Cash;
            double           endDate          = Deal.EndDate();

            if (!cashAccumulators.Ignore && endDate <= fT.fHorizon)
            {
                double  tEnd   = CalcUtils.DaysToYears(endDate - factors.BaseDate);
                IFxRate fxRate = factors.GetInterface <IFxRate>(fDeal.Currency);
                cashAccumulators.Accumulate(fxRate, endDate, scale * price.Get(tEnd) / fxRate.Get(tEnd));
            }
        }