Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The cash flows of FloatingRateBond are different from my expectation #305

Open
xuruilong100 opened this issue Aug 18, 2020 · 3 comments
Open

Comments

@xuruilong100
Copy link

xuruilong100 commented Aug 18, 2020

If the curve is flat.

import QuantLib as ql
import prettytable as pt
from datetime import date

print(ql.__version__)

'''
1.19
'''

today = ql.Date(28, ql.July, 2020)
ql.Settings.instance().evaluationDate = today

settlementDays = 1
faceAmount = 100.0

effectiveDate = ql.Date(9, ql.June, 2020)
terminationDate = ql.Date(9, ql.June, 2025)
tenor = ql.Period(ql.Quarterly)
calendar = ql.China(ql.China.IB)
convention = ql.Unadjusted
terminationDateConvention = convention
rule = ql.DateGeneration.Backward
endOfMonth = False

schedule = ql.Schedule(
    effectiveDate,
    terminationDate,
    tenor,
    calendar,
    convention,
    terminationDateConvention,
    rule,
    endOfMonth)

nextLpr = 4.0 / 100.0
fixedLpr = 4.0 / 100.0

compounding = ql.Compounded
frequency = ql.Quarterly
accrualDayCounter = ql.ActualActual(ql.ActualActual.Bond, schedule)
dayCounter = ql.ActualActual(ql.ActualActual.Bond, schedule)
paymentConvention = ql.Unadjusted
fixingDays = 1
gearings = ql.DoubleVector(1, 1.0)
spreads = ql.DoubleVector(1, 0.0 / 100.0)

lprTermStructure = ql.YieldTermStructureHandle(
    ql.FlatForward(
        settlementDays,
        calendar,
        nextLpr,
        dayCounter,
        compounding,
        frequency))

lpr3m = ql.IborIndex(
    'LPR1Y',
    ql.Period(ql.Quarterly),
    settlementDays,
    ql.CNYCurrency(),
    calendar,
    convention,
    endOfMonth,
    dayCounter,
    lprTermStructure)

lpr3m.addFixing(ql.Date(8, ql.June, 2020), fixedLpr)

bond = ql.FloatingRateBond(
    settlementDays,
    faceAmount,
    schedule,
    lpr3m,
    accrualDayCounter,
    convention,
    fixingDays,
    gearings,
    spreads)

cfTab = pt.PrettyTable(['Date', 'Amount'])

for c in bond.cashflows():
    dt = date(
        c.date().year(),
        c.date().month(),
        c.date().dayOfMonth())
    cfTab.add_row([dt, c.amount()])

print(cfTab)

'''
1.19
+------------+--------------------+
|    Date    |       Amount       |
+------------+--------------------+
| 2020-09-09 |        1.0         |
| 2020-12-09 | 1.0000000000000009 |
| 2021-03-09 | 1.0000000000000009 |
| 2021-06-09 | 1.0000000000000009 |
| 2021-09-09 | 1.000000000000023  |
| 2021-12-09 | 0.9999999999999787 |
| 2022-03-09 | 1.0000000000000009 |
| 2022-06-09 | 1.0000000000000009 |
| 2022-09-09 | 1.0000000000000009 |
| 2022-12-09 | 1.0000000000000009 |
| 2023-03-09 | 1.0000000000000009 |
| 2023-06-09 | 1.0000000000000009 |
| 2023-09-09 | 1.000109533621161  |
| 2023-12-09 | 1.0000000000000009 |
| 2024-03-09 | 0.9999988095049638 |
| 2024-06-09 | 0.9999458343873505 |
| 2024-09-09 | 0.9999458343873505 |
| 2024-12-09 | 1.0000000000000009 |
| 2025-03-09 | 1.0000541695215703 |
| 2025-06-09 | 0.9999458343873505 |
| 2025-06-09 |       100.0        |
+------------+--------------------+
'''

The cash flow at 2023-09-09 is quite different from my expectation, I think it should be 1.0000000000000009.

@boring-cyborg
Copy link

boring-cyborg bot commented Aug 18, 2020

Thanks for posting! It might take a while before we look at your issue, so don't worry if there seems to be no feedback. We'll get to it.

@xuruilong100 xuruilong100 changed the title The cash flows of The cash flows of FloatingRateBond are different from my expection Aug 18, 2020
@xuruilong100 xuruilong100 changed the title The cash flows of FloatingRateBond are different from my expection The cash flows of FloatingRateBond are different from my expectation Aug 18, 2020
@nhaga
Copy link

nhaga commented Aug 28, 2020

if you define your day counters without the schedule as parameter you will get the values you were expecting.

accrualDayCounter = ql.ActualActual(ql.ActualActual.Bond)
dayCounter = ql.ActualActual(ql.ActualActual.Bond)

@xuruilong100
Copy link
Author

if you define your day counters without the schedule as parameter you will get the values you were expecting.

accrualDayCounter = ql.ActualActual(ql.ActualActual.Bond)
dayCounter = ql.ActualActual(ql.ActualActual.Bond)

Yes, you are right.

But the curve is flat, no matter how the forward rate is calculated, it should be 1.0.

The cash flows are created by FloatingLeg, I chack the code, it can not use refStart and refEnd in this case.

While, if I define day counters with the schedule, they can use refStart and refEnd, please see here: https://quant.stackexchange.com/questions/12707/pricing-a-fixedratebond-in-quantlib-yield-vs-termstructure

So, there is inconsistence.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants
@lballabio @nhaga @xuruilong100 and others