library(tidyverse)
## -- Attaching packages --------------------------------------- tidyverse 1.3.1 --
## v ggplot2 3.3.5     v purrr   0.3.4
## v tibble  3.1.6     v dplyr   1.0.8
## v tidyr   1.2.0     v stringr 1.4.0
## v readr   2.1.2     v forcats 0.5.1
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
library(readr)
ETF6_20080101_20200430 <- read_csv("C:/Users/CTY REDSTAR/Downloads/ETF6_20080101-20200430.csv")
## Rows: 14935 Columns: 4
## -- Column specification --------------------------------------------------------
## Delimiter: ","
## chr (2): 證券代碼, 簡稱
## dbl (2): 年月日, 收盤價(元)
## 
## i Use `spec()` to retrieve the full column specification for this data.
## i Specify the column types or set `show_col_types = FALSE` to quiet this message.
rm(list = ls())
etf6 <- read.table('C:/Users/CTY REDSTAR/Downloads/ETF6_20080101-20200430.csv', sep = ',', header = T)
head(etf6)
##   è..å..ä..ç..             ç..ç.. å¹.æœ.æ.. æ..ç..價.å.ƒ.
## 1      0050     元大å\217°ç\201£50     20080102        39.6472
## 2      0052     富邦科æŠ\200       20080102        27.0983
## 3      0056    元大é«\230è‚¡æ\201¯     20080102        14.5739
## 4      0050     元大å\217°ç\201£50     20080103        38.9876
## 5      0052     富邦科æŠ\200       20080103        26.0676
## 6      0056    元大é«\230è‚¡æ\201¯     20080103        14.3758
etf6 <- etf6[, -2]
colnames(etf6) <- c('id', 'date', 'price')
head(etf6)
##        id     date   price
## 1 0050    20080102 39.6472
## 2 0052    20080102 27.0983
## 3 0056    20080102 14.5739
## 4 0050    20080103 38.9876
## 5 0052    20080103 26.0676
## 6 0056    20080103 14.3758
library(pacman)
p_load(reshape2, xts, quantmod)
etf6.l <- dcast(etf6, date~id)
## Using price as value column: use value.var to override.
head(etf6.l)
##       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.l)
## 'data.frame':    3041 obs. of  7 variables:
##  $ date   : int  20080102 20080103 20080104 20080107 20080108 20080109 20080110 20080111 20080114 20080115 ...
##  $ 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.l[, -1], order.by = as.Date(as.character(etf6.l$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
library(curl)
## Using libcurl 7.64.1 with Schannel
## 
## Attaching package: 'curl'
## 
## The following object is masked from 'package:readr':
## 
##     parse_date
library(SIT)
## Loading required package: SIT.date
## 
## Attaching package: 'SIT'
## 
## The following object is masked from 'package:TTR':
## 
##     DVI
## 
## The following objects are masked from 'package:dplyr':
## 
##     count, lst
## 
## The following object is masked from 'package:purrr':
## 
##     cross
## 
## The following object is masked from 'package:tibble':
## 
##     lst
## 
## The following object is masked from 'package:base':
## 
##     close
data <- new.env()
model <- list()
last <- xts::last
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"
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"
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)
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
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)
}
## Loading required package: kernlab
## 
## Attaching package: 'kernlab'
## 
## The following object is masked from 'package:SIT':
## 
##     cross
## 
## The following object is masked from 'package:purrr':
## 
##     cross
## 
## The following object is masked from 'package:ggplot2':
## 
##     alpha
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   
weight
##         e50  e52  e56
##   [1,]   NA   NA   NA
##   [2,]   NA   NA   NA
##   [3,]   NA   NA   NA
##   [4,]   NA   NA   NA
##   [5,]   NA   NA   NA
##   [6,]   NA   NA   NA
##   [7,]   NA   NA   NA
##   [8,]   NA   NA   NA
##   [9,]   NA   NA   NA
##  [10,]   NA   NA   NA
##  [11,]   NA   NA   NA
##  [12,]   NA   NA   NA
##  [13,]   NA   NA   NA
##  [14,]   NA   NA   NA
##  [15,]   NA   NA   NA
##  [16,]   NA   NA   NA
##  [17,]   NA   NA   NA
##  [18,]   NA   NA   NA
##  [19,]   NA   NA   NA
##  [20,]   NA   NA   NA
##  [21,]   NA   NA   NA
##  [22,]   NA   NA   NA
##  [23,]   NA   NA   NA
##  [24,]   NA   NA   NA
##  [25,]   NA   NA   NA
##  [26,]   NA   NA   NA
##  [27,]   NA   NA   NA
##  [28,]   NA   NA   NA
##  [29,]   NA   NA   NA
##  [30,]   NA   NA   NA
##  [31,]   NA   NA   NA
##  [32,]   NA   NA   NA
##  [33,]   NA   NA   NA
##  [34,]   NA   NA   NA
##  [35,]   NA   NA   NA
##  [36,] 0.35 0.00 0.65
##  [37,] 0.35 0.00 0.65
##  [38,] 0.40 0.00 0.60
##  [39,] 0.42 0.00 0.58
##  [40,] 0.45 0.00 0.55
##  [41,] 0.47 0.00 0.53
##  [42,] 0.41 0.00 0.59
##  [43,] 0.36 0.00 0.64
##  [44,] 0.42 0.00 0.58
##  [45,] 0.00 0.00 1.00
##  [46,] 0.00 0.00 1.00
##  [47,] 0.00 0.00 1.00
##  [48,] 0.00 0.00 1.00
##  [49,] 0.00 0.00 1.00
##  [50,] 0.00 0.00 1.00
##  [51,] 0.00 0.13 0.87
##  [52,] 0.00 0.00 1.00
##  [53,] 0.11 0.00 0.89
##  [54,] 0.17 0.00 0.83
##  [55,] 0.00 0.10 0.90
##  [56,] 0.00 0.05 0.95
##  [57,] 0.00 0.04 0.96
##  [58,] 0.05 0.23 0.72
##  [59,] 0.00 0.26 0.74
##  [60,] 0.00 0.30 0.70
##  [61,] 0.00 0.35 0.65
##  [62,] 0.00 0.36 0.64
##  [63,] 0.00 0.38 0.62
##  [64,] 0.05 0.31 0.64
##  [65,] 0.18 0.29 0.53
##  [66,] 0.24 0.24 0.52
##  [67,] 0.22 0.25 0.53
##  [68,] 0.21 0.29 0.50
##  [69,] 0.29 0.30 0.40
##  [70,] 0.21 0.31 0.48
##  [71,] 0.21 0.32 0.46
##  [72,] 0.42 0.23 0.35
##  [73,] 0.39 0.26 0.35
##  [74,] 0.39 0.33 0.28
##  [75,] 0.37 0.30 0.33
##  [76,] 0.44 0.26 0.30
##  [77,] 0.56 0.17 0.27
##  [78,] 0.59 0.28 0.13
##  [79,] 0.59 0.28 0.13
##  [80,] 0.62 0.22 0.16
##  [81,] 0.92 0.01 0.07
##  [82,] 0.89 0.00 0.11
##  [83,] 0.98 0.00 0.02
##  [84,] 0.93 0.00 0.07
##  [85,] 0.84 0.00 0.16
##  [86,] 0.81 0.00 0.19
##  [87,] 0.75 0.00 0.25
##  [88,] 0.84 0.00 0.16
##  [89,] 0.89 0.00 0.11
##  [90,] 0.93 0.00 0.06
##  [91,] 0.99 0.00 0.01
##  [92,] 0.94 0.00 0.06
##  [93,] 0.99 0.00 0.01
##  [94,] 0.90 0.00 0.10
##  [95,] 0.85 0.00 0.15
##  [96,] 0.83 0.00 0.17
##  [97,] 0.78 0.00 0.22
##  [98,] 0.82 0.00 0.18
##  [99,] 0.67 0.00 0.33
## [100,] 0.61 0.00 0.39
## [101,] 0.60 0.00 0.40
## [102,] 0.62 0.00 0.38
## [103,] 0.68 0.00 0.32
## [104,] 0.66 0.00 0.34
## [105,] 0.66 0.00 0.34
## [106,] 0.69 0.00 0.31
## [107,] 0.68 0.00 0.32
## [108,] 0.69 0.00 0.31
## [109,] 0.73 0.00 0.27
## [110,] 0.75 0.00 0.25
## [111,] 0.76 0.00 0.24
## [112,] 0.77 0.00 0.23
## [113,] 0.73 0.00 0.27
## [114,] 0.75 0.00 0.25
## [115,] 0.75 0.00 0.25
## [116,] 0.72 0.00 0.28
## [117,] 0.63 0.00 0.37
## [118,] 0.59 0.00 0.41
## [119,] 0.58 0.00 0.42
## [120,] 0.57 0.00 0.43
## [121,] 0.59 0.00 0.41
## [122,] 0.58 0.00 0.42
## [123,] 0.59 0.00 0.41
## [124,] 0.58 0.00 0.42
## [125,] 0.59 0.00 0.41
## [126,] 0.57 0.00 0.43
## [127,] 0.43 0.00 0.57
## [128,] 0.46 0.00 0.54
## [129,] 0.50 0.00 0.50
## [130,] 0.09 0.00 0.91
## [131,] 0.16 0.00 0.84
## [132,] 0.12 0.00 0.88
## [133,] 0.20 0.00 0.80
## [134,] 0.15 0.00 0.85
## [135,] 0.14 0.00 0.86
## [136,] 0.16 0.00 0.84
## [137,] 0.16 0.00 0.84
## [138,] 0.16 0.00 0.84
## [139,] 0.02 0.00 0.98
## [140,] 0.02 0.00 0.98
## [141,] 0.01 0.00 0.99
## [142,] 0.00 0.00 1.00
## [143,] 0.00 0.00 1.00
## [144,] 0.00 0.00 1.00
## [145,] 0.00 0.00 1.00
## [146,] 0.00 0.00 1.00
## [147,] 0.00 0.00 1.00
## [148,] 0.00 0.00 1.00
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)