Setting the First ZeroCurve Date to the Evaluation Date in QuantLib
Summary
The question describes pricing a fixed coupon bond in QuantLib with a flat yield curve built from semiannual zero rates. The user encounters a negative-time error because the curve’s first date comes after the evaluation date. The accepted answer explains that the curve should begin on the evaluation date, then extend forward at the chosen intervals. This addresses the specific date setup behind the error and allows the bond engine to obtain discount factors for its cash flows.
The discussion is a narrow implementation tip rather than a general guide to bond valuation. It does not explain curve construction assumptions, day-count conventions, settlement-date handling, or how to validate the resulting price. A curve built from one yield should also be understood as a modeling simplification; the document gives no market data or evidence comparing that flat curve with an observed term structure.
Key ideas
- A QuantLib zero curve should include the evaluation date as its first date in this setup.
- Starting the curve later can produce a negative-time error when discounting cash flows.
- The example uses a flat yield to construct points at semiannual intervals.
- The answer does not cover curve calibration or broader bond pricing assumptions.
Tags
Full text
# Pricing fixed coupon bond with ytm in QuantLib python # Pricing fixed coupon bond with ytm in QuantLib python I'm new to QuantLib and I'm confused about `ZeroCurve` in `YieldTermStructureHandle` The start date is Oct 20, 2001. Assuming the evaluation date is May 8, 2017, and I can obtain the ytm, which is 4.3291. I think I can construct a flat yield curve and discount the cash flow. However, it says negative time (-0.452055) given. ``` from QuantLib import * todaysDate = Date(8, 5, 2017) Settings.instance().evaluationDate = todaysDate spotDates = [Date(20, 4, 2017)+Period(i*6, Months) for i in range(1, 10)] spotRates = [4.3291/100]*len(spotDates) dayCount = ActualActual() calendar = China() interpolation = Linear() compounding = Compounded compoundingFrequency = 2 spotCurve = ZeroCurve(spotDates, spotRates, dayCount, calendar, interpolation, compounding, compoundingFrequency) spotCurveHandle = YieldTermStructureHandle(spotCurve) issueDate = Date(20, 10, 2001) maturityDate = Date(20, 10, 2021) tenor = Period(2) bussinessConvention = Following dateGeneration = DateGeneration.Backward monthEnd = False schedule = Schedule(issueDate, maturityDate, tenor, calendar, bussinessConvention, bussinessConvention, dateGeneration, monthEnd) couponRate = 4.2/100 coupons = [couponRate] settlementDays = faceValue = 100 fixedRateBond = FixedRateBond(settlementDays, faceValue, schedule, coupons, dayCount) bondEngine = DiscountingBondEngine(spotCurveHandle) fixedRateBond.setPricingEngine(bondEngine) fixedRateBond.NPV() ``` ## Answer by Lliane (score 1, accepted) https://quant.stackexchange.com/a/40076 The first point in your rate curve needs to be the evaluation date, start with i = 0 and your evaluation date `spotDates = [Date(8, 5, 2017)+Period(i*6, Months) for i in range(0, 10)]`
Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.