I am trying to learn QuantLib for Python but I must say I am banging my head against the documentation (I also bought Ballabio's python cookbook) - maybe it's me, but even finding the most basic concepts seems a struggle.
How can I do something as banal as discounting a set of irregular cashflows? The cashflows could be anything - the returns from a real estate investment, an asset-backed bond, etc.
The code below runs without any errors, but the result is... zero!
What I have done:
I have defined the cashflows with SimpleCashFlow - is that the right class to use?
I then use a FlatForward to define a flat yield curve.
What I use for discount_curve is taken from page 57 of the Python cookbook.
I looked for examples of how CashFlows.npv works, but I couldn't find any here https://quantlib-python-docs.readthedocs.io/en/latest/termstructures.html#yield-term-structures and this other page https://rkapl123.github.io/QLAnnotatedSource/d8/d7d/class_quant_lib_1_1_cash_flows.html isn't the clearest.
My questions:
- What am I doing wrong?
- Should calc_date be... what? The date of the first cashflow? I have tried that, I have tried days before, nothing.
- does FlatForward(calc_date, rate, ql.ActualActual()) define a yield curve from calc_date to infinity? Or do we need to specify a start date and an end date for the curve?
- is there any way to inspect / debug the SimpleCashFlow instances ( I use Spyder)? cfs[0] returns
<QuantLib.QuantLib.SimpleCashFlow; proxy of <Swig Object of type 'ext::shared_ptr< SimpleCashFlow > *' at 0x0000021354440B40> >
but how can I check what date and values are really there?
This is the code:
import QuantLib as ql
d1 = ql.Date(15,1,2011)
cfs = [ql.SimpleCashFlow(10, d1),
ql.SimpleCashFlow(10, d1 + 365),
ql.SimpleCashFlow(110, d1 + 365*2)]
calc_date = ql.Date(15,1,2011)
risk_free_rate = 0.05
discount_curve = ql.YieldTermStructureHandle(
ql.FlatForward(calc_date, risk_free_rate, ql.ActualActual()))
# WHY is this zero??
pv = ql.CashFlows.npv(cfs, discount_curve, True)