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?

  • $\begingroup$ Hi Kirill Dolmatov, welcome to Quant.SE! Without looking the QuantLib why of doing things probably makes sense. Why don't you try to fix that. As it stands the question is: are there other ways? Which is pretty vague and can be answered with: Yes $\endgroup$
    – Bob Jansen
    Commented Apr 12, 2016 at 16:57
  • $\begingroup$ Maybe more of a programming question but I think the API of QuantLib is on-topic here. $\endgroup$
    – Bob Jansen
    Commented Apr 13, 2016 at 14:03
  • $\begingroup$ PYobject is just a wrapper for quantlib in Python. $\endgroup$
    – SmallChess
    Commented Apr 13, 2016 at 16:18
  • $\begingroup$ Have you tried getting rid of the question mark? Your error message is pretty obvious. $\endgroup$
    – SmallChess
    Commented Apr 13, 2016 at 16:20
  • $\begingroup$ @StudentT , I put the question mark because I don't know what I should to put. I try to put "ql.FixedRateBond" but then get "RuntimeError: failed to call Python function". It's pretty obvious that if I put question mark I get "SyntaxError: invalid syntax". Have you any idea that I should to put? $\endgroup$ Commented Apr 14, 2016 at 7:16

1 Answer 1


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().

  • $\begingroup$ Do you have an example of how to define fixedRateBond to get access to bondYield and cleanPrice methods? When I try to do this myself, it gives an error null price engine because it requires setting an engine, which also requires definition... however, I am more interested in replicating the excel YIELD function here support.office.com/en-us/article/… which doesn't require defining such engine nor the yield term structure... $\endgroup$
    – tsando
    Commented Sep 14, 2017 at 14:17
  • 1
    $\begingroup$ You need to use the overload of bondYield that takes the clean price as an input (that is, bond.bondYield(price, day_count, compounding, frequency)). If you use the other overload (bond.bondYield(day_count, compounding, frequency)) the bond tries to calculate the price and thus needs an engine. $\endgroup$ Commented Sep 14, 2017 at 15:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.