I tried the following prompt:
Write Python program to create a schedule in QuantLib having London, UK, holiday calendar, issue date on December 1, 2023, long first coupon paid on April 1, 2024, followed by quarterly coupon periods, until the maturity date January 1, 2025.
This was the response from Google Bard:
import QuantLib as ql
Create the London holiday calendar
london_calendar = ql.UnitedKingdom()
Define the schedule parameters
issue_date = ql.Date(1, 12, 2023)
maturity_date = ql.Date(1, 1, 2025)
tenor = ql.Period(ql.Quarterly) # Quarterly coupons
calendar = london_calendar
business_convention = ql.Following # Adjust to following business day if a holiday
date_generation = ql.DateGeneration.Forward
end_of_month = False # Coupon payments not necessarily on end of month
Create the schedule with a long first period
schedule = ql.Schedule(issue_date, maturity_date, tenor, calendar,
business_convention, business_convention,
date_generation, end_of_month)
Set the first coupon date explicitly to April 1, 2024
schedule.firstDate = ql.Date(1, 4, 2024)
Print the schedule
print(schedule)
Problem 1: print(schedule) outputs:
<QuantLib.QuantLib.Schedule; proxy of <Swig Object of type 'Schedule *' at 0x0000017A3DA20720> >
Replacing print with
for i, date in enumerate(schedule):
print(f"#{i} {date.ISO()}")
outputs:
#0 2023-12-01
#1 2024-03-01
#2 2024-06-03
#3 2024-09-02
#4 2024-12-02
#5 2025-01-02
Problem 2: these are not the dates that we're looking for. Changing schedule.firstDate did not have the desired effect.
Problem 3: Sidetracking, my pet peeve: "London" holidays are not the same as "Scotland" holidays and there is no such thing as UnitedKingdom() holidays, except in EU programmers' imagination.
Clicking "Regenerate draft" caused Bard to change the Schedule call to:
schedule = ql.Schedule(issue_date, maturity_date, tenor, calendar,
business_convention, business_convention,
date_generation, end_of_month, firstDate=ql.Date(1, 4, 2024))
Problem 4: Between SWIG, Quantlib and Python, we can't pass named keywords like firstDate - Python throws TypeError: Schedule.__init__() got an unexpected keyword argument.... This date should have been passed as a positional argument instead. A cleaned-up version is at the end of this answer.
ChatGPT 3.5 generated the following more convoluted code:
from QuantLib import *
def create_schedule_with_custom_dates():
issue_date = Date(1, 12, 2023)
long_first_coupon_date = Date(1, 4, 2024)
maturity_date = Date(1, 1, 2025)
tenor = Period(3, Months) # Quarterly coupons
calendar = UnitedKingdom()
convention = ModifiedFollowing
# Create schedule with custom dates
schedule = Schedule(issue_date, maturity_date, tenor, calendar,
convention, convention,
DateGeneration.Backward, False)
# Set custom long first coupon date
schedule[0] = long_first_coupon_date
return schedule
def main():
schedule = create_schedule_with_custom_dates()
for date in schedule:
print(date)
if name == "main":
main()
Problem 5:
schedule[0] = long_first_coupon_date
~~~~~~~~^^^
TypeError: 'Schedule' object does not support item assignment
ChatGPT 4.0 in Microsoft CoPilot generated this code:
# Import QuantLib library
import QuantLib as ql
Define the parameters
issue_date = ql.Date(1, 12, 2023) # December 1, 2023
maturity_date = ql.Date(1, 1, 2025) # January 1, 2025
coupon_frequency = ql.Period(ql.Quarterly) # Quarterly coupons
calendar = ql.UnitedKingdom() # London, UK, holiday calendar
convention = ql.ModifiedFollowing # Business day convention
end_of_month = False # Do not adjust to end of month
first_coupon_date = ql.Date(1, 4, 2024) # April 1, 2024
first_coupon_period = ql.Period(ql.Semiannual) # Long first coupon
Create the schedule
schedule = ql.Schedule(issue_date, maturity_date, coupon_frequency,
calendar, convention, convention, ql.DateGeneration.Forward, end_of_month,
first_coupon_date, first_coupon_period)
Print the schedule
print("The schedule is:")
for date in schedule:
print(date)
Problem 6: Semiannual is AI's hallucination. The odd first coupon is meant to be 4 months long.
Problem 7: Passing the hallucinatory first_coupon_period in the position where the constructor expects nextToLastDate causes Python to throw:
TypeError: Wrong number or type of arguments for overloaded function 'new_Schedule'.
Possible C/C++ prototypes are:
...
Conclusion: none of the generative AI programs wrote a program that ran correctly, but Bard came close.
For reference, here is a cleaned up version of Bard's code:
import QuantLib as ql
Define the schedule parameters
issue_date = ql.Date(1, 12, 2023)
maturity_date = ql.Date(1, 1, 2025) # bumped to January 2 because of New year's Day
tenor = ql.Period(ql.Quarterly) # Quarterly coupons
calendar = ql.UnitedKingdom() # London, UK, holiday calendar... NOT!
business_convention = ql.ModifiedFollowing # Adjust to business day if a holiday
date_generation = ql.DateGeneration.Forward
end_of_month = False # Coupon payments not necessarily on end of month
first_coupon_date = ql.Date(1, 4, 2024) # bumped to April 2 because of Easter Monday
Create the schedule with a long first period
schedule = ql.Schedule(issue_date, maturity_date, tenor, calendar,
business_convention, business_convention,
date_generation, end_of_month, first_coupon_date)
Print the schedule
for i, date in enumerate(schedule):
print(f"#{i} {date.ISO()}")
which produces the desired output:
#0 2023-12-01
#1 2024-04-02
#2 2024-07-01
#3 2024-10-01
#4 2025-01-02