// Composition - forward part in the cutoff period; past/valuation date case dealt with in previous methods
 internal double compositionFactorCutoff()
 {
     if (!nextFixing.isAfter(lastFixingNonCutoff))
     {
         OvernightIndexObservation obs = computation.observeOn(lastFixingNonCutoff);
         double rate = rates.rate(obs);
         double compositionFactor = 1.0d;
         for (int i = 0; i < cutoffOffset - 1; i++)
         {
             compositionFactor *= 1.0d + accrualFactorCutoff[i] * rate;
         }
         return(compositionFactor);
     }
     return(1.0d);
 }
        //-------------------------------------------------------------------------
        // Compute the approximated rate in the case where the whole period is forward.
        // There is no need to compute overnight periods, except for the cut-off period.
        private double rateForward(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       onRateNoCutOffEndDate = onRateEndDate;
            int             cutoffOffset          = computation.RateCutOffDays > 1 ? computation.RateCutOffDays : 1;
            double          accumulatedInterest   = 0.0d;
            double          accrualFactorTotal    = index.DayCount.yearFraction(onRateStartDate, onRateEndDate);

            if (cutoffOffset > 1)
            {     // Cut-off period
                LocalDate currentFixingDate            = endFixingDate;
                OvernightIndexObservation lastIndexObs = null;
                double cutOffAccrualFactorTotal        = 0d;
                for (int i = 1; i < cutoffOffset; i++)
                {
                    currentFixingDate         = calendar.previous(currentFixingDate);
                    lastIndexObs              = computation.observeOn(currentFixingDate);
                    onRateNoCutOffEndDate     = lastIndexObs.MaturityDate;
                    cutOffAccrualFactorTotal += lastIndexObs.YearFraction;
                }
                double forwardRateCutOff = rates.rate(lastIndexObs);
                accumulatedInterest += cutOffAccrualFactorTotal * forwardRateCutOff;
            }
            // Approximated part
            accumulatedInterest += approximatedInterest(computation.observeOn(onRateStartDate), onRateNoCutOffEndDate, rates);
            // final rate
            return(accumulatedInterest / accrualFactorTotal);
        }
Esempio n. 3
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);
            }
        }
Esempio n. 4
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 rateGbpNoCutOff()
        {
            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]);
            }
            OvernightAveragedRateComputation          ro    = OvernightAveragedRateComputation.of(GBP_SONIA, START_DATE, END_DATE, 0, REF_DATA);
            ForwardOvernightAveragedRateComputationFn obsFn = ForwardOvernightAveragedRateComputationFn.DEFAULT;
            double accrualFactorTotal = 0.0d;
            double accruedRate        = 0.0d;
            int    indexLast          = 5; // Fixing in the observation period are from 1 to 5 (inclusive)

            for (int i = 1; i <= indexLast; i++)
            {
                LocalDate startDate = GBP_OBS[i].EffectiveDate;
                LocalDate endDate   = GBP_OBS[i].MaturityDate;
                double    af        = GBP_SONIA.DayCount.yearFraction(startDate, endDate);
                accrualFactorTotal += af;
                accruedRate        += FIXING_RATES[i] * af;
            }
            double rateExpected = accruedRate / accrualFactorTotal;
            double rateComputed = obsFn.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv);

            assertEquals(rateExpected, rateComputed, TOLERANCE_RATE);
        }
Esempio n. 5
0
        /// <summary>
        /// Test for the case where publication lag=1, effective offset=0 (USD conventions) and cutoff=2 (FedFund swaps). </summary>
        public virtual void rateFedFund()
        {
            OvernightIndexRates mockRates = mock(typeof(OvernightIndexRates));

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

            for (int i = 0; i < USD_OBS.Length; i++)
            {
                when(mockRates.rate(USD_OBS[i])).thenReturn(FIXING_RATES[i]);
            }
            OvernightAveragedRateComputation          ro    = OvernightAveragedRateComputation.of(USD_FED_FUND, START_DATE, END_DATE, 2, REF_DATA);
            ForwardOvernightAveragedRateComputationFn obsFn = ForwardOvernightAveragedRateComputationFn.DEFAULT;
            double accrualFactorTotal = 0.0d;
            double accruedRate        = 0.0d;
            int    indexLast          = 5; // Fixing in the observation period are from 1 to 5 (inclusive), but last is modified by cut-off

            for (int i = 1; i <= indexLast - 1; i++)
            {
                LocalDate endDate = USD_OBS[i].MaturityDate;
                double    af      = USD_FED_FUND.DayCount.yearFraction(FIXING_DATES[i], endDate);
                accrualFactorTotal += af;
                accruedRate        += FIXING_RATES[i] * af;
            }
            // CutOff
            LocalDate endDate = USD_OBS[indexLast].MaturityDate;
            double    af      = USD_FED_FUND.DayCount.yearFraction(FIXING_DATES[indexLast], endDate);

            accrualFactorTotal += af;
            accruedRate        += FIXING_RATES[indexLast - 1] * af;
            double rateExpected = accruedRate / accrualFactorTotal;
            double rateComputed = obsFn.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv);

            assertEquals(rateExpected, rateComputed, TOLERANCE_RATE);
        }
            // Accumulated rate - cutoff part if not fixed
            internal double cutOffAccumulation()
            {
                double accumulatedInterest = 0.0d;
                int    nbPeriodNotCutOff   = nbPeriods - cutoffOffset + 1;

                for (int i = Math.Max(fixedPeriod, nbPeriodNotCutOff); i < nbPeriods; i++)
                {
                    OvernightIndexObservation obs = observations[i];
                    double forwardRate            = rates.rate(obs);
                    accumulatedInterest += obs.YearFraction * forwardRate;
                }
                return(accumulatedInterest);
            }
Esempio n. 7
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Test for the case where publication lag=1, effective offset=0 (USD conventions) and no cutoff period. </summary>
        public virtual void rateFedFundNoCutOff()
        {
            OvernightIndexRates mockRates = mock(typeof(OvernightIndexRates));

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

            for (int i = 0; i < USD_OBS.Length; i++)
            {
                when(mockRates.rate(USD_OBS[i])).thenReturn(FIXING_RATES[i]);
            }
            OvernightAveragedRateComputation ro = OvernightAveragedRateComputation.of(USD_FED_FUND, START_DATE, END_DATE, 0, REF_DATA);
            // Accrual dates = fixing dates
            ForwardOvernightAveragedRateComputationFn obsFn = ForwardOvernightAveragedRateComputationFn.DEFAULT;
            double accrualFactorTotal = 0.0d;
            double accruedRate        = 0.0d;
            int    indexLast          = 5; // Fixing in the observation period are from 1 to 5 (inclusive)

            for (int i = 1; i <= indexLast; i++)
            {
                LocalDate endDate = USD_OBS[i].MaturityDate;
                double    af      = USD_FED_FUND.DayCount.yearFraction(FIXING_DATES[i], endDate);
                accrualFactorTotal += af;
                accruedRate        += FIXING_RATES[i] * af;
            }
            double rateExpected = accruedRate / accrualFactorTotal;
            double rateComputed = obsFn.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv);

            assertEquals(rateExpected, rateComputed, TOLERANCE_RATE);

            // explain
            ExplainMapBuilder builder       = ExplainMap.builder();
            double            explainedRate = obsFn.explainRate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv, builder);

            assertEquals(explainedRate, rateExpected, TOLERANCE_RATE);

            ExplainMap built = builder.build();

            assertEquals(built.get(ExplainKey.OBSERVATIONS).Present, false);
            assertEquals(built.get(ExplainKey.COMBINED_RATE).Value.doubleValue(), rateExpected, TOLERANCE_RATE);
        }