0

I am trying to calculate the yield to maturity for bonds (working in Google Colab (Jupyter)). The mathematical formulation of the problem is: enter image description here with price = $1276.76, number of periods = 60 [0.5 years] = 30 years, payment per period = $40 and final payment(par value) = $1000 and interest rate = r.

Where I am trying to derive the "r" through a function.
When going for an approach with hardcoding the formula and function I found herefore:

# Yield to maturity

""" Get yield-to-maturity of a bond """
import scipy.optimize as optimize


def bond_ytm(price, par, T, coup, freq=2, guess=0.05):
    freq = float(freq)
    periods = T*freq
    coupon = coup/100.*par/freq
    dt = [(i+1)/freq for i in range(int(periods))]
    ytm_func = lambda(y): \
        sum([coupon/(1+y/freq)**(freq*t) for t in dt]) + \
        par/(1+y/freq)**(freq*t) - price
        
    return optimize.newton(ytm_func, guess)
from bond_ytm import bond_ytm
ytm = bond_ytm(95.0428, 100, 1.5, 5.75, 2)
print(ytm)

I get the error: "invalid syntax" in the lambda line and when removing it (in order to check if the function itself works) "no module named 'bond_ytm'" even saving it as extra file in the same directory as (.jpynb) python file. I did also not understand the lambda in-line function, the dt array/for-loop, and where and why the bond_ytm is called from.

Here is a very similar approach form github, which also did not run, using another function for the second part:
https://github.com/jamesmawm/Mastering-Python-for-Finance-source-codes/blob/master/B03898_05_Codes/bond_ytm.py

if __name__ == "__main__":
    ytm = bond_ytm(95.0428, 100, 1.5, 5.75, 2)
    print ytm

And which left me with the same missing understanding.

Here is a large documentation to a package, where I can't know their methodology of calculation, but where I can enter the dates of the period manually and which allows for computing accrued interest between the payment (coupon) dates. https://bond-pricing.readthedocs.io/en/latest/#module-bond_pricing.simple_bonds:

>>> bond_yield(settle="2012-04-15", mat="2022-01-01", cpn=8e-2,
... price=94.33, freq=1)
0.08884647275135965

>>> bond_yield(mat=10.25, cpn=8e-2, price=93.37, freq=2)
0.09000591604105035

>>> bond_yield(settle="2012-04-15", mat="2022-01-01", cpn=8e-2,
... price=[93, 94, 95], freq=1)
array([0.09104904, 0.08938905, 0.08775269])

Wurschti
  • 23
  • 2
  • 9
  • There are some very outdated discussions on this topic - unrelated to python and without code: https://stackoverflow.com/questions/14689092/financial-calculate-yield-to-maturity and https://stackoverflow.com/questions/1173555/open-source-financial-library-specifically-yield-to-maturity – Wurschti Mar 01 '21 at 23:22
  • Please repeat [on topic](https://stackoverflow.com/help/on-topic) and [how to ask](https://stackoverflow.com/help/how-to-ask) from the [intro tour](https://stackoverflow.com/tour). I'm not clear what your question is through all of this. You have a problem with importing your module -- but without the details of your environment, we can only guess at the issue, and those guesses are already documented in readily available resources on line. You plead a lack of understand on two or three points -- both the open-ended "I don't get this" and the multiple points are out of scope on this site. – Prune Mar 01 '21 at 23:28
  • @Prune thank you. My problem is that I want to calculate a YTM - yield to maturity. The library "bond_pricing" seems to do it, but I do not know how they calculate it and I would like to it manually. I found codes without documentation/comments to do so as described above. But I was unable to run them and got an "invalid syntax" error in the lambda line, looking at several explanations of lambda I did not get to understand and fix the error. I have added some similar sites and codes in my post for people to get an easier context and similar approaches and be able to help me better. – Wurschti Mar 02 '21 at 09:15
  • @Wurschti Did you found out solution to bond_ytm. I am also facing a similar issue with lambda function. Can you please suggest work around which helped you to solve this issue. Thanks – Add Jul 17 '21 at 06:38

1 Answers1

1

If what you want to find is the internal rate of return, there is a numpy financial library (that needs to be installed with pip) that will find that.

>>> import numpy_financial as npf
>>> npf.irr([-1276.76] + [40]*60 + [1000])
0.02985264673122634
Chris Charley
  • 6,403
  • 2
  • 24
  • 26
  • Cool, thank you, the numpy financial library I will definitely look at. The IRR here is easy to calculate. But if I have a bond that pays twice per year 40$. The yield (or interest rate) is different depending on how close the current date is to the payment date. The day before the payment the expected yield is higher than a week or a month before the next payment. So I want to account for accrued interest. (accumulated theoretical interest by waiting for the next payment) – Wurschti Mar 02 '21 at 09:08