# How to make a schedule for amortizing bonds in python quantlib?

I am trying to make a schedule for amortizing bonds in quantlib, but have no idea how to include amortization in this schedule.

I have the following bond:

Maturity Date:
30.04.2023
Coupon Frequency:
300 at
30.04.2018
300 at
30.04.2021
Day Count
Convention: 30Е/360
Coupon rate: 10


Here is the python code

faceValue = 100.0
ed = ql.Date(2, ql.December, 2019)
mat_d = ql.Date(30, ql.April, 2023)
coupons = [0.1]

dayCounter = ql.Thirty360(ql.Thirty360.European)

schedule = ql.Schedule(ed, mat_d, ql.Period(ql.Semiannual),
ql.Russia(),
ql.DateGeneration.Backward, False)


Amortization is included when you build the bond.

Given that you're mentioning a payment of 300, I'll guess that your face amount is 1000, not 100 as you wrote. Also, you're mentioning a payment on 30.04.2018, but your schedule starts on 02.12.2019. For the purpose of the example, I'll start the schedule earlier so it includes both payments.

So, let's say your schedule is

start_d = ql.Date(30, ql.April, 2016)
mat_d = ql.Date(30, ql.April, 2023)
schedule = ql.Schedule(
start_d, mat_d, ql.Period(ql.Semiannual),
ql.Russia(),
ql.DateGeneration.Backward, False)


which gives the dates:

[Date(30,4,2016),
Date(30,10,2016),
Date(30,4,2017),
Date(30,10,2017),
Date(30,4,2018),
Date(30,10,2018),
Date(30,4,2019),
Date(30,10,2019),
Date(30,4,2020),
Date(30,10,2020),
Date(30,4,2021),
Date(30,10,2021),
Date(30,4,2022),
Date(30,10,2022),
Date(30,4,2023)]


To create an amortizing bond, you'll specify the notional for each coupon. In this example, the first four coupons (before 30.04.2018) are paid on the full notional; then an amortizing payment of 300 is made, and the next six coupons are paid on the remaining notional (700); then another amortizing payment of 300 comes, and the next four coupons are paid on what remains (400). So you'll write:

notionals = [1000, 1000, 1000, 1000,
700, 700, 700, 700, 700, 700,
400, 400, 400, 400]


and you'll create the bond as

settlement_days = 3
coupons = [0.1]
dayCounter = ql.Thirty360(ql.Thirty360.European)

bond = ql.AmortizingFixedRateBond(settlement_days, notionals, schedule, coupons, dayCounter)


Now you can check its cashflows:

for c in bond.cashflows():
print(f"{str(c.date()):20} => {c.amount():.4}")


which gives

October 31st, 2016   => 50.0
May 2nd, 2017        => 50.0
October 30th, 2017   => 50.0
May 3rd, 2018        => 50.0
May 3rd, 2018        => 300.0
October 30th, 2018   => 35.0
April 30th, 2019     => 35.0
October 30th, 2019   => 35.0
April 30th, 2020     => 35.0
October 30th, 2020   => 35.0
April 30th, 2021     => 35.0
April 30th, 2021     => 300.0
November 1st, 2021   => 20.0
May 3rd, 2022        => 20.0
October 31st, 2022   => 20.0
May 2nd, 2023        => 20.0
May 2nd, 2023        => 400.0

• Very seldom, a few bonds (not the example in the question) have amortizations dates that don't coincide with coupon dates. Then some coupons need to be accrued on different remaining notionals within the same coupon period. Oct 12, 2021 at 15:58
• Right - that special case is not covered at this time. Oct 12, 2021 at 18:35