コード例 #1
0
        public virtual double pvbp(RatePaymentPeriod paymentPeriod, RatesProvider provider)
        {
            ArgChecker.isTrue(!paymentPeriod.FxReset.Present, "FX reset is not supported");
            int accPeriodCount = paymentPeriod.AccrualPeriods.size();

            ArgChecker.isTrue(accPeriodCount == 1 || paymentPeriod.CompoundingMethod.Equals(CompoundingMethod.FLAT), "Only one accrued period or Flat compounding supported");
            // no compounding
            if (accPeriodCount == 1)
            {
                RateAccrualPeriod accrualPeriod = paymentPeriod.AccrualPeriods.get(0);
                double            df            = provider.discountFactor(paymentPeriod.Currency, paymentPeriod.PaymentDate);
                return(df * accrualPeriod.YearFraction * paymentPeriod.Notional);
            }
            else
            {
                // Flat compounding
                switch (paymentPeriod.CompoundingMethod)
                {
                case FLAT:
                    return(pvbpCompoundedFlat(paymentPeriod, provider));

                default:
                    throw new System.NotSupportedException("PVBP not implemented yet for non FLAT compounding");
                }
            }
        }
コード例 #2
0
 private double accrualWithNotional(RatePaymentPeriod period, double notional, RatesProvider provider)
 {
     // handle simple case and more complex compounding for whole payment period
     if (period.AccrualPeriods.size() == 1)
     {
         RateAccrualPeriod accrualPeriod = period.AccrualPeriods.get(0);
         return(unitNotionalAccrual(accrualPeriod, accrualPeriod.Spread, provider) * notional);
     }
     return(accrueCompounded(period, notional, provider));
 }
コード例 #3
0
        // sensitivity to the spread for a payment period with FLAT compounding type
        private PointSensitivityBuilder pvbpSensitivtyCompoundedFlat(RatePaymentPeriod paymentPeriod, RatesProvider provider)
        {
            Currency ccy   = paymentPeriod.Currency;
            int      nbCmp = paymentPeriod.AccrualPeriods.size();

            double[] rate = paymentPeriod.AccrualPeriods.Select(ap => rawRate(ap, provider)).ToArray();
            double   df   = provider.discountFactor(ccy, paymentPeriod.PaymentDate);
            double   rB1  = 1.0;

            double[] cpaAccumulatedB1 = new double[nbCmp + 1];
            cpaAccumulatedB1[nbCmp] = paymentPeriod.Notional * df * rB1;
            for (int j = nbCmp - 1; j >= 0; j--)
            {
                RateAccrualPeriod accrualPeriod = paymentPeriod.AccrualPeriods.get(j);
                cpaAccumulatedB1[j] = (1.0d + accrualPeriod.YearFraction * rate[j] * accrualPeriod.Gearing) * cpaAccumulatedB1[j + 1];
            }
            // backward sweep
            double pvbpB2 = 1.0d;

            double[] cpaAccumulatedB1B2 = new double[nbCmp + 1];
            double[] rateB2             = new double[nbCmp];
            for (int j = 0; j < nbCmp; j++)
            {
                RateAccrualPeriod accrualPeriod = paymentPeriod.AccrualPeriods.get(j);
                cpaAccumulatedB1B2[j + 1] += accrualPeriod.YearFraction * pvbpB2;
                cpaAccumulatedB1B2[j + 1] += (1.0d + accrualPeriod.YearFraction * rate[j] * accrualPeriod.Gearing) * cpaAccumulatedB1B2[j];
                rateB2[j] += accrualPeriod.YearFraction * accrualPeriod.Gearing * cpaAccumulatedB1[j + 1] * cpaAccumulatedB1B2[j];
            }
            double dfB2 = paymentPeriod.Notional * rB1 * cpaAccumulatedB1B2[nbCmp];
            PointSensitivityBuilder dfdr   = provider.discountFactors(ccy).zeroRatePointSensitivity(paymentPeriod.PaymentDate);
            PointSensitivityBuilder pvbpdr = dfdr.multipliedBy(dfB2);

            for (int j = 0; j < nbCmp; j++)
            {
                RateAccrualPeriod accrualPeriod = paymentPeriod.AccrualPeriods.get(j);
                pvbpdr = pvbpdr.combinedWith(rateComputationFn.rateSensitivity(accrualPeriod.RateComputation, accrualPeriod.StartDate, accrualPeriod.EndDate, provider).multipliedBy(rateB2[j]));
            }
            return(pvbpdr);
        }
コード例 #4
0
        // explain PV for an accrual period, ignoring compounding
        private void explainPresentValue(RateAccrualPeriod accrualPeriod, DayCount dayCount, Currency currency, double notional, RatesProvider provider, ExplainMapBuilder builder)
        {
            double rawRate    = rateComputationFn.explainRate(accrualPeriod.RateComputation, accrualPeriod.StartDate, accrualPeriod.EndDate, provider, builder);
            double payOffRate = rawRate * accrualPeriod.Gearing + accrualPeriod.Spread;
            double ua         = unitNotionalAccrual(accrualPeriod, accrualPeriod.Spread, provider);

            // Note that the forecast value is not published since this is potentially misleading when
            // compounding is being applied, and when it isn't then it's the same as the forecast
            // value of the payment period.

            builder.put(ExplainKey.ENTRY_TYPE, "AccrualPeriod");
            builder.put(ExplainKey.START_DATE, accrualPeriod.StartDate);
            builder.put(ExplainKey.UNADJUSTED_START_DATE, accrualPeriod.UnadjustedStartDate);
            builder.put(ExplainKey.END_DATE, accrualPeriod.EndDate);
            builder.put(ExplainKey.UNADJUSTED_END_DATE, accrualPeriod.UnadjustedEndDate);
            builder.put(ExplainKey.ACCRUAL_YEAR_FRACTION, accrualPeriod.YearFraction);
            builder.put(ExplainKey.ACCRUAL_DAYS, dayCount.days(accrualPeriod.StartDate, accrualPeriod.EndDate));
            builder.put(ExplainKey.DAYS, (int)DAYS.between(accrualPeriod.StartDate, accrualPeriod.EndDate));
            builder.put(ExplainKey.GEARING, accrualPeriod.Gearing);
            builder.put(ExplainKey.SPREAD, accrualPeriod.Spread);
            builder.put(ExplainKey.PAY_OFF_RATE, accrualPeriod.NegativeRateMethod.adjust(payOffRate));
            builder.put(ExplainKey.UNIT_AMOUNT, ua);
        }
コード例 #5
0
        public virtual void currency_exposure_USD()
        {
            LocalDate               startDate     = LocalDate.of(2016, 8, 2);
            LocalDate               fixingDate    = LocalDate.of(2016, 11, 2);
            LocalDate               endDate       = LocalDate.of(2016, 11, 4);
            double                  yearFraction  = 0.25;
            double                  rate          = 0.10;
            RateAccrualPeriod       accrual       = RateAccrualPeriod.builder().startDate(startDate).endDate(endDate).yearFraction(yearFraction).rateComputation(FixedRateComputation.of(rate)).build();
            double                  notional      = 1000000;
            RatePaymentPeriod       fixedFx       = RatePaymentPeriod.builder().accrualPeriods(accrual).fxReset(FxReset.of(FxIndexObservation.of(FxIndices.GBP_USD_WM, fixingDate, REF_DATA), USD)).notional(notional).paymentDate(endDate).dayCount(DayCounts.ONE_ONE).currency(GBP).build(); // 1_000_000 USD paid in GBP at maturity
            PointSensitivityBuilder pts           = PERIOD_PRICER.presentValueSensitivity(fixedFx, PROVIDER);
            MultiCurrencyAmount     ceComputed    = PERIOD_PRICER.currencyExposure(fixedFx, PROVIDER);
            double                  dfUsd         = PROVIDER.discountFactor(USD, endDate);
            double                  ceUsdExpected = notional * yearFraction * rate * dfUsd;

            assertEquals(ceComputed.getAmount(USD).Amount, ceUsdExpected, 1.0E-6);
            MultiCurrencyAmount ceWithoutPvComputed = PROVIDER.currencyExposure(pts.build().convertedTo(USD, PROVIDER));
            CurrencyAmount      pvComputed          = CurrencyAmount.of(GBP, PERIOD_PRICER.presentValue(fixedFx, PROVIDER));
            MultiCurrencyAmount ceComputed2         = ceWithoutPvComputed.plus(pvComputed);

            assertEquals(ceComputed2.getAmount(USD).Amount, ceUsdExpected, TOLERANCE);
            assertEquals(ceComputed2.getAmount(GBP).Amount, 0.0, TOLERANCE);
        }
コード例 #6
0
        // computes the sensitivity of the accrual period to the rate observations (not to discount factors)
        private PointSensitivityBuilder unitNotionalSensitivityAccrual(RateAccrualPeriod period, Currency ccy, RatesProvider provider)
        {
            PointSensitivityBuilder sensi = rateComputationFn.rateSensitivity(period.RateComputation, period.StartDate, period.EndDate, provider);

            return(sensi.multipliedBy(period.Gearing * period.YearFraction));
        }
コード例 #7
0
 // finds the raw rate for the accrual period
 // the raw rate is the rate before gearing, spread and negative checks are applied
 private double rawRate(RateAccrualPeriod accrualPeriod, RatesProvider provider)
 {
     return(rateComputationFn.rate(accrualPeriod.RateComputation, accrualPeriod.StartDate, accrualPeriod.EndDate, provider));
 }
コード例 #8
0
        // calculate the accrual for a unit notional from the raw rate
        private double unitNotionalAccrualRaw(RateAccrualPeriod accrualPeriod, double rawRate, double spread)
        {
            double treatedRate = rawRate * accrualPeriod.Gearing + spread;

            return(accrualPeriod.NegativeRateMethod.adjust(treatedRate * accrualPeriod.YearFraction));
        }
コード例 #9
0
        // calculate the accrual for a unit notional
        private double unitNotionalAccrual(RateAccrualPeriod accrualPeriod, double spread, RatesProvider provider)
        {
            double rawRate = this.rawRate(accrualPeriod, provider);

            return(unitNotionalAccrualRaw(accrualPeriod, rawRate, spread));
        }