0
$\begingroup$

How can I in QuantLib add redemptions to a AmortizingFloatingRateBond that follow in dates outside the Bond Schedule?

self.schedule = ql.Schedule(ql.Date(18, 5, 2022), ql.Date(10, 12, 2026), self.frequency, 
                            ql.UnitedStates(), ql.ModifiedFollowing, ql.ModifiedFollowing,
                            ql.DateGeneration.Forward, True, ql.Date(18, 5, 2022))
this is the schedule:
               June 20th, 2022        53998.86
               July 18th, 2022        45817.22
             August 18th, 2022        50726.20
          September 19th, 2022        52362.53
            October 18th, 2022        64941.37
           November 18th, 2022        69422.10
           December 19th, 2022        69422.10
            January 18th, 2023        67181.70
                          ...         ...
           November 18th, 2026        67181.70
           December 10th, 2026        49260.84
           December 10th, 2026     15000000.01

these are the redemptions:
September 30th, 2022    159705.21
 December 31st, 2022    159705.21
    March 31st, 2023    227928.79
     June 30th, 2023    227928.79
September 30th, 2023    227928.79
 December 31st, 2023    227928.79
    March 31st, 2024    254287.90
     June 30th, 2024    254287.90
September 30th, 2024    254287.90
 December 31st, 2024    254287.90
    March 31st, 2025    293051.30
     June 30th, 2025    293051.30
September 30th, 2025    293051.30
 December 31st, 2025    293051.30
    March 31st, 2026    345769.53
     June 30th, 2026    345769.53
September 30th, 2026    345769.53
 December 10th, 2026  10542209.04

I have tried:

g.bond.redemptions = (ql.Redemption(159705.21,  ql.Date( 30, 9, 2022)))

but still do not see it in the cash flows:

          September 19th, 2022        52362.53
            October 18th, 2022        64941.37
$\endgroup$
6
  • $\begingroup$ Ungortunately, QuantLib does not support amortizations on dates that are not also coupon payment dates. $\endgroup$ Aug 24, 2022 at 21:00
  • $\begingroup$ That's unfortunate, but isnt the last date irregular? December 10th, 2026 49260.84 December 10th, 2026 15000000.01 is also falls out of the schedule and it is still a redemption... $\endgroup$
    – jamoreiras
    Aug 24, 2022 at 21:45
  • $\begingroup$ How should the coupon be calculated in this case? Take, for instance, a coupon with an amortization date in the middle — would it pay interests accrued on the initial notional for half the coupon and on the final notional for the other half? $\endgroup$ Aug 27, 2022 at 9:25
  • $\begingroup$ The coupon should be calculated based on the trailing Outstanding amount. In your example, the irregular amortization date would cause the next interest payment to reflect the reduction of the notional in the middle. I will post what I have done so far. $\endgroup$
    – jamoreiras
    Aug 29, 2022 at 13:38
  • $\begingroup$ Yes quant.stackexchange.com/questions/48613/… $\endgroup$ Aug 29, 2022 at 15:03

1 Answer 1

1
$\begingroup$

I have followed the guidance from Luigi posted here and joined and sorted the schedule dates with the redemption dates.
The result is very satisfactory, however shows interest payment in irregular dates, which is not correct.

schedule = ql.Schedule(effectiveDate,
                       terminationDate,
                       frequency,
                       calendar,
                       convention,
                       terminationDateConvention,
                       rule,
                       endOfMonth)

dates = list(schedule)

dates.extend([ql.Date(30, 9, 2022),ql.Date(31, 12, 2022),ql.Date(31, 3, 2023),
              ql.Date(30, 6, 2023),ql.Date(30, 9, 2023),ql.Date(31, 12, 2023),
              ql.Date(31, 3, 2024),ql.Date(30, 6, 2024),ql.Date(30, 9, 2024),
              ql.Date(31, 12, 2024),ql.Date(31, 3, 2025),ql.Date(30, 6, 2025),
              ql.Date(30, 9, 2025),ql.Date(31, 12, 2025),ql.Date(31, 3, 2026),
              ql.Date(30, 6, 2026),ql.Date(30, 9, 2026)])

dates.sort()
sched = ql.Schedule(dates, ql.UnitedStates(), ql.ModifiedFollowing)

notional = [15000000.01,15000000.01,15000000.01,15000000.01,15000000.01,
            14840294.8, ...
accrualStartDate().to_date accrualEndDate().to_date accrualDays hasOccurred date().to_date index nominal fixingDate().to_date indexFixing spread rate amount
0 2022-05-20 2022-06-10 21 True 2022-06-10 USDLibor1M Actual/360 index 1.5e+07 2022-05-18 0.0092719 0.03 0.0392719 34,362.9
1 2022-06-10 2022-07-11 31 True 2022-07-11 USDLibor1M Actual/360 index 1.5e+07 2022-06-08 0.0092719 0.03 0.0392719 50,726.2
2 2022-07-11 2022-08-10 30 True 2022-08-10 USDLibor1M Actual/360 index 1.5e+07 2022-07-07 0.0092719 0.03 0.0392719 49,089.9
3 2022-08-10 2022-09-12 33 False 2022-09-12 USDLibor1M Actual/360 index 1.5e+07 2022-08-08 0.0092719 0.03 0.0392719 53,998.9
4 2022-09-12 2022-09-30 18 False 2022-09-30 USDLibor1M Actual/360 index 1.5e+07 2022-09-08 0.023736 0.03 0.053736 40,302
5 2022-09-30 2022-10-11 11 False 2022-10-11 USDLibor1M Actual/360 index 1.48403e+07 2022-09-28 0.0237305 0.03 0.0537305 24,364.3
6 2022-10-11 2022-11-10 30 False 2022-11-10 USDLibor1M Actual/360 index 1.48403e+07 2022-10-07 0.0237454 0.03 0.0537454 66,466.4
7 2022-11-10 2022-12-12 32 False 2022-12-12 USDLibor1M Actual/360 index 1.48403e+07 2022-11-08 0.0237469 0.03 0.0537469 70,899.6
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.