Payment dates now are calculated as an offset to the period end date

This commit is contained in:
Richard Green 2016-06-13 19:00:27 +01:00
parent 8ea8ec435e
commit 86203709c0
3 changed files with 25 additions and 13 deletions

View File

@ -1,6 +1,5 @@
package com.r3corda.contracts
import com.r3corda.core.*
import com.r3corda.core.contracts.*
import com.r3corda.core.crypto.Party
import com.r3corda.core.crypto.SecureHash
@ -672,15 +671,18 @@ class InterestRateSwap() : Contract {
// Create a schedule for the fixed payments
for (periodEndDate in dates) {
val paymentDate = BusinessCalendar.getOffsetDate(periodEndDate, Frequency.Daily, fixedLeg.paymentDelay) // + fixedLeg.paymentDelay
val paymentEvent = FixedRatePaymentEvent(
// TODO: We are assuming the payment date is the end date of the accrual period.
periodEndDate, periodStartDate, periodEndDate,
paymentDate,
periodStartDate,
periodEndDate,
fixedLeg.dayCountBasisDay,
fixedLeg.dayCountBasisYear,
fixedLeg.notional,
fixedLeg.fixedRate
)
fixedLegPaymentSchedule[periodEndDate] = paymentEvent
fixedLegPaymentSchedule[paymentDate] = paymentEvent
periodStartDate = periodEndDate
}
@ -695,8 +697,9 @@ class InterestRateSwap() : Contract {
// Now create a schedule for the floating and fixes.
for (periodEndDate in dates) {
val paymentDate = BusinessCalendar.getOffsetDate(periodEndDate, Frequency.Daily, floatingLeg.paymentDelay) // + fixedLeg.paymentDelay
val paymentEvent = FloatingRatePaymentEvent(
periodEndDate,
paymentDate,
periodStartDate,
periodEndDate,
floatingLeg.dayCountBasisDay,
@ -706,7 +709,7 @@ class InterestRateSwap() : Contract {
ReferenceRate(floatingLeg.indexSource, floatingLeg.indexTenor, floatingLeg.index)
)
floatingLegPaymentSchedule.put(periodEndDate, paymentEvent)
floatingLegPaymentSchedule[paymentDate] = paymentEvent
periodStartDate = periodEndDate
}

View File

@ -27,7 +27,7 @@ fun createDummyIRS(irsSelect: Int): InterestRateSwap.State {
rollConvention = DateRollConvention.ModifiedFollowing,
dayInMonth = 10,
paymentRule = PaymentRule.InArrears,
paymentDelay = 0,
paymentDelay = 3,
paymentCalendar = BusinessCalendar.getInstance("London", "NewYork"),
interestPeriodAdjustment = AccrualAdjustment.Adjusted
)
@ -47,7 +47,7 @@ fun createDummyIRS(irsSelect: Int): InterestRateSwap.State {
dayInMonth = 10,
resetDayInMonth = 10,
paymentRule = PaymentRule.InArrears,
paymentDelay = 0,
paymentDelay = 3,
paymentCalendar = BusinessCalendar.getInstance("London", "NewYork"),
interestPeriodAdjustment = AccrualAdjustment.Adjusted,
fixingPeriod = DateOffset.TWODAYS,
@ -360,7 +360,7 @@ class IRSTests {
for (i in stuffToPrint) {
println(i)
var z = dummyIRS.evaluateCalculation(LocalDate.of(2016, 9, 12), Expression(i))
var z = dummyIRS.evaluateCalculation(LocalDate.of(2016, 9, 15), Expression(i))
println(z.javaClass)
println(z)
println("-----------")

View File

@ -8,7 +8,6 @@ import com.fasterxml.jackson.databind.JsonSerializer
import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import com.fasterxml.jackson.databind.annotation.JsonSerialize
import com.r3corda.core.contracts.CommandData
import java.math.BigDecimal
import java.time.DayOfWeek
import java.time.LocalDate
@ -267,6 +266,9 @@ enum class Frequency(val annualCompoundCount: Int) {
},
BiWeekly(26) {
override fun offset(d: LocalDate) = d.plusWeeks(2)
},
Daily(365) {
override fun offset(d: LocalDate) = d.plusDays(1)
};
abstract fun offset(d: LocalDate): LocalDate
@ -317,11 +319,9 @@ open class BusinessCalendar private constructor(val calendars: Array<out String>
var currentDate = startDate
while (true) {
currentDate = period.offset(currentDate)
val scheduleDate = calendar.applyRollConvention(currentDate, dateRollConvention)
currentDate = getOffsetDate(currentDate, period)
if (periodOffset == null || periodOffset <= ctr)
ret.add(scheduleDate)
ret.add(calendar.applyRollConvention(currentDate, dateRollConvention))
ctr += 1
// TODO: Fix addl period logic
if ((ctr > noOfAdditionalPeriods ) || (currentDate >= endDate ?: currentDate ))
@ -329,7 +329,16 @@ open class BusinessCalendar private constructor(val calendars: Array<out String>
}
return ret
}
fun getOffsetDate(startDate: LocalDate, period: Frequency, howMany: Int = 1): LocalDate {
if (howMany == 0) return startDate
var nextDate = startDate
repeat(howMany) { nextDate = period.offset(nextDate) }
return nextDate
}
}
override fun equals(other: Any?): Boolean = if (other is BusinessCalendar) {
/** Note this comparison is OK as we ensure they are sorted in getInstance() */