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