//------------------------------------------------------------------------- // 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); }
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); }