I found some unexpected result when trying to call AmortizingFixedRateBond wiht daily coupon payments, but starting in the last day of the month.
settlementDays = 0
calendar = ql.Russia()
nominal = 1000
startDate = ql.Date(31, 8, 2021) #ql.Date.todaysDate()
duration = ql.Period('12m')
frequency = ql.Monthly
interest = 0.07
daytimeConvention = ql.Thirty360()
businessAdjustment = ql.ModifiedFollowing
annuityAsBond = ql.AmortizingFixedRateBond(settlementDays, calendar, nominal, startDate, duration, frequency, interest, daytimeConvention, businessAdjustment, ql.Date())
leg = ql.Leg([*annuityAsBond.cashflows()])
df = pd.DataFrame({'Date': [c.date().to_date() for c in leg],
'Payment': [c.amount() for c in leg]})
df = df.groupby('Date').sum()
Output:
Payment
Date
2021-09-30 86.526746
2021-10-29 86.526746
2021-11-30 86.526746
2021-12-31 86.526746
2022-01-31 86.526746
2022-02-28 **86.296602**
2022-03-31 **86.823502**
2022-04-29 86.526746
2022-05-31 86.526746
2022-06-30 86.526746
2022-07-29 86.526746
2022-08-31 86.526746
As you see, the annuity calculator breaks a little bit (basically it transfers a single day interest from one month to another due to shortness of the February). At the same time, it is totally working as expected if startDate
is not the end of the month. I tried different combinations of the convention and businessAdjustment, but this end of month trick is persistent. Is there a way around it to obtain correct coupons?