#######################
## Only for educational purposes, not intended as an investment tool.
## Covers the base case, but can be adapted to more assets or different
## deliveries or time steps.
## This code has been possible thanks to the generosity of the:
## http://stackoverflow.com/ community
## Thanks to http://www.quantmod.com/ excellent package
## Contact:
## https://www.researchgate.net/profile/Mariano_Mendez
#######################


##### Just in case...
# install.packages("quantmod")
# install.packages("ggthemes")
# install.packages("scales")
# install.packages("MASS")
# install.packages("ggplot2")
# install.packages("reshape2")
# install.packages("corrplot")

library(quantmod)
## Loading required package: xts
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## Loading required package: TTR
## Version 0.4-0 included new data defaults. See ?getSymbols.
library(ggthemes)
library(scales)
library(MASS)
library(ggplot2)
library(reshape2)
library(corrplot)

rm(list = ls())
set.seed(233)

### Product especific information
timeSteps <- 1 # number of time steps inside periods 
periods <- 10 * timeSteps # number of periods in the simulation
periodsPerYear <- 1 # one year
sigmaTime <- 52 # Weeks semesters, adjust sigma to time of simulation 
t  <-  periods + 1 # number of periods plus 1
dt  <-  1 # time interval 1 
paths <- 1e4
pathsGraph <- 190 # Only small number of paths for graph simulation
### Information for retrieving asset data
ticker <- c("JPM","C") ### finance.yahoo.com tickers
assets <- length(ticker)
from <- '2004-01-01'
to <- '2008-05-22' # Historical data: yyyy-mm-dd
rf <- c(0.0388, 0.0388)/(periodsPerYear) # rf adjusted by periods per year 
strike <- 40

# Labels for the simulation graph
ValuationDate <- rep(to,t)
ValuationDate <- as.POSIXlt(to)
ValuationDate$year <-ValuationDate$year+c(0:periods) 
ValuationDate <- format(ValuationDate,"%Y")

### Obtaining prices, all at de same time
getSymbols(ticker,from=from,to=to)
##     As of 0.4-0, 'getSymbols' uses env=parent.frame() and
##  auto.assign=TRUE by default.
## 
##  This  behavior  will be  phased out in 0.5-0  when the call  will
##  default to use auto.assign=FALSE. getOption("getSymbols.env") and 
##  getOptions("getSymbols.auto.assign") are now checked for alternate defaults
## 
##  This message is shown once per session and may be disabled by setting 
##  options("getSymbols.warning4.0"=FALSE). See ?getSymbols for more details.
## [1] "JPM" "C"
ClosePrices <- do.call(cbind,lapply(ticker,function(x) Cl(get(x))))
ClosePrices <- na.locf(ClosePrices) # get prices but getting rid of NA
AdjustedPrices <- do.call(cbind,lapply(ticker,function(x) Ad(get(x))))
AdjustedPrices <- na.locf(AdjustedPrices) # get prices but getting rid of NA
ReturnPrices <- do.call(cbind,lapply(ticker,function(x) weeklyReturn(get(x))))
ReturnPrices <- na.locf(ReturnPrices) # get prices but getting rid of NA
colnames(ReturnPrices) <- ticker
colnames(AdjustedPrices) <- ticker

### Calculating dividend yield, because of quantmod we need to ge one at a time
### Because Citibank Reverse Split we use adjusted close
Dividends <- list()
CheckDividends <- list()
for(i in seq_along(ticker)){
  AdcloseP <- get(ticker[[i]])[,6] #get adjusted closing prices
  div <- getDividends(ticker[i], from = from, to = to, auto.assign = FALSE)
  if(nrow(div!=0)){
  temp <- merge.xts(AdcloseP,div,join='right')
  temp$yld <- temp[,2]/temp[,1]
  temp1 <- apply.yearly(temp$yld,sum)
  temp1 <-  last(temp1, '-1 year') 
  CheckDividends[[i]] <- temp1
  temp1 <- colMeans(temp1)}
  else{temp1 <- 0}
  Dividends <- c(Dividends,temp1)
}

## some cleaning...
AdcloseP <- NULL; div <- NULL; temp <- NULL; temp1 <- NULL
### Gathering data for the simulation of GBM
Dividends <- as.numeric(Dividends)
GraphDividends <-data.frame(ticker, Dividends) # Yearly div for graph
Dividends <- Dividends/(periodsPerYear)

## Choose model with or without dividends
#Dividends <- 0

#### historical volatility estimation 
sigma <- apply(ReturnPrices, 2, sd)
sigma <- sigma*sqrt(sigmaTime) # from weekly to semester sigma
correlation <- cor(ReturnPrices)
# Setting initial prices for the simulation
InitialPrices <- ClosePrices[nrow(ClosePrices),]
colnames(InitialPrices) <- ticker
S0 <- ClosePrices[nrow(ClosePrices),]
S0 <- matrix(rep(S0,each=paths),nrow=paths) 

# First and second terms of GBM
g1 <- matrix(rep(rf-Dividends-((sigma^2)/2)*dt,each=paths),nrow = paths)
g2 <- matrix(rep(sigma*sqrt(dt),each=paths),nrow = paths)

###############
#### Uncorrelated noise matrix
wiener <- rnorm(paths*t*assets)
dim(wiener) <- c(paths,t,assets)
#################
# ### Correlated noise matrix
# wiener <- mvrnorm(paths*t,mu=rep(0, assets),Sigma=correlation,empirical=T)
# dim(wiener) <- c(paths, t, assets)
####################

# Preasigment of variables for Loops
St <- array(0,c(paths,t,assets)) 
returns <- list()
stock <- list()
# Generating simulated prices
for(i in 1:assets){
  St[,,i] <- exp(g1[,i]+wiener[,,i]*g2[,i])
  St[,1,] <- S0
  St[,,i] <- t(apply(St[,,i],1,cumprod))
  stock[[i]] <- St[,,i]
}

## Call valuation by simulation
last_price <- c(t,(t+t))
valuation <- data.frame(stock)
valuation <- valuation[last_price]
call_sim <- valuation-strike
call_sim[call_sim<0] <- 0
call_sim <- exp(-rf*periods)*colMeans(call_sim)

## BSM Valuation
InitialPrices <- as.numeric(InitialPrices)
d1 <- (log(InitialPrices/strike)+(rf-Dividends+sigma^2/2)*periods)/(sigma*sqrt(periods))
d2 <- d1 - sigma*sqrt(periods)
call_BSM <- InitialPrices*exp(-Dividends*periods)*pnorm(d1)-strike*exp(-rf*periods)*pnorm(d2)

### Binding Output
call_Prices <- rbind(InitialPrices, strike, sigma, rf, 
                     Dividends, call_sim, call_BSM)
colnames(call_Prices) <- ticker

##################
### GRAPHS########
##################
## Historical Prices Graph closing prices
df<-data.frame(Date=index(ClosePrices),coredata(ClosePrices))
df_melt = melt(df, id.vars = 'Date')
ggplot(df_melt, aes(x = Date, y = value)) + 
  geom_line() + 
  facet_wrap(~ variable, scales = 'free_y', ncol = 1) +
  ylab("Closing Prices") +
  theme(axis.title.x=element_blank())

## Dividends Graph
ggplot(GraphDividends,aes(x=ticker,y=Dividends,fill=factor(ticker))) +
  geom_point(size=3) +
  ggtitle("Annual dividend rate") +
  scale_y_continuous(breaks = scales::pretty_breaks(n = 15),labels=percent) +
  theme_economist() +
  scale_colour_economist() +
  theme(legend.position="none",axis.title.x = element_blank(),axis.title.y=element_blank())

###Correlation
corrplot(correlation, addCoef.col = "black", type="upper")

# 
## Simulation
# Row binding the different stocks for the "pathsGraph" number of simulated paths
# do.call calls the function
stock <- do.call( rbind, lapply(stock,'[',1:pathsGraph,))
group <- rep(ticker,each=pathsGraph)
stock <- data.frame(id=seq_along(group),group,stock)
stockm <- melt(stock,id.vars = c("id","group"))

ggplot(stockm, aes(variable, value, group = id)) +
  geom_line(aes(colour = factor(id)),alpha = 0.5) +
  facet_wrap(~ group, scales="free_y", ncol = 1) +
  theme(legend.position="none") +
  scale_x_discrete(labels=as.character.Date(ValuationDate),expand = c(0,0)) +
  xlab("Time") + ylab(paste0("Sample of ",pathsGraph," paths for each asset"))+
  geom_hline(aes(yintercept=strike),color="black",size=0.8, linetype="dashed")

call_Prices
##                       JPM           C
## InitialPrices 43.04999900 21.72000000
## strike        40.00000000 40.00000000
## sigma          0.25336406  0.26496261
## rf             0.03880000  0.03880000
## Dividends      0.04483412  0.04602221
## call_sim       8.92754864  1.85333964
## call_BSM       8.68370747  1.79619654