I want to calculate yield of bond having market price and coupons. I try to replicate C++ from (https://mhittesdorf.wordpress.com/2013/03/03/introducing-quantlib-internal-rate-of-return/) in Python but without success. How to use "bisection" solver in quantlib-python?
solver = ql.Bisection()
solver_max = 0.5
solver_min = 0.1
solver_maxEvaluations = 1000
solution = solver.solve(?, solver_maxEvaluations, solver_min, solver_max)
NotImplementedError: Wrong number or type of arguments for overloaded function 'Bisection_solve'.
Possible C/C++ prototypes are:
Bisection::solve(PyObject *,Real,Real,Real)
Bisection::solve(PyObject *,Real,Real,Real,Real)
What is the "PyObject*" in this case?
Answer
In the call to Bisection.solve
, the question mark must be the Python function whose zero you want to find. In your case, it should be something reproducing the logic of IRRSolver::operator()
in Mick Hittesdorf's code, i.e., something like this (which I haven't tested):
cashflows = fixedRateBond.cashflows()
npv = fixedRateBond.NPV()
def price_error_given_yield(rate):
interestRate = InterestRate(rate, ActualActual(ActualActual.Bond),
Compounded, Annual)
return CashFlows.npv(cashflows, interestRate, False) - npv
irr = solver.solve(price_error_given_yield, accuracy, guess, min, max)
The idea is that you write a function that takes a yield and tells you how much the corresponding price differs from the target price; the solver takes the function and returns its zero, that is, the value of the input yield for which the result (i.e. the difference from the target price) is zero.
This said, Mick's approach is useful for educational purposes but it duplicates functionality that is already available from the bond object. All you need is to call
fixedRateBond.bondYield(targetPrice, ActualActual(ActualActual.Bond),
Compounded, Annual)
Note, though, that the targetPrice
above should be the clean price, so in your case what's returned by fixedRateBond.cleanPrice()
rather than fixedRateBond.NPV()
.
No comments:
Post a Comment