#Load required packages
library(xts)
library(quantmod)
library(SIT)
library(reshape2)
library(readr)
library(kernlab)
#Load analytical file
rm(list = ls())
etf6 <- read_csv("C:/Users/User/Downloads/ETF6_20080101-20200430.csv")
## Rows: 14935 Columns: 4
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (2): 證券代碼, 簡稱
## dbl (2): 年月日, 收盤價(元)
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(etf6)
## # A tibble: 6 × 4
##   證券代碼 簡稱         年月日 `收盤價(元)`
##   <chr>    <chr>         <dbl>        <dbl>
## 1 0050     元大台灣50 20080102         39.6
## 2 0052     富邦科技   20080102         27.1
## 3 0056     元大高股息 20080102         14.6
## 4 0050     元大台灣50 20080103         39.0
## 5 0052     富邦科技   20080103         26.1
## 6 0056     元大高股息 20080103         14.4
etf6 <- etf6[, -2]
colnames(etf6) <- c('id', 'date', 'price')
head(etf6)
## # A tibble: 6 × 3
##   id        date price
##   <chr>    <dbl> <dbl>
## 1 0050  20080102  39.6
## 2 0052  20080102  27.1
## 3 0056  20080102  14.6
## 4 0050  20080103  39.0
## 5 0052  20080103  26.1
## 6 0056  20080103  14.4
etf6.1 <- dcast(etf6, date~id)
## Using price as value column: use value.var to override.
head(etf6.1)
##       date    0050    0052    0056 0061 006206 00638R
## 1 20080102 39.6472 27.0983 14.5739   NA     NA     NA
## 2 20080103 38.9876 26.0676 14.3758   NA     NA     NA
## 3 20080104 38.9876 25.9346 14.4041   NA     NA     NA
## 4 20080107 37.2064 24.1391 14.1777   NA     NA     NA
## 5 20080108 37.5692 24.1391 14.3531   NA     NA     NA
## 6 20080109 38.2619 24.2721 14.4663   NA     NA     NA
str(etf6.1)
## 'data.frame':    3041 obs. of  7 variables:
##  $ date  : num  20080102 20080103 20080104 20080107 20080108 ...
##  $ 0050  : num  39.6 39 39 37.2 37.6 ...
##  $ 0052  : num  27.1 26.1 25.9 24.1 24.1 ...
##  $ 0056  : num  14.6 14.4 14.4 14.2 14.4 ...
##  $ 0061  : num  NA NA NA NA NA NA NA NA NA NA ...
##  $ 006206: num  NA NA NA NA NA NA NA NA NA NA ...
##  $ 00638R: num  NA NA NA NA NA NA NA NA NA NA ...
etf6.xts <- xts(etf6.1[, -1], order.by = as.Date(as.character(etf6.1$date), format = '%Y%m%d'))
class(etf6.xts)
## [1] "xts" "zoo"
head(etf6.xts)
##               0050    0052    0056 0061 006206 00638R
## 2008-01-02 39.6472 27.0983 14.5739   NA     NA     NA
## 2008-01-03 38.9876 26.0676 14.3758   NA     NA     NA
## 2008-01-04 38.9876 25.9346 14.4041   NA     NA     NA
## 2008-01-07 37.2064 24.1391 14.1777   NA     NA     NA
## 2008-01-08 37.5692 24.1391 14.3531   NA     NA     NA
## 2008-01-09 38.2619 24.2721 14.4663   NA     NA     NA
data <- new.env()

model <- list()

etf3 <- etf6.xts[, 1:3]
head(etf3)
##               0050    0052    0056
## 2008-01-02 39.6472 27.0983 14.5739
## 2008-01-03 38.9876 26.0676 14.3758
## 2008-01-04 38.9876 25.9346 14.4041
## 2008-01-07 37.2064 24.1391 14.1777
## 2008-01-08 37.5692 24.1391 14.3531
## 2008-01-09 38.2619 24.2721 14.4663
names(etf3)
## [1] "0050" "0052" "0056"
colnames(etf3) <- c('e50', 'e52', 'e56')
names(etf3)
## [1] "e50" "e52" "e56"
#Question 1. Select the first 3 ETFs (0050, 0052 and 0056) 
#and apply moving average (MA) investment rule to the selected three ETFs.
#MA investment rule is that we will build up our position 
#when prices are higher than the average trading prices of last 50 days. 
#Show MA invstment performance of these 3 ETFs.  

md = 50
i = 'e50'
for(i in names(etf3)) {
  data$prices = data$weight = data$execution.price = etf3[, i]
  data$weight[] <- 1
  data$execution.price[] <- NA
  model[[i]] <- bt.run(data)
  sma <- SMA(data$prices, md)
  data$weight[] <- iif(data$prices >= sma, 1, 0)
  i <- paste(i, '.sma.cross', sep = '')
  model[[i]] <- bt.run(data)
}
## Latest weights :
##            e50
## 2020-04-30 100
## 
## Performance summary :
##  CAGR    Best    Worst   
##  6.4 8   -7  
## 
## Latest weights :
##            e50
## 2020-04-30 100
## 
## Performance summary :
##  CAGR    Best    Worst   
##  5.3 7   -6.4    
## 
## Latest weights :
##            e52
## 2020-04-30 100
## 
## Performance summary :
##  CAGR    Best    Worst   
##  7.3 10  -9.2    
## 
## Latest weights :
##            e52
## 2020-04-30 100
## 
## Performance summary :
##  CAGR    Best    Worst   
##  0.9 10  -9.2    
## 
## Latest weights :
##            e56
## 2020-04-30 100
## 
## Performance summary :
##  CAGR    Best    Worst   
##  5.3 7   -6.9    
## 
## Latest weights :
##            e56
## 2020-04-30 100
## 
## Performance summary :
##  CAGR    Best    Worst   
##  9.9 7   -5.3    
strategy.performance.snapshoot(model, T)

## NULL
plotbt(model, plotX = T, log = 'y', LeftMargin = 3)
mtext('Cumulative Performance', side = 2, line =1)
plotbt.strategy.sidebyside(model, return.table = T, make.plot = F)
##            e50                 e50.sma.cross       e52                
## Period     "Jan2008 - Apr2020" "Jan2008 - Apr2020" "Jan2008 - Apr2020"
## Cagr       "6.43"              "5.3"               "7.32"             
## Sharpe     "0.42"              "0.49"              "0.41"             
## DVR        "0.37"              "0.39"              "0.33"             
## Volatility "20.06"             "12.22"             "26.2"             
## MaxDD      "-52.38"            "-23.13"            "-59.41"           
## AvgDD      "-3.57"             "-3.08"             "-5.19"            
## VaR        "-1.93"             "-1.17"             "-2.64"            
## CVaR       "-3.07"             "-1.94"             "-3.94"            
## Exposure   "99.97"             "62.08"             "99.97"            
##            e52.sma.cross       e56                 e56.sma.cross      
## Period     "Jan2008 - Apr2020" "Jan2008 - Apr2020" "Jan2008 - Apr2020"
## Cagr       "0.93"              "5.27"              "9.94"             
## Sharpe     "0.14"              "0.39"              "0.99"             
## DVR        "0.03"              "0.33"              "0.93"             
## Volatility "17.63"             "17.17"             "10.38"            
## MaxDD      "-56.14"            "-54.36"            "-14.95"           
## AvgDD      "-7.84"             "-3.42"             "-2.15"            
## VaR        "-1.74"             "-1.61"             "-0.93"            
## CVaR       "-2.93"             "-2.86"             "-1.62"            
## Exposure   "60.77"             "99.97"             "61.82"
# Question 2: Compute equal weighted portfolio of the 3 selected ETFs
#-------------------
data$prices = data$weight = data$execution.price = etf3
data$execution.price[] <- NA
prices <- data$prices
n <- ncol(prices)
data$weight <- ntop(prices, n)
model$etf3bh <- bt.run(data)
## Latest weights :
##              e50   e52   e56
## 2020-04-30 33.33 33.33 33.33
## 
## Performance summary :
##  CAGR    Best    Worst   
##  6.9 7.5 -7  
etf3.m <- to.monthly(etf3, indexAt = 'lastof', OHLC = FALSE)
head(etf3.m)
##                e50     e52     e56
## 2008-01-31 36.2499 23.2680 12.8646
## 2008-02-29 40.1420 25.5356 14.0079
## 2008-03-31 39.8781 25.1366 14.4324
## 2008-04-30 42.1541 26.7326 14.8851
## 2008-05-31 41.0326 26.1008 14.5625
## 2008-06-30 36.2828 23.1416 12.9608
etf3.w <- to.weekly(etf3, indexAt = 'lastof', OHLC = FALSE)
## Warning in !missing(sec) && sec%%1 != 0: 'length(x) = 635 > 1' in coercion to
## 'logical(1)'
head(etf3.w)
##                e50     e52     e56
## 2008-01-04 38.9876 25.9346 14.4041
## 2008-01-11 38.0310 24.3319 14.6022
## 2008-01-18 38.5917 23.8598 14.1777
## 2008-01-25 37.2064 23.6071 13.4702
## 2008-02-01 37.2064 23.4475 13.0457
## 2008-02-15 37.8001 23.9396 13.3004
# Question 3: Convert data into monthly data and compute MVP portfolios based on last 36 month data.

#Question 4: By setting constraints = new.constraints(n, lb = 0, ub = 1), recompute question 3. 
data$prices = data$weight = data$execution.price = etf3.m
data$execution.price[] <- NA
prices <- data$prices
n <- ncol(prices)
constraints = new.constraints(n, lb = 0, ub = +Inf)
constraints = add.constraints(rep(1, n), 1, type = '=', constraints)        
ret = prices / mlag(prices) - 1
weight = coredata(prices)
weight[] = NA
i = 36
for (i in 36:dim(weight)[1]) {
  hist = ret[ (i- 36 +1):i, ]
  hist = na.omit(hist)
  ia = create.historical.ia(hist, 12)
  ia$cov = cov(coredata(hist))
  weight[i,] = min.risk.portfolio(ia, constraints)
}


#Question 5: Show the above portfolio performance and make comment based on risk measures.

weight <- round(weight, digits = 2)
data$weight[] = weight     
model$mvp.month = bt.run(data, type = "weight")
## Latest weights :
##            e50 e52 e56
## 2020-04-30   0   0 100
## 
## Performance summary :
##  CAGR    Best    Worst   
##  5.1 12.1    -12.2   
#
plotbt.strategy.sidebyside(model, return.table=T, make.plot = T)

##            e50                 e50.sma.cross       e52                
## Period     "Jan2008 - Apr2020" "Jan2008 - Apr2020" "Jan2008 - Apr2020"
## Cagr       "6.43"              "5.3"               "7.32"             
## Sharpe     "0.42"              "0.49"              "0.41"             
## DVR        "0.37"              "0.39"              "0.33"             
## Volatility "20.06"             "12.22"             "26.2"             
## MaxDD      "-52.38"            "-23.13"            "-59.41"           
## AvgDD      "-3.57"             "-3.08"             "-5.19"            
## VaR        "-1.93"             "-1.17"             "-2.64"            
## CVaR       "-3.07"             "-1.94"             "-3.94"            
## Exposure   "99.97"             "62.08"             "99.97"            
##            e52.sma.cross       e56                 e56.sma.cross      
## Period     "Jan2008 - Apr2020" "Jan2008 - Apr2020" "Jan2008 - Apr2020"
## Cagr       "0.93"              "5.27"              "9.94"             
## Sharpe     "0.14"              "0.39"              "0.99"             
## DVR        "0.03"              "0.33"              "0.93"             
## Volatility "17.63"             "17.17"             "10.38"            
## MaxDD      "-56.14"            "-54.36"            "-14.95"           
## AvgDD      "-7.84"             "-3.42"             "-2.15"            
## VaR        "-1.74"             "-1.61"             "-0.93"            
## CVaR       "-2.93"             "-2.86"             "-1.62"            
## Exposure   "60.77"             "99.97"             "61.82"            
##            etf3bh              mvp.month          
## Period     "Jan2008 - Apr2020" "Jan2008 - Apr2020"
## Cagr       "6.86"              "5.14"             
## Sharpe     "0.45"              "0.49"             
## DVR        "0.4"               "0.37"             
## Volatility "19"                "11.6"             
## MaxDD      "-54.89"            "-17.84"           
## AvgDD      "-2.99"             "-6.42"            
## VaR        "-1.88"             "-5.38"            
## CVaR       "-2.97"             "-8.1"             
## Exposure   "99.97"             "75.68"
plotbt(model)