Homework 8- European Option Pricing
Instructor: Le Nhat Tan
Libraries
library(tidyverse)## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.1 ──
## ✔ ggplot2 3.3.6 ✔ purrr 0.3.4
## ✔ tibble 3.1.7 ✔ dplyr 1.0.9
## ✔ tidyr 1.2.0 ✔ stringr 1.4.0
## ✔ readr 2.1.2 ✔ forcats 0.5.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
library(ggplot2)
library(VNDS) # https://github.com/phamdinhkhanh/VNDS
library(yuima)## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
## Loading required package: stats4
## Loading required package: expm
## Loading required package: Matrix
##
## Attaching package: 'Matrix'
## The following objects are masked from 'package:tidyr':
##
## expand, pack, unpack
##
## Attaching package: 'expm'
## The following object is masked from 'package:Matrix':
##
## expm
## Loading required package: cubature
## Loading required package: mvtnorm
## ########################################
## This is YUIMA Project package v.1.15.15
## Why don't you try yuimaGUI package?
## Visit: http://www.yuima-project.com
## ########################################
##
## Attaching package: 'yuima'
## The following object is masked from 'package:tibble':
##
## char
## The following object is masked from 'package:stats':
##
## simulate
Inclass
HAG
HAG = tq_get(symbol = 'HAG', from = '2018-01-01', to = '2022-09-30',
src = 'CAFEF')## #HAG from 2018-01-01 to 2022-09-30 already cloned
HAG = as.data.frame(HAG)
plot(HAG$date, HAG$adjusted, type = 'l', col = 'blue',
xlab = 'Time', ylab = 'Adjusted Price', main = 'HAG')price = rev(HAG$adjusted)
delta = 1 / 252
gBm = setModel(drift = "mu*x", diffusion = "sigma*x")## Warning in yuima.warn("Solution variable (lhs) not specified. Trying to use state variables."):
## YUIMA: Solution variable (lhs) not specified. Trying to use state variables.
mod = setYuima(model = gBm, data = setData(price, delta = delta))
fit = qmle(mod, start = list(mu = 1, sigma = 1),
lower = list(mu = 0.001, sigma = 0.001),
upper = list(mu = 10, sigma = 10))
coef(summary(fit))## Estimate Std. Error
## sigma 0.4770663 0.009879862
## mu 0.2407408 0.220184436
Estimated parameters are \(\mu=0.2407\) and \(\sigma=0.4771\)
tail(HAG, 1)## date open high low close volume adjusted
## 1184 2018-01-02 7.35 7.38 7.23 7.25 5924880 7.25
(length(price) - 1) / 252## [1] 4.694444
geometric_brownian_motion = function(start, time, size, mu, sigma) {
# dSt = St(\mu dt + \sigma dWt)
step = time / size
dWt = rnorm(size, mean = 0, sd = sqrt(step))
dt = rep(step, length(dWt))
dSt_by_St = mu * dt + sigma * dWt
return(cumprod(c(start, dSt_by_St + 1)))
}sigma = coef(summary(fit))[1]; mu = coef(summary(fit))[2]
start = price[length(price)]; x = HAG$date[1] + 1:365
time = 1; size = length(x) - 1; num_path = 500; val = NA;
for (i in 1:num_path) {
y = geometric_brownian_motion(start, time, size, mu, sigma)
val = rbind(val, data.frame(x, y, path = i, col = 'black'))
}
val_HAG = val %>% group_by(x) %>% summarize(y = mean(y))
val_HAG = rbind(val_HAG, data.frame(x = HAG$date, y = HAG$adjusted))
val_HAG$path = num_path + 1
val_HAG$col = 'red'
val = rbind(val, val_HAG)
ggplot(val, aes(x, y, group = path)) +
geom_line(data = val[val$col == 'black',], aes(color = 'GBM Sample Paths'),
alpha = 0.2) +
geom_line(data = val[val$col == 'red',], aes(color = 'HAG as Average'), alpha = 2,
size = 1.1) +
scale_color_manual(values = c('black', 'red')) +
theme_classic() +
theme(legend.title = element_blank()) +
xlab('Time') +
ylab('Price') +
ggtitle('Forecasting HAG Future movements')## Warning: Removed 1 row(s) containing missing values (geom_path).
## Warning: Removed 2 row(s) containing missing values (geom_path).
## VIC
VIC = tq_get(symbol = 'VIC', from = '2018-01-01', to = '2022-09-30',
src = 'CAFEF')## #VIC from 2018-01-01 to 2022-09-30 already cloned
VIC = as.data.frame(VIC)
plot(VIC$date, VIC$adjusted, type = 'l', col = 'blue',
xlab = 'Time', ylab = 'Adjusted Price', main = 'VIC')price = rev(VIC$adjusted)
gBm = setModel(drift = "mu*x", diffusion = "sigma*x")## Warning in yuima.warn("Solution variable (lhs) not specified. Trying to use state variables."):
## YUIMA: Solution variable (lhs) not specified. Trying to use state variables.
mod = setYuima(model = gBm, data = setData(price, delta = delta))
fit = qmle(mod, start = list(mu = 1, sigma = 1),
lower = list(mu = 0.001, sigma = 0.001),
upper = list(mu = 10, sigma = 10))
coef(summary(fit))## Estimate Std. Error
## sigma 0.30046910 0.00637214
## mu 0.03401463 0.13867805
Estimated parameters are \(\mu=0.03401463\) and \(\sigma=0.30046910\)
tail(VIC, 1)## date open high low close volume adjusted
## 1184 2018-01-02 77.6 78.5 77.4 78.2 1435130 57.45
(length(price) - 1) / 252## [1] 4.694444
sigma = coef(summary(fit))[1]; mu = coef(summary(fit))[2]
start = price[length(price)]; x = VIC$date[1] + 1:365
size = length(x) - 1; val = NA;
for (i in 1:num_path) {
y = geometric_brownian_motion(start, time, size, mu, sigma)
val = rbind(val, data.frame(x, y, path = i, col = 'black'))
}
val_VIC = val %>% group_by(x) %>% summarize(y = mean(y))
val_VIC = rbind(val_VIC, data.frame(x = VIC$date, y = VIC$adjusted))
val_VIC$path = num_path + 1
val_VIC$col = 'red'
val = rbind(val, val_VIC)
ggplot(val, aes(x, y, group = path)) +
geom_line(data = val[val$col == 'black',],
aes(color = 'GBM Sample Paths'), alpha = 0.2) +
geom_line(data = val[val$col == 'red',], aes(color = 'VIC'),
alpha = 2, size = 1.1) +
scale_color_manual(values = c('black', 'red')) +
theme_classic() +
theme(legend.title = element_blank()) +
xlab('Time') +
ylab('Price') +
ggtitle('Forecasting VIC Future movements')## Warning: Removed 1 row(s) containing missing values (geom_path).
## Warning: Removed 2 row(s) containing missing values (geom_path).
Homework
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)
}Problem 2
sigma = 0.3; k = 8; r = 0.07
time = 1 - 0.5; price = 10
step = 500
delta_t = time / step
u = exp(sigma * sqrt(delta_t))
d = exp(-sigma * sqrt(delta_t))
st = stock_tree(price, u, d, step + 1)
p = (exp(r * delta_t) - d) / (u - d)
European_call(st, p, r, delta_t, k)[1][1]## [1] 2.375834
Problem 3
k = 10; time = 1 - 0.5
delta_t = time / step
u = exp(sigma * sqrt(delta_t))
d = exp(-sigma * sqrt(delta_t))
st = stock_tree(price, u, d, step + 1)
p = (exp(r * delta_t) - d) / (u - d)
European_put(st, p, r, delta_t, k)[1][1]## [1] 0.6690108
Problem 5
We assume the time period January 1 2022 − September 30 2022.
stock_list = c('HPG', 'VHM', 'SSI', 'MBB', 'MWG')
for (stock in stock_list) {
data = tq_get(symbol = stock, from = '2022-01-01', to = '2022-09-30',
src = 'CAFEF')
data = as.data.frame(data)
price = rev(data$adjusted)
delta = 1 / 252
gBm = setModel(drift = "mu*x", diffusion = "sigma*x")
mod = setYuima(model = gBm, data = setData(price, delta = delta))
fit = qmle(mod, start = list(mu = 1, sigma = 1),
lower = list(mu = 0.001, sigma = 0.001),
upper = list(mu = 10, sigma = 10))
sigma = coef(summary(fit))[1]; mu = coef(summary(fit))[2]
print(paste0('Stock: ', stock, ', mu: ', mu, ', sigma: ', sigma))
print('')
}## #HPG from 2022-01-01 to 2022-09-30 already cloned
## Warning in yuima.warn("Solution variable (lhs) not specified. Trying to use state variables."):
## YUIMA: Solution variable (lhs) not specified. Trying to use state variables.
## [1] "Stock: HPG, mu: 0.00105574899140394, sigma: 0.38493408076749"
## [1] ""
## #VHM from 2022-01-01 to 2022-09-30 already cloned
## Warning in yuima.warn("Solution variable (lhs) not specified. Trying to use state variables."):
## YUIMA: Solution variable (lhs) not specified. Trying to use state variables.
## [1] "Stock: VHM, mu: 0.00105574899140394, sigma: 0.275376909394133"
## [1] ""
## #SSI from 2022-01-01 to 2022-09-30 already cloned
## Warning in yuima.warn("Solution variable (lhs) not specified. Trying to use state variables."):
## YUIMA: Solution variable (lhs) not specified. Trying to use state variables.
## [1] "Stock: SSI, mu: 0.00105574899140394, sigma: 0.512427009892711"
## [1] ""
## #MBB from 2022-01-01 to 2022-09-30 already cloned
## Warning in yuima.warn("Solution variable (lhs) not specified. Trying to use state variables."):
## YUIMA: Solution variable (lhs) not specified. Trying to use state variables.
## [1] "Stock: MBB, mu: 0.00105574899140394, sigma: 0.357350054322151"
## [1] ""
## #MWG from 2022-01-01 to 2022-09-30 already cloned
## Warning in yuima.warn("Solution variable (lhs) not specified. Trying to use state variables."):
## YUIMA: Solution variable (lhs) not specified. Trying to use state variables.
## [1] "Stock: MWG, mu: 0.00105574899140394, sigma: 0.365469521928479"
## [1] ""
Problem 6
Binomial Pricing
VCB = tq_get(symbol = 'VCB', from = '2014-02-01', to = '2019-02-01',
src = 'CAFEF')## #VCB from 2014-02-01 to 2019-02-01 already cloned
sigma = sd(VCB$close) / sqrt(5)
sigma## [1] 5.146645
k = 62; r = 0.08; time = 0.5
VCB = as.data.frame(VCB)
price = rev(VCB$close)
price = price[length(price)]
delta_t = time / step
u = exp(sigma * sqrt(delta_t))
d = exp(-sigma * sqrt(delta_t))
st = stock_tree(price, u, d, step + 1)
p = (exp(r * delta_t) - d) / (u - d)
European_put(st, p, r, delta_t, k)[1][1]## [1] 55.57305
Black-Scholes-Merton
price = rev(VCB$close)
delta = 1 / 252
gBm = setModel(drift = "mu*x", diffusion = "sigma*x")## Warning in yuima.warn("Solution variable (lhs) not specified. Trying to use state variables."):
## YUIMA: Solution variable (lhs) not specified. Trying to use state variables.
mod = setYuima(model = gBm, data = setData(price, delta = delta))
fit = qmle(mod, start = list(mu = 1, sigma = 1),
lower = list(mu = 0.001, sigma = 0.001),
upper = list(mu = 10, sigma = 10))
sigma = coef(summary(fit))[1]; mu = coef(summary(fit))[2]
print(paste0('mu: ', mu, ', sigma: ', sigma))## [1] "mu: 0.200453262009897, sigma: 0.340860249618946"
sigma = sigma * sqrt(252)
price = price[length(price)]
d_plus = (log(price) - log(k) +
(r + sigma * sigma / 2) * time) / (sigma * sqrt(time))
d_minus = (log(price) - log(k) +
(r - sigma * sigma / 2) * time) / (sigma * sqrt(time))
k * exp(-r * time) * pnorm(-d_minus) - price * pnorm(-d_plus)## [1] 56.33554