Search code examples
pythonfinance

For-loop for discounting bond coupons


Quick question on how to write a for-loop to give me the present value (i.e. discounted value) of all coupons. My code looks like this:

i want a for-loop to do the operation

c[0]*np.exp(-r*1)
c[1]*np.exp(-r*2)
c[2]*np.exp(-r*3) 

and so on (the number times -r is always the index +1). i want a sum of all values e.g. using x+= the for-loop iteration

c=[7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5]
r=0.071
PVx=0 

for i in c:
    print(i)
    year = c.index(i)+1
    print(year)
    PV=c[i]*np.exp(-r*year)
    PVx += PV 
    print(PVx)

Somehow I'm getting the error code "TypeError: list indices must be integers or slices, not float" for my PV variable. In essence, I want to have each value in my list be multiplied by np.exp(-r* index position +1) and then to get the sum :S

EDIT:

My new code

import numpy as np
c=[7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5]
r=0.071
PVx=0 

for i in c:
    year = c.index(i)+1
    print(year)
    PV=i*np.exp(-r*year)
    PVx += PV
    print(PVx)

keeps printing the year as 1 (meaning c.index(i) yields 0 +1 = 1), while I would expect it to go from 1 to 7. I guess that my problem right now.


Solution

  • My new code [...] keeps printing the year as 1 (meaning c.index(i) yields 0 +1 = 1), while I would expect it to go from 1 to 7.

    list.index(i) returns the first index where i appears, or -1 if i isn't in the list.


    NumPy solution:

    import numpy as np
    
    r = 0.071
    
    arr_1 = np.full(shape=7, fill_value=7.5)
    print(arr_1)
    
    arr_2 = np.exp(-r * np.arange(1, arr_1.shape[0] + 1))
    print(arr_2)
    
    arr_3 = arr_1 * arr_2
    print(arr_3)
    print(arr_3.sum())
    

    Output:

    [7.5 7.5 7.5 7.5 7.5 7.5 7.5]
    [0.93146189 0.86762126 0.80815614 0.75276664 0.70117344 0.65311634
     0.60835298]
    [6.98596419 6.50715942 6.06117103 5.64574984 5.25880082 4.89837257
     4.56264738]
    39.919865247574606
    

    Looping solution:

    import math
    from pprint import pprint
    
    r = 0.071
    
    vals = [7.5 * math.exp(-r * i) for i in range(1, 8)]
    
    pprint(vals)
    pprint(sum(vals))
    

    Output:

    [6.985964190956941,
     6.507159423644355,
     6.0611710291236625,
     5.645749835296472,
     5.258800824064293,
     4.898372565905067,
     4.562647378583822]
    39.919865247574606
    

    I'm not entirely certain that I understood what you're trying to do, so let me know if I'm missing anything.