Beispiel #1
0
        /// <summary>
        /// Test for the case where publication lag=0, effective offset=0 (GBP conventions) and no cutoff period.
        ///   The arithmetic average coupons are used mainly in USD. This test is more for completeness than a real case.
        /// </summary>
        public virtual void rateGbpNoCutOffSensitivity()
        {
            OvernightIndexRates mockRates = mock(typeof(OvernightIndexRates));

            when(mockRates.Index).thenReturn(GBP_SONIA);
            SimpleRatesProvider simpleProv = new SimpleRatesProvider(mockRates);

            for (int i = 0; i < GBP_OBS.Length; i++)
            {
                when(mockRates.rate(GBP_OBS[i])).thenReturn(FIXING_RATES[i]);
                OvernightRateSensitivity sensitivity = OvernightRateSensitivity.of(GBP_OBS[i], GBP_SONIA.Currency, 1d);
                when(mockRates.ratePointSensitivity(GBP_OBS[i])).thenReturn(sensitivity);
            }
            OvernightAveragedRateComputation          ro       = OvernightAveragedRateComputation.of(GBP_SONIA, START_DATE, END_DATE, 0, REF_DATA);
            ForwardOvernightAveragedRateComputationFn obsFn    = ForwardOvernightAveragedRateComputationFn.DEFAULT;
            PointSensitivityBuilder sensitivityBuilderComputed = obsFn.rateSensitivity(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv);
            PointSensitivities      sensitivityComputed        = sensitivityBuilderComputed.build().normalized();

            double?[] sensitivityExpected = computedSensitivityFD(ro, GBP_SONIA, GBP_OBS);
            assertEquals(sensitivityComputed.Sensitivities.size(), sensitivityExpected.Length);
            for (int i = 0; i < sensitivityExpected.Length; ++i)
            {
                assertEquals(sensitivityComputed.Sensitivities.get(i).Sensitivity, sensitivityExpected[i], EPS_FD);
            }
        }
            // Accumulated rate sensitivity - cutoff part if not fixed
            internal PointSensitivityBuilder cutOffAccumulationSensitivity()
            {
                PointSensitivityBuilder combinedPointSensitivityBuilder = PointSensitivityBuilder.none();
                int nbPeriodNotCutOff = nbPeriods - cutoffOffset + 1;

                for (int i = Math.Max(fixedPeriod, nbPeriodNotCutOff); i < nbPeriods; i++)
                {
                    OvernightIndexObservation obs = observations[i];
                    PointSensitivityBuilder   forwardRateSensitivity = rates.ratePointSensitivity(obs).multipliedBy(obs.YearFraction);
                    combinedPointSensitivityBuilder = combinedPointSensitivityBuilder.combinedWith(forwardRateSensitivity);
                }
                return(combinedPointSensitivityBuilder);
            }
        private PointSensitivityBuilder rateForwardSensitivity(OvernightAveragedRateComputation computation, OvernightIndexRates rates)
        {
            OvernightIndex          index                           = computation.Index;
            HolidayCalendar         calendar                        = computation.FixingCalendar;
            LocalDate               startFixingDate                 = computation.StartDate;
            LocalDate               endFixingDateP1                 = computation.EndDate;
            LocalDate               endFixingDate                   = calendar.previous(endFixingDateP1);
            LocalDate               onRateEndDate                   = computation.calculateMaturityFromFixing(endFixingDate);
            LocalDate               onRateStartDate                 = computation.calculateEffectiveFromFixing(startFixingDate);
            LocalDate               lastNonCutOffMatDate            = onRateEndDate;
            int                     cutoffOffset                    = computation.RateCutOffDays > 1 ? computation.RateCutOffDays : 1;
            PointSensitivityBuilder combinedPointSensitivityBuilder = PointSensitivityBuilder.none();
            double                  accrualFactorTotal              = index.DayCount.yearFraction(onRateStartDate, onRateEndDate);

            if (cutoffOffset > 1)
            {     // Cut-off period
                IList <double> noCutOffAccrualFactorList = new List <double>();
                LocalDate      currentFixingDate         = endFixingDateP1;
                LocalDate      cutOffEffectiveDate;
                for (int i = 0; i < cutoffOffset; i++)
                {
                    currentFixingDate    = calendar.previous(currentFixingDate);
                    cutOffEffectiveDate  = computation.calculateEffectiveFromFixing(currentFixingDate);
                    lastNonCutOffMatDate = computation.calculateMaturityFromEffective(cutOffEffectiveDate);
                    double accrualFactor = index.DayCount.yearFraction(cutOffEffectiveDate, lastNonCutOffMatDate);
                    noCutOffAccrualFactorList.Add(accrualFactor);
                }
                OvernightIndexObservation lastIndexObs = computation.observeOn(currentFixingDate);
                PointSensitivityBuilder   forwardRateCutOffSensitivity = rates.ratePointSensitivity(lastIndexObs);
                double totalAccrualFactor = 0.0;
                for (int i = 0; i < cutoffOffset - 1; i++)
                {
                    totalAccrualFactor += noCutOffAccrualFactorList[i];
                }
                forwardRateCutOffSensitivity    = forwardRateCutOffSensitivity.multipliedBy(totalAccrualFactor);
                combinedPointSensitivityBuilder = combinedPointSensitivityBuilder.combinedWith(forwardRateCutOffSensitivity);
            }
            // Approximated part
            OvernightIndexObservation indexObs = computation.observeOn(onRateStartDate);
            PointSensitivityBuilder   approximatedInterestAndSensitivity = approximatedInterestSensitivity(indexObs, lastNonCutOffMatDate, rates);

            combinedPointSensitivityBuilder = combinedPointSensitivityBuilder.combinedWith(approximatedInterestAndSensitivity);
            combinedPointSensitivityBuilder = combinedPointSensitivityBuilder.multipliedBy(1.0 / accrualFactorTotal);
            // final rate
            return(combinedPointSensitivityBuilder);
        }
            // Composition - forward part in the cutoff period; past/valuation date case dealt with in previous methods
            internal ObjDoublePair <PointSensitivityBuilder> compositionFactorAndSensitivityCutoff()
            {
                OvernightIndexObservation obs = computation.observeOn(lastFixingNonCutoff);

                if (!nextFixing.isAfter(lastFixingNonCutoff))
                {
                    double rate = rates.rate(obs);
                    double compositionFactor           = 1.0d;
                    double compositionFactorDerivative = 0.0;
                    for (int i = 0; i < cutoffOffset - 1; i++)
                    {
                        compositionFactor           *= 1.0d + accrualFactorCutoff[i] * rate;
                        compositionFactorDerivative += accrualFactorCutoff[i] / (1.0d + accrualFactorCutoff[i] * rate);
                    }
                    compositionFactorDerivative *= compositionFactor;
                    PointSensitivityBuilder rateSensitivity = cutoffOffset <= 1 ? PointSensitivityBuilder.none() : rates.ratePointSensitivity(obs);
                    rateSensitivity = rateSensitivity.multipliedBy(compositionFactorDerivative);
                    return(ObjDoublePair.of(rateSensitivity, compositionFactor));
                }
                return(ObjDoublePair.of(PointSensitivityBuilder.none(), 1.0d));
            }