Option pricing in Vietnam

Dr. Le Nhat Tan - FM2

Install necessary R package

library(DT)
library(tidyverse)
library(htmlwidgets)
library(xts)
library(ggthemes)
library(plotly)

Load data into R

## set working directory to the folder containing data
setwd("/Users/tantoankhoa10/Downloads/forecast")
## Import csv file into R 
df <- read.csv(file="excel_vic.csv", head=T,stringsAsFactors = F)
df %>% head(n=100) %>% datatable()
df <- df[,c(2:7)] # only select interested columns
df %>% head(n=100) %>% datatable()
date <- as.Date(as.character(df$X.DTYYYYMMDD.), format="%Y%m%d")
# transform date column to a suitable formate
class(date)
## [1] "Date"
df <- cbind(date,df)
df %>% head(n=100) %>% datatable()
df <- df[,-2] # eliminate the second column
df %>% head(n=100) %>% datatable()
df <- df[order(df$date),] # arrange data from oldest to newest
df %>% head(n=100) %>% datatable()
names(df) <- paste(c("date", "Open", "High", "Low", "Close", "Volume"))
df %>% head(n=100) %>% datatable()

Transform 5-year lastest data into a time series

df<-subset(df,df$date >= "2014-12-31" )
df_plot=ggplot(df, aes(x=date, y= Close, group=1))+geom_point(size=0.2)+geom_line(col="blue")+labs(x="Trading dates", y= "Prices", title="Price movement of VIC since 31/12/2014")
ggplotly(df_plot)
df <- xts(df[,2:6],order.by = df[,1])
X<-df[,4]
X <- as.numeric(na.omit(X))
plot(X,type="l",col="blue", main="VIC prices since 31/12/2014",xlab="Number of trading dates", ylab="Price")

Estimate the parameters of Geometric Brownian motion governing VIC price

library(yuima)
Delta <- 1/252
gBm <- setModel(drift="mu*x", diffusion="sigma*x")
mod <- setYuima(model=gBm, data=setData(X, delta=Delta))
fit <- qmle(mod, start=list(mu=0.01, sigma=0.01),
            lower=list(mu=0, sigma=0),
            upper=list(mu=100, sigma=100))
summary(fit)
## Quasi-Maximum likelihood estimation
## 
## Call:
## qmle(yuima = mod, start = list(mu = 0.01, sigma = 0.01), lower = list(mu = 0, 
##     sigma = 0), upper = list(mu = 100, sigma = 100))
## 
## Coefficients:
##        Estimate  Std. Error
## sigma 0.2724124 0.005340088
## mu    0.3022219 0.119570297
## 
## -2 log L: 3443.291
## The stock price is governed by the equation dS_t= 0.302 S_tdt+0.272 S_tdW_t

Similuating VIC prices in the next 6 month since 06/04/2020

GBM=function(T,N) {
# T=1 expiry time
# N=100 number of simulation points
h=T/N # the timestep of the simulation
X=rep(0, (N+1)) # create space to store value of Brownian motion
X[1]=91 ## start at 0
for(i in 1:N) { X[i+1]=X[i]*exp((0.302-0.272^2/2)*h+0.272*sqrt(h)*rnorm(1))}
return(X)
}


GBMSamplepaths <- function(T,N,nt)
{h=T/N ## time step
#nt: number of samples
t=seq(0,T, by=h) # produce a sequence of time points
X=matrix(rep(0, length(t) *nt), nrow=nt)
X_median=matrix(rep(0, length(t)), nrow=1)
## each row of the matrix stores one sample
# #return(X)
for (i in 1:nt) {X[i,]= GBM(T=T,N=N)}
for (j in 1:length(t)){X_median[j]= median(X[,j])}

# # ##Plot
ymax=max(X); ymin=min(X) #bounds for simulated prices
plot(t,X[1,], t="l" ,ylim=c(ymin, ymax), col=1,ylab="Price P(t)",xlab="time t")
for(i in 2:nt){lines(t,X[i,], t="l",ylim=c(ymin, ymax), col="gray")}
lines(t, X_median, col="red")
return(X_median)}
GBMSamplepaths(T=0.5,N=252/2,nt=252*5)

##      [,1]    [,2]     [,3]     [,4]     [,5]     [,6]     [,7]     [,8]
## [1,]   91 91.1379 91.17307 91.22555 91.36113 91.43905 91.63155 91.54227
##          [,9]    [,10]    [,11]    [,12]    [,13]    [,14]    [,15]
## [1,] 91.57951 92.03259 91.94465 92.02373 92.19426 92.24063 92.31838
##         [,16]    [,17]    [,18]    [,19]    [,20]    [,21]   [,22]
## [1,] 92.47723 92.58127 92.69084 92.72538 92.94794 92.89345 93.1281
##         [,23]    [,24]    [,25]    [,26]    [,27]    [,28]    [,29]
## [1,] 93.33655 93.43021 93.47453 93.64872 93.54946 93.72928 93.84764
##         [,30]    [,31]    [,32]    [,33]    [,34]    [,35]    [,36]
## [1,] 94.13978 94.22685 94.38408 94.68332 94.65685 94.54749 94.56368
##         [,37]    [,38]    [,39]    [,40]   [,41]    [,42]    [,43]   [,44]
## [1,] 94.71446 94.91342 94.85796 95.19445 95.2297 95.38038 95.54423 95.7569
##        [,45]    [,46]   [,47]    [,48]   [,49]    [,50]    [,51]    [,52]
## [1,] 95.6559 95.74499 95.9812 96.11271 96.2048 96.23281 96.38163 96.02738
##         [,53]    [,54]    [,55]    [,56]    [,57]    [,58]    [,59]
## [1,] 96.45149 96.63577 96.50915 97.09168 97.07428 96.98584 96.83383
##         [,60]    [,61]    [,62]    [,63]    [,64]    [,65]    [,66]
## [1,] 97.35524 97.73194 97.70214 97.95903 98.14853 98.37136 98.39847
##         [,67]    [,68]    [,69]    [,70]    [,71]    [,72]    [,73]
## [1,] 98.60745 98.60253 98.78901 98.92134 98.69605 99.05365 99.03588
##         [,74]    [,75]    [,76]    [,77]   [,78]    [,79]    [,80]
## [1,] 98.98325 98.82579 98.99944 99.21514 99.1652 99.14843 99.13395
##         [,81]    [,82]  [,83]   [,84]    [,85]    [,86]    [,87]    [,88]
## [1,] 99.42253 99.84123 99.984 100.151 100.3103 100.0649 100.5422 100.5906
##         [,89]    [,90]    [,91]    [,92]    [,93]    [,94]    [,95]
## [1,] 100.9053 100.8689 101.0263 100.9708 101.1419 101.2453 101.2199
##         [,96]    [,97]    [,98]    [,99]   [,100]  [,101]   [,102]
## [1,] 101.0551 101.1532 101.1821 101.1162 101.5359 101.611 101.7747
##        [,103]   [,104]   [,105]   [,106]   [,107]  [,108]   [,109]
## [1,] 101.8461 101.8772 102.0369 102.1715 102.1118 102.349 102.3204
##        [,110]   [,111]   [,112]   [,113] [,114]   [,115]   [,116]   [,117]
## [1,] 102.0555 102.4037 102.7417 102.5326 103.08 103.2184 102.9675 103.4818
##        [,118]   [,119]   [,120]   [,121]   [,122]   [,123]  [,124]
## [1,] 103.8278 103.5184 103.7106 103.8516 104.7109 104.1104 104.211
##        [,125]   [,126]   [,127]
## [1,] 103.6858 104.3972 104.1462

Option pricing by closed-form Black-Scholes formula

## Suppose we would like to compute the price of a European call option written on VIC price
## With current price S0=91, strike price K =95, expiry T=0.5, r= 0.07, volatility sigma=0.272

BS_call <-  function (S0,K,T,r,sigma){
d1 <- (log(S0/K)+(r+0.5*sigma^2)*T)/(sigma*sqrt(T))
d2 <- d1- sigma*sqrt(T)
opt.val <- S0*pnorm(d1)-K*exp(-r*T)*pnorm(d2)
return(opt.val)}

BS_call (S0=91,K=95,T=0.5,r=0.07,sigma=0.272)
## [1] 6.639527

Option pricing by Binomial tree method

European_call_binomial=function( T, t,r, X,N,S0,sigma){
delta_t=(T-t)/N
u = exp(sigma*sqrt(delta_t))
d = exp(-sigma*sqrt(delta_t))
p = (exp(r * delta_t) - d)/(u - d) ### probability of up move
Df = exp(-r * (T-t)) ### discounting factor
Ce=0;
for (i in 1:(N+1)){Ce =Ce+choose(N,i-1)*p^{i-1}*(1-p)^{N+1-i}*max(S0*u^{i-1}*d^{N-i+1}-X,0)}
return(Df*Ce)}
European_call_binomial(T=0.5, t=0, r=0.07, X=95, N=1000, S0=91, sigma=0.272)
## [1] 6.641113