Skip to content
All library documents

Discounting Cash Flows with Zero-Coupon Yield Curves in QuantLib

Article Quant Q&A · Author: Leonardo Cruciani

Summary

This document describes a question about valuing a dated leg of cash flows using a zero-coupon yield curve in QuantLib. The curve is built from supplied dates and rates with linear interpolation, annual compounding, and an Actual/Actual ISDA day-count convention. The user then asks why QuantLib’s discount factors differ slightly from values produced by a manually applied compounding formula.

The document supplies the curve setup, cash-flow dates and amounts, and the competing discounting expression, so it illustrates how curve conventions and calculation assumptions can affect present values. However, it contains no answer or resolution explaining the discrepancy. It therefore serves as a problem statement rather than a complete method. Its relevance is to fixed-income valuation and implementation details; the example does not provide evidence about trading performance or establish which set of discount factors is correct.

Key ideas

  • A zero curve can be constructed from dated zero rates with a specified day count and compounding convention.
  • Discount factors for cash flows are obtained by querying the curve at each payment date.
  • The question compares QuantLib output with a manually interpolated and compounded calculation.
  • The document does not resolve the discrepancy or establish which convention explains it.

Tags

Full text
# QuantLib: Getting the present value of a leg of cashflows using a 'risk-free' yield curve


# QuantLib: Getting the present value of a leg of cashflows using a 'risk-free' yield curve












I am trying to evaluate the present value of some cashflows and QuantLib does not return the discount factors that I am expecting.

I have a Risk Free (Zero Coupon Bond) Yield curve:

```
import QuantLib as ql

dates = [Date(1,12,2022), Date(2,12,2022), Date(1,1,2023), Date(1,2,2023), Date(1,3,2023), Date(1,4,2023), Date(1,5,2023), Date(1,6,2023)]
rates = [0.0, 0.0059, 0.0112, 0.0160, 0.0208, 0.0223, 0.0239, 0.0254]
```

So I create a QuantLib ZeroCurve:

```
discount_curve_day_count = ql.ActualActual(ql.ActualActual.ISDA)
discount_curve_compounding_frequency = ql.Annual
discount_curve_compounding_type = ql.Compounded
calendar = ql.NullCalendar()

zero_curve = ql.ZeroCurve(dates,rates, discount_curve_day_count,calendar, ql.Linear(),discount_curve_compounding_type,discount_curve_compounding_frequency)
```

I define the Leg of Cashflows:

```
cf_dates = [Date(18,1,2023), Date(18,2,2023), Date(18,3,2023), Date(18,4,2023), Date(18,5,2023), Date(18,6,2023), Date(18,7,2023), Date(18,8,2023), Date(18,9,2023), Date(18,10,2023), Date(18,11,2023), Date(18,12,2023), Date(18,1,2024), Date(18,2,2024), Date(18,3,2024), Date(18,4,2024), Date(18,5,2024), Date(18,6,2024), Date(18,7,2024), Date(18,8,2024), Date(18,9,2024), Date(18,10,2024), Date(18,11,2024), Date(18,12,2024), Date(18,1,2025)]

cf_amounts = [-30000.0, 203.84, 184.11, 203.84, 634.37, 634.37, 634.37, 634.37, 634.37, 634.37, 634.37, 634.37, 634.37, 634.37, 634.37, 634.37, 634.37, 634.37, 634.37, 634.37, 634.37, 634.37,634.37, 634.37, 634.37]

cf= []
for i in range(len(cf_dates)):
    cashflow = ql.SimpleCashFlow(cf_dates[i], cf_amounts[i])
    cf.append(cashflow) 

leg = ql.Leg(cf)
```

And I want to evaluate the discount factors at the cashflow dates:

```
for cf in leg:
    print(cf.date(), zero_curve.discount(cf.date()))
```

Unfortunately, the values I get are slightly off (error=0.02) from the expected ones, calculated using the following compounding formula:

$$ d = \frac{1}{(1+r)^y \left( 1+r\frac{d_p}{d_y} \right)} $$

where $r$ is the linearly interpolated rate from the curve, $y$ is the number of years that have passed from the first cashflow date, $d_p$ is the number of days that have passed from the previous payment and $d_y$ the number of days in the year in which the payment occurs (all of these are calculated using Act/Act ISDA daycount convention).

Any chance I can get those numbers right using QuantLib?

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.