Financial Mathematics 1 - Homework 13

Instructor: Dr. Le Nhat Tan


1 Functions

stock_tree = function(stock, up, down, n) {
  tree = matrix(0, nrow = n, ncol = n)
  for (i in 1:n) {
    for (j in 1:i) {
      tree[i,j] = stock * up^(j - 1) * down^((i - 1) - (j - 1))
    }
  }
  return(tree)
}

European_call = function(stock_tree, p, r, delta_t, strike) {
  tree = matrix(0, nrow = nrow(stock_tree), ncol = nrow(stock_tree))
  tree[nrow(tree),] = pmax(stock_tree[nrow(stock_tree),] - strike, 0)
  for (i in (nrow(tree) - 1):1) {
    for (j in 1:i) {
      tree[i, j] = ((1 - p) * tree[i + 1, j] + 
                      p * tree[i + 1, j + 1])/exp(r * delta_t)
    }
  }
  return(tree)
}

European_put = function(stock_tree, p, r, delta_t, strike) {
  tree = matrix(0, nrow = nrow(stock_tree), ncol = nrow(stock_tree))
  tree[nrow(tree),] = pmax(strike - stock_tree[nrow(stock_tree),], 0)
  for (i in (nrow(tree) - 1):1) {
    for (j in 1:i) {
      tree[i, j] = ((1 - p) * tree[i + 1, j] + 
                      p * tree[i + 1, j + 1])/exp(r * delta_t)
    }
  }
  return(tree)
}

American_call = function(stock_tree, p, r, delta_t, strike) {
  tree = matrix(0, nrow = nrow(stock_tree), ncol = nrow(stock_tree))
  tree[nrow(tree),] = pmax(stock_tree[nrow(stock_tree),] - strike, 0)
  for (i in (nrow(tree) - 1):1) {
    for (j in 1:i) {
      no_exercise = ((1 - p) * tree[i + 1, j] +
                       p * tree[i + 1, j + 1])/exp(r * delta_t)
      
      tree[i, j] = max(stock_tree[i, j] - strike, no_exercise)
    }
  }
  return(tree)
}

American_put = function(stock_tree, p, r, delta_t, strike) {
  tree = matrix(0, nrow = nrow(stock_tree), ncol = nrow(stock_tree))
  tree[nrow(tree),] = pmax(strike - stock_tree[nrow(stock_tree),], 0)
  for (i in (nrow(tree) - 1):1) {
    for (j in 1:i) {
      no_exercise = ((1 - p) * tree[i + 1, j] +
                       p * tree[i + 1, j + 1])/exp(r * delta_t)
      tree[i, j] = max(strike - stock_tree[i, j], no_exercise)
    }
  }
  return(tree)
}

2 Slide 52

Consider the PDR stock with price \(27,500\) VND on 15/12/2018. An investor anticipates that PDR price will be higher than \(25,000\) VND on 15/06/2019. The investor thus decided to buy a European call option written on PDR on 15/12/2018, maturing on 15/06/2019, with strike price K = \(25,000.\) Assume that the risk-free interest rate \(r\) is \(7\%\) p.a. compounded continuously.

  1. Using the historical PDR price from 15/12/2014 to 15/12/2018 to estimate the volatility of the stock.
  2. Compute the option price at each node of \(4-\)step CRR binomial tree model.
  3. Write an R code to verify your above answer.
  4. Write an R code to compute the option price at inception using \(500-\)step CRR binomial tree model.
  5. Write an R code to illustrate the change of option price at inception as the number of steps of binomial tree increases from \(3\) steps to \(500\) steps.

Solution.

PDR = tq_get(symbol = 'PDR', from = '2014-12-15', to = '2018-12-15',
             src = 'CAFEF')
glimpse(as.data.frame(PDR))
sigma = sd(PDR$adjusted) / sqrt(4)
sigma
## [1] 1.636962
time = 1
delta_t = time / 4
u = exp(sigma * sqrt(delta_t))
d = exp(-sigma * sqrt(delta_t))
price = 27.5
st = stock_tree(price, u, d, 5)
st
##           [,1]      [,2]      [,3]     [,4]     [,5]
## [1,] 27.500000  0.000000   0.00000   0.0000   0.0000
## [2,] 12.130282 62.343973   0.00000   0.0000   0.0000
## [3,]  5.350682 27.500000 141.33713   0.0000   0.0000
## [4,]  2.360192 12.130282  62.34397 320.4188   0.0000
## [5,]  1.041084  5.350682  27.50000 141.3371 726.4067
k = 25
r = 0.07
p = (exp(r * delta_t) - d) / (u - d)
European_call(st, p, r, delta_t, k)
##            [,1]       [,2]      [,3]     [,4]     [,5]
## [1,] 16.4999440  0.0000000   0.00000   0.0000   0.0000
## [2,]  3.9605774 44.5954802   0.00000   0.0000   0.0000
## [3,]  0.2406795 12.2430958 117.19699   0.0000   0.0000
## [4,]  0.0000000  0.7756924  37.77767 295.8525   0.0000
## [5,]  0.0000000  0.0000000   2.50000 116.3371 701.4067
European_call(st, p, r, delta_t, k)[1][1]
## [1] 16.49994
delta_t = time / 500
u = exp(sigma * sqrt(delta_t))
d = exp(-sigma * sqrt(delta_t))
st = stock_tree(price, u, d, 501)
st[1:5, 1:5]
##          [,1]     [,2]     [,3]     [,4]     [,5]
## [1,] 27.50000  0.00000  0.00000  0.00000  0.00000
## [2,] 25.55873 29.58872  0.00000  0.00000  0.00000
## [3,] 23.75449 27.50000 31.83608  0.00000  0.00000
## [4,] 22.07762 25.55873 29.58872 34.25414  0.00000
## [5,] 20.51912 23.75449 27.50000 31.83608 36.85586
p = (exp(r * delta_t) - d) / (u - d)
European_call(st, p, r, delta_t, k)[1:5, 1:5]
##          [,1]     [,2]     [,3]     [,4]     [,5]
## [1,] 17.06946  0.00000  0.00000  0.00000  0.00000
## [2,] 15.47466 18.78379  0.00000  0.00000  0.00000
## [3,] 14.01437 17.04436 20.65365  0.00000  0.00000
## [4,] 12.67841 15.45037 18.75781 22.69168  0.00000
## [5,] 11.45732 13.99091 17.01917 20.62680 24.91149
European_call(st, p, r, delta_t, k)[1][1]
## [1] 17.06946
options = c()
for (i in 3:500) {
  delta_t = time / i
  u = exp(sigma * sqrt(delta_t))
  d = exp(-sigma * sqrt(delta_t))
  st = stock_tree(price, u, d, i + 1)
  p = (exp(r * delta_t) - d) / (u - d)
  oi = European_call(st, p, r, delta_t, k)[1][1]
  options = c(options, oi)
}
plot(x = 3:500, y = options, type = 'l',
     xlab = 'Step Count', ylab = 'Option Price')

3 Slide 55 - P1

A stock price is currently $\(40.\) Over each of the next two \(3-\)month periods it is expected to go up by \(10\%\) or down by \(10\%.\) The interest rate \(r\) is \(12\%\) p.a. with continuous compounding.

  1. What is the value of a \(6-\)month European put option with a strike price of $\(42?\)
  2. What is the value of a \(6-\)month American put option with a strike price of $\(42?\)

Solution.

time = 6 / 12
delta_t = time / 2
u = 1.1
d = 0.9
price = 40
st = stock_tree(price, u, d, 3)
st
##      [,1] [,2] [,3]
## [1,] 40.0  0.0  0.0
## [2,] 36.0 44.0  0.0
## [3,] 32.4 39.6 48.4
k = 42
r = 0.12
p = (exp(r * delta_t) - d) / (u - d)
European_put(st, p, r, delta_t, k)
##          [,1]     [,2] [,3]
## [1,] 2.118480 0.000000    0
## [2,] 4.758712 0.809881    0
## [3,] 9.600000 2.400000    0
European_put(st, p, r, delta_t, k)[1][1]
## [1] 2.11848
American_put(st, p, r, delta_t, k)
##          [,1]     [,2] [,3]
## [1,] 2.537353 0.000000    0
## [2,] 6.000000 0.809881    0
## [3,] 9.600000 2.400000    0
American_put(st, p, r, delta_t, k)[1][1]
## [1] 2.537353

4 Slide 55 - P2

A stock price is currently $\(30.\) During each \(2-\)month period for the next \(4\) months it will increase by \(8\%\) or reduce by \(10\%.\) The interest rate \(r\) is \(5\%.\)

  1. Use a \(2-\)step tree to calculate the value of a derivative that pays off \((\max(30-S_T,0))^2,\) where \(S_T\) is the stock price in 4 months.
  2. If the derivative is American-style, should it be exercised early?

Solution.

slide_55_P2_1 = function(stock_tree, p, r, delta_t, strike) {
  tree = matrix(0, nrow = nrow(stock_tree), ncol = nrow(stock_tree))
  tree[nrow(tree),] = pmax(strike - stock_tree[nrow(stock_tree),], 0)
  for (i in 1:nrow(tree)) {
    for (j in 1:nrow(tree)) {
      tree[i, j] = tree[i, j] ^ 2
    }
  }
  for (i in (nrow(tree) - 1):1) {
    for (j in 1:i) {
      tree[i, j] = ((1 - p) * tree[i + 1, j] + 
                      p * tree[i + 1, j + 1])/exp(r * delta_t)
    }
  }
  return(tree)
}
time = 4 / 12
delta_t = time / 2
u = 1.08
d = 0.9
price = 30
st = stock_tree(price, u, d, 3)
st
##      [,1]  [,2]   [,3]
## [1,] 30.0  0.00  0.000
## [2,] 27.0 32.40  0.000
## [3,] 24.3 29.16 34.992
k = 30
r = 0.05
p = (exp(r * delta_t) - d) / (u - d)
slide_55_P2_1(st, p, r, delta_t, k)
##           [,1]      [,2] [,3]
## [1,]  5.392846 0.0000000    0
## [2,] 13.243528 0.2784666    0
## [3,] 32.490000 0.7056000    0
slide_55_P2_1(st, p, r, delta_t, k)[1][1]
## [1] 5.392846
slide_55_P2_2 = function(stock_tree, p, r, delta_t, strike) {
  tree = matrix(0, nrow = nrow(stock_tree), ncol = nrow(stock_tree))
  tree[nrow(tree),] = pmax(strike - stock_tree[nrow(stock_tree),], 0)
  for (i in 1:nrow(tree)) {
    for (j in 1:nrow(tree)) {
      tree[i, j] = tree[i, j] ^ 2
    }
  }
  for (i in (nrow(tree) - 1):1) {
    for (j in 1:i) {
      no_exercise = ((1 - p) * tree[i + 1, j] + 
                       p * tree[i + 1, j + 1])/exp(r * delta_t)
      
      option = max(strike - stock_tree[i, j], no_exercise)
      tree[i, j] = option ^ 2
    }
  }
  return(tree)
}
slide_55_P2_2(st, p, r, delta_t, k)
##          [,1]       [,2] [,3]
## [1,] 4797.606 0.00000000    0
## [2,]  175.391 0.07754364    0
## [3,]   32.490 0.70560000    0

5 Slide 56

Consider the VNM stock with price \(135,000\) VND on 15/12/2018. An investor anticipates that VNM price will be much lower than \(145,000\) VND at some time during the next 3 months. The investor thus decided to buy an American put option written on VNM on 15/12/2018, maturing on 15/03/2019, with strike price K = \(145,000.\) Assume that the interest rate \(r\) is \(7\%\) p.a. compounded continuously.

  1. Using the historical VNM price from 15/12/2014 to 15/12/2018 to estimate the volatility of the stock.
  2. Compute the option price at each node of \(4-\)step CRR binomial tree model.
  3. Write an R code to verify your above answer.
  4. Write an R code to compute the option price at inception using \(500-\)step CRR binomial tree model.
  5. Write an R code to illustrate the change of option price at inception as the number of steps of binomial tree increases from \(3\) steps to \(500\) steps.

Solution.

VNM = tq_get(symbol = 'VNM', from = '2014-12-15', to = '2018-12-15',
             src = 'CAFEF')
glimpse(as.data.frame(VNM))
sigma = sd(VNM$adjusted) / sqrt(4)
sigma
## [1] 12.25059
time = 3 / 12
delta_t = time / 4
u = exp(sigma * sqrt(delta_t))
d = exp(-sigma * sqrt(delta_t))
price = 135
st = stock_tree(price, u, d, 5)
st
##              [,1]         [,2]      [,3]       [,4]     [,5]
## [1,] 1.350000e+02    0.0000000     0.000       0.00        0
## [2,] 6.313103e+00 2886.8530519     0.000       0.00        0
## [3,] 2.952242e-01  135.0000000 61732.745       0.00        0
## [4,] 1.380578e-02    6.3131028  2886.853 1320098.98        0
## [5,] 6.456098e-04    0.2952242   135.000   61732.74 28229124
k = 145
r = 0.07
p = (exp(r * delta_t) - d) / (u - d)
American_put(st, p, r, delta_t, k)
##          [,1]     [,2]      [,3] [,4] [,5]
## [1,] 142.1198   0.0000  0.000000    0    0
## [2,] 143.5192 126.2237  0.000000    0    0
## [3,] 144.7048 132.3093  9.043067    0    0
## [4,] 144.9862 138.6869  9.509504    0    0
## [5,] 144.9994 144.7048 10.000000    0    0
American_put(st, p, r, delta_t, k)[1][1]
## [1] 142.1198
delta_t = time / 500
u = exp(sigma * sqrt(delta_t))
d = exp(-sigma * sqrt(delta_t))
st = stock_tree(price, u, d, 501)
st[1:5, 1:5]
##           [,1]      [,2]     [,3]     [,4]     [,5]
## [1,] 135.00000   0.00000   0.0000   0.0000   0.0000
## [2,] 102.65186 177.54184   0.0000   0.0000   0.0000
## [3,]  78.05485 135.00000 233.4897   0.0000   0.0000
## [4,]  59.35167 102.65186 177.5418 307.0680   0.0000
## [5,]  45.13007  78.05485 135.0000 233.4897 403.8328
p = (exp(r * delta_t) - d) / (u - d)
American_put(st, p, r, delta_t, k)[1:5, 1:5]
##          [,1]     [,2]     [,3]     [,4]     [,5]
## [1,] 143.6674   0.0000   0.0000   0.0000   0.0000
## [2,] 143.7386 143.5855   0.0000   0.0000   0.0000
## [3,] 143.8058 143.6618 143.4968   0.0000   0.0000
## [4,] 143.8696 143.7336 143.5789 143.4005   0.0000
## [5,] 143.9302 143.8016 143.6560 143.4891 143.2957
American_put(st, p, r, delta_t, k)[1][1]
## [1] 143.6674
options = c()
for (i in 3:500) {
  delta_t = time / i
  u = exp(sigma * sqrt(delta_t))
  d = exp(-sigma * sqrt(delta_t))
  st = stock_tree(price, u, d, i + 1)
  p = (exp(r * delta_t) - d) / (u - d)
  oi = American_put(st, p, r, delta_t, k)[1][1]
  options = c(options, oi)
}
plot(x = 3:500, y = options, type = 'l',
     xlab = 'Step Count', ylab = 'Option Price')

6 Slide 57

Consider the SHS stock with price \(14,400\) VND on 15/12/2018. An investor anticipates that SHS price will be much higher than \(13,000\) VND at some time during the next \(6\) months. The investor thus decided to buy an American call option written on SHS on 15/12/2018, maturing on 15/06/2019, with strike price K = \(13,000.\) Assume that the risk-free interest rate \(r\) is \(7\%\) p.a. compounded continuously.

  1. Using the historical SHS price from 15/12/2014 to 15/12/2018 to estimate the volatility of the stock.
  2. Compute the option price at each node of \(4-\)step CRR binomial tree model.
  3. Write an R code to verify your above answer.
  4. Write an R code to compute the option price at inception using \(500-\)step CRR binomial tree model.
  5. Write an R code to illustrate the change of option price at inception as the number of steps of binomial tree increases from \(3\) steps to \(500\) steps.

Solution.

SHS = tq_get(symbol = 'SHS', from = '2014-12-15', to = '2018-12-15',
             src = 'CAFEF')
glimpse(as.data.frame(SHS))
sigma = sd(SHS$adjusted) / sqrt(4)
sigma
## [1] 0.8895824
time = 6 / 12
delta_t = time / 4
u = exp(sigma * sqrt(delta_t))
d = exp(-sigma * sqrt(delta_t))
price = 14.4
st = stock_tree(price, u, d, 5)
st
##           [,1]      [,2]     [,3]     [,4]     [,5]
## [1,] 14.400000  0.000000  0.00000  0.00000  0.00000
## [2,] 10.514059 19.722164  0.00000  0.00000  0.00000
## [3,]  7.676767 14.400000 27.01137  0.00000  0.00000
## [4,]  5.605137 10.514059 19.72216 36.99463  0.00000
## [5,]  4.092552  7.676767 14.40000 27.01137 50.66765
k = 13
r = 0.07
p = (exp(r * delta_t) - d) / (u - d)
American_call(st, p, r, delta_t, k)
##           [,1]      [,2]      [,3]     [,4]     [,5]
## [1,] 4.3283865 0.0000000  0.000000  0.00000  0.00000
## [2,] 1.5676414 7.9904560  0.000000  0.00000  0.00000
## [3,] 0.2612258 3.2908809 14.236893  0.00000  0.00000
## [4,] 0.0000000 0.6047447  6.835418 24.10789  0.00000
## [5,] 0.0000000 0.0000000  1.400000 14.01137 37.66765
American_call(st, p, r, delta_t, k)[1][1]
## [1] 4.328386
time = 6 / 12
delta_t = time / 500
u = exp(sigma * sqrt(delta_t))
d = exp(-sigma * sqrt(delta_t))
price = 135
st = stock_tree(price, u, d, 501)
st[1:5, 1:5]
##          [,1]     [,2]     [,3]     [,4]     [,5]
## [1,] 135.0000   0.0000   0.0000   0.0000   0.0000
## [2,] 131.2552 138.8516   0.0000   0.0000   0.0000
## [3,] 127.6143 135.0000 142.8131   0.0000   0.0000
## [4,] 124.0744 131.2552 138.8516 146.8876   0.0000
## [5,] 120.6327 127.6143 135.0000 142.8131 151.0784
k = 145
r = 0.07
p = (exp(r * delta_t) - d) / (u - d)
American_put(st, p, r, delta_t, k)[1:5, 1:5]
##          [,1]     [,2]     [,3]     [,4]     [,5]
## [1,] 37.14207  0.00000  0.00000  0.00000  0.00000
## [2,] 38.68264 35.57068  0.00000  0.00000  0.00000
## [3,] 40.24800 37.08608 34.02481  0.00000  0.00000
## [4,] 41.83656 38.62793 35.51336 32.50622  0.00000
## [5,] 43.44664 40.19469 37.02995 33.96629 31.01655
American_put(st, p, r, delta_t, k)[1][1]
## [1] 37.14207
options = c()
for (i in 3:500) {
  delta_t = time / i
  u = exp(sigma * sqrt(delta_t))
  d = exp(-sigma * sqrt(delta_t))
  st = stock_tree(price, u, d, i + 1)
  p = (exp(r * delta_t) - d) / (u - d)
  oi = American_put(st, p, r, delta_t, k)[1][1]
  options = c(options, oi)
}
plot(x = 3:500, y = options, type = 'l',
     xlab = 'Step Count', ylab = 'Option Price')

7 Slide 58

Consider a \(1-\)year European put option on a stock whose price follows a \(4-\)step CRR model. The current stock price is $\(100,\) the volatility of stock is \(20\%\) p.a., the strike price $\(102,\) the interest rate \(r\) is \(8\%\) p.a. compounded continuously.

  1. Compute the above European put option.
  2. Compute the corresponding American put option.
  3. When should the American put option be exercised?

Solution.

sigma = 0.2
time = 1
delta_t = time / 4
u = exp(sigma * sqrt(delta_t))
d = exp(-sigma * sqrt(delta_t))
price = 100
st = stock_tree(price, u, d, 5)
st
##           [,1]      [,2]     [,3]     [,4]     [,5]
## [1,] 100.00000   0.00000   0.0000   0.0000   0.0000
## [2,]  90.48374 110.51709   0.0000   0.0000   0.0000
## [3,]  81.87308 100.00000 122.1403   0.0000   0.0000
## [4,]  74.08182  90.48374 110.5171 134.9859   0.0000
## [5,]  67.03200  81.87308 100.0000 122.1403 149.1825
k = 102
r = 0.08
p = (exp(r * delta_t) - d) / (u - d)
European_put(st, p, r, delta_t, k)
##           [,1]      [,2]      [,3] [,4] [,5]
## [1,]  4.970898  0.000000 0.0000000    0    0
## [2,]  9.198312  2.031639 0.0000000    0    0
## [3,] 16.127447  4.417441 0.3456830    0    0
## [4,] 25.898443  9.496523 0.8314842    0    0
## [5,] 34.967995 20.126925 2.0000000    0    0
European_put(st, p, r, delta_t, k)[1][1]
## [1] 4.970898
American_put(st, p, r, delta_t, k)
##           [,1]      [,2]      [,3] [,4] [,5]
## [1,]  6.131614  0.000000 0.0000000    0    0
## [2,] 11.516258  2.380733 0.0000000    0    0
## [3,] 20.126925  5.257130 0.3456830    0    0
## [4,] 27.918178 11.516258 0.8314842    0    0
## [5,] 34.967995 20.126925 2.0000000    0    0
American_put(st, p, r, delta_t, k)[1][1]
## [1] 6.131614
bool = k - st == American_put(st, p, r, delta_t, k)
for (i in 1:nrow(bool)) {
  for (j in i:nrow(bool)) {
    bool[i, j] = FALSE
  }
}
bool
##       [,1]  [,2]  [,3]  [,4]  [,5]
## [1,] FALSE FALSE FALSE FALSE FALSE
## [2,]  TRUE FALSE FALSE FALSE FALSE
## [3,]  TRUE FALSE FALSE FALSE FALSE
## [4,]  TRUE  TRUE FALSE FALSE FALSE
## [5,]  TRUE  TRUE  TRUE FALSE FALSE