contents

4.11

2004-05-23

by hand

(a)

kskd0,k=dk=1/(1+sk)kxkxk*d0,k
01-40-40
15.00.952109.52
25.30.902109.02
35.60.849108.49
45.80.798107.98
56.00.747107.47
66.10.701107.01
∴PV=9.49

(b)

kskfk-1,k=(1+sk)k/(1+sk-1)k-1-1dk-1,k=1/(1+fk-1,k)
15.05.00.952
25.35.60.947
35.66.20.942
45.86.40.940
56.06.80.936
66.16.60.938
PV(6) =  10
PV(5) =  10 + 0.938 * 10.00 = 19.38
PV(4) =  10 + 0.936 * 19.38 = 28.14
PV(3) =  10 + 0.940 * 28.14 = 36.45
PV(2) =  10 + 0.942 * 36.45 = 44.34
PV(1) =  10 + 0.947 * 44.34 = 51.99
PV(0) = -40 + 0.952 * 51.99 =  9.49

Python

(added on 2015-04-11.)

(a)

code


# 4.11.py
# 20:33 2015-04-11
#
# x, cash flow stream
# s, spot rates
# d, discount factor
# pv, present value

# input
x = [-40, 10,  10,  10,  10,  10,  10 ]
s = [  0, 5.0, 5.3, 5.6, 5.8, 6.0, 6.1]

# calculate
s  = list(map(lambda x: x / 100, s))
d  = [ 1 / (1 + s[i])**i for i in range(len(s)) ]
xd = [ x[i] * d[i] for i in range(len(x)) ]
pv = sum(xd)

# output
fmt1 = "{:>10}{:>10}{:>10}{:>10}{:>10}"
fmt2 = "{:10d}{:10.3f}{:10.2f}{:10.0f}{:10.2f}"
print(fmt1.format("k", "s", "d", "x", "x*d"))
print(50 * "-")
for i in range(len(x)):
  print(fmt2.format(i, s[i], d[i], x[i], xd[i]))
print(50 * "-")
print("{:>40}{:10.2f}".format("pv=", pv))
# eof

output


         k         s         d         x       x*d
--------------------------------------------------
         0     0.000      1.00       -40    -40.00
         1     0.050      0.95        10      9.52
         2     0.053      0.90        10      9.02
         3     0.056      0.85        10      8.49
         4     0.058      0.80        10      7.98
         5     0.060      0.75        10      7.47
         6     0.061      0.70        10      7.01
--------------------------------------------------
                                     pv=      9.50

(b)

code


# 4.11b.py
# 22:12 2015-04-11
#
# d,  discount factors
# f,  forward rates
# pv, present values
# s,  spot rates
# x,  cash flow stream

def fij(i, j): # text book in Japanese(p.97)
  return ((1 + s[j])**j / (1 + s[i])**i)**(1 / (j - i))-1

# input
x = [-40, 10,  10,  10,  10,  10,  10 ]
s = [  0, 5.0, 5.3, 5.6, 5.8, 6.0, 6.1]

# calculate
s = [ s[i] / 100 for i in range(len(s)) ]
f = [[0 for j in range(len(x))] for i in range(len(x) - 1)]
for i in range(len(s) - 1):
  f[i][i+1] = fij(i, i+1)

d = [[0 for j in range(len(x))] for i in range(len(x) - 1)]
for i in range(len(f)):
  d[i][i+1] = 1 / (1 + f[i][i+1])

pv = [0 for i in range(len(x))]
pv[6] = x[6]
pv[5] = x[5] + d[5][6] * pv[6]
pv[4] = x[4] + d[4][5] * pv[5]
pv[3] = x[3] + d[3][4] * pv[4]
pv[2] = x[2] + d[2][3] * pv[3]
pv[1] = x[1] + d[1][2] * pv[2]
pv[0] = x[0] + d[0][1] * pv[1]

print("x", x)
print("s", s)
for i in range(len(f)):
  print("f(", i, ",", i+1, ")=", round(f[i][i+1], 3))
for i in range(len(d)):
  print("d(", i, ",", i+1, ")=", round(d[i][i+1], 3))
for i in reversed(range(len(pv))):
  print("PV(", i, ")=", round(pv[i], 2))
print("")

# output
fmt1 = "{:9s}{:^63s}"
fmt2 = "{:9s}{:63s}"
fmt3 = "{:9s}{:9d}{:9d}{:9d}{:9d}{:9d}{:9d}{:9d}"
fmt4 = "{:9s}{:9.3f}{:9.3f}{:9.3f}{:9.3f}{:9.3f}{:9.3f}"
fmt5 = "{:9s}{:9.2f}{:9.2f}{:9.2f}{:9.2f}{:9.2f}{:9.2f}{:9.2f}"
keisen1 = 72 * "-"
keisen2 = 63 * "-"
print(keisen1)
print(fmt1.format("", "Year k"))
print(fmt2.format("", keisen2))
print(fmt3.format("", *[i for i in range(len(x))]))
print(keisen1)
print(fmt3.format("Cash flow", *x))
print(fmt4.format("Discount", *[d[i][i+1] for i in range(len(d))]))
print(fmt5.format("PV(k)", *pv))
print(keisen1)
# eof

output


x [-40, 10, 10, 10, 10, 10, 10]
s [0.0, 0.05, 0.053, 0.055999999999999994, 0.057999999999999996, 0.06, 0.061]
f( 0 , 1 )= 0.05
f( 1 , 2 )= 0.056
f( 2 , 3 )= 0.062
f( 3 , 4 )= 0.064
f( 4 , 5 )= 0.068
f( 5 , 6 )= 0.066
d( 0 , 1 )= 0.952
d( 1 , 2 )= 0.947
d( 2 , 3 )= 0.942
d( 3 , 4 )= 0.94
d( 4 , 5 )= 0.936
d( 5 , 6 )= 0.938
PV( 6 )= 10
PV( 5 )= 19.38
PV( 4 )= 28.15
PV( 3 )= 36.45
PV( 2 )= 44.32
PV( 1 )= 51.97
PV( 0 )= 9.5

------------------------------------------------------------------------
                                     Year k                             
         ---------------------------------------------------------------
                 0        1        2        3        4        5        6
------------------------------------------------------------------------
Cash flow      -40       10       10       10       10       10       10
Discount     0.952    0.947    0.942    0.940    0.936    0.938
PV(k)         9.50    51.97    44.32    36.45    28.15    19.38    10.00
------------------------------------------------------------------------

code 2

by recursive function, added on 2016-04-03


# 4.11b2.py
# 2016-04-02
#
# d,  discount factors
# f,  forward rates
# pv, present value function
# s,  spot rates
# x,  cash flow stream

# input
x = [-40, 10,  10,  10,  10,  10,  10 ]
s = [  0, 5.0, 5.3, 5.6, 5.8, 6.0, 6.1]	# unit: %

# define function
def pv(k, x, d):	# running present value (recursive)
  if(k == len(x)-1):
    return x[k]
  else:
    return x[k] + d[k + 1] * pv(k + 1, x, d)

# calculate
s = [ s[i] / 100 for i in range(len(s)) ]
f = [ 0          for i in range(len(s)) ]
for i in range(1, len(s)):
  f[i] = ((1 + s[i]) ** i)/((1 + s[i - 1]) ** (i - 1)) - 1
d = [ 1 / (1 + f[i]) for i in range(len(s))]

# output
fmt1 = '{:>10}{:>10}{:>10}{:>10}{:>10}'
fmt2 = '{:10d}{:10d}{:10.3f}{:10.3f}{:10.3f}'
print("4.11b2.py")
print("input")
print(fmt1.format('k','x[k]','s[k]', 'f[k-1,k]', 'd[k-1,k]'))
print(5 * '----------')
for i in reversed(range(len(x))):
  print(fmt2.format(i, x[i], s[i], f[i], d[i]))
print(5 * '----------')
print()
print("output")
print("pv= ", '{:10.3f}'.format(pv(0, x, d)),
      "(by running present value, with a recursive function.)")
# eof

output 2


4.11b2.py
input
         k      x[k]      s[k]  f[k-1,k]  d[k-1,k]
--------------------------------------------------
         6        10     0.061     0.066     0.938
         5        10     0.060     0.068     0.936
         4        10     0.058     0.064     0.940
         3        10     0.056     0.062     0.942
         2        10     0.053     0.056     0.947
         1        10     0.050     0.050     0.952
         0       -40     0.000     0.000     1.000
--------------------------------------------------

output
pv=       9.498 (by running present value, with a recursive function.)

Gauche

2016-03-27.

(a) code

2024-11-02 4.11a.scm

(b) code

added on 2016-03-27, revised on 2016-03-30, 2016-04-03.

(by recursive function) 4.11b2.scm

JavaScript

2024-11-02 4.11.js

Julia

2024-11-02 4.11.jl

Fortran

2024-11-02 4.11.f90


history

2004-05-23, revised on 2015-04-12, 2016-03-30, 2016-04-03, 2016-10-15.
2016-10-15 Gauche code linked.
2021-02-17 change XHTML to html5, change shift-jis to utf-8, add viewport.
2024-11-02 revise the Gauche code; add a JavaScript code, a Julia code and a Fortran code.