QuantLib曲线计算异常:负时间值RuntimeError报错排查
That RuntimeError: negative time (-0.00273973) given error is a classic sign that QuantLib is calculating a time interval where the end date is earlier than the start date—even though your input dates look correct at first glance. Let’s break down the most likely causes and fixes:
1. First: Verify Your Date Conversion
The error’s numerical value (-0.00273973) is almost exactly -1/365—which matches the Actual365Fixed day count your curve uses. That tells us the calculated time difference is equivalent to one day backward.
The most common culprit here is a bug in your pydate_to_qldate function. QuantLib’s Date constructor uses the order (day, month, year)—mixing up these parameters can lead to unexpected date shifts (like turning 2018-01-01 into a date in 2017).
Debug Step: Print Converted Dates
Add this code right before your forwardRate call to confirm what dates you’re actually passing to QuantLib:
start_qld = pydate_to_qldate(start_date) end_qld = pydate_to_qldate(end_date) print(f"Python Start Date: {start_date} → QL Date: {start_qld}") print(f"Python End Date: {end_date} → QL Date: {end_qld}") print(f"Start Date is AFTER End Date? {start_qld > end_qld}")
If the last line prints True, your conversion function is broken.
Fix the Conversion Function
Replace your pydate_to_qldate with a safe, correct implementation:
import QuantLib as ql from datetime import datetime def pydate_to_qldate(pyd): # Convert date to datetime if needed if isinstance(pyd, datetime.date): pyd = datetime(pyd.year, pyd.month, pyd.day) # Use QuantLib's built-in converter to avoid parameter mix-ups return ql.Date.fromDateTime(pyd)
Or if you prefer manual construction (ensure parameter order is correct):
def pydate_to_qldate(pyd): return ql.Date(pyd.day, pyd.month, pyd.year)
2. Check Curve Node Coverage
While less likely to cause negative time, if your OIS curve’s latest node is earlier than 2018-01-01, even with extrapolation enabled, edge cases can occur. Verify your curve’s date range with:
print(f"Curve Reference Date: {usd_ois.ois_curve_c.referenceDate()}") print(f"Curve Latest Valid Date: {usd_ois.ois_curve_c.maxDate()}") print(f"End Date is beyond curve range? {end_qld > usd_ois.ois_curve_c.maxDate()}")
If the end date is beyond the curve’s max date, double-check that your OIS swap helpers include a tenor that covers at least 2018-01-01.
3. Confirm ForwardRate Overload Usage
Make sure you’re calling the correct forwardRate overload that accepts two dates. Accidentally passing time values (floats) instead of dates can lead to unexpected calculations, but since your code works for most dates, this is less likely. The correct signature for your use case is:
ois_curve.ois_curve_c.forwardRate( start_qld, # QL Date object end_qld, # QL Date object ql.Actual360(), ql.Simple ).rate() * 100
Quick Recap
The negative time error almost always boils down to date mismatches from conversion bugs. Start by validating your converted dates—once those are correct, the error should disappear.
内容的提问来源于stack exchange,提问作者sumit_uk1

