rm(list = ls())
library(devtools)
## Warning: package 'devtools' was built under R version 4.3.3
## Loading required package: usethis
## Warning: package 'usethis' was built under R version 4.3.3
setwd("D:/School Folder/HW/Investment")
etf6 <- read.table('finish_data.csv', sep = ',', header = T)
head(etf6)
##   id       date price
## 1 50 2008-01-02 60.01
## 2 52 2008-01-02 40.14
## 3 56 2008-01-02 25.70
## 4 50 2008-01-03 58.89
## 5 52 2008-01-03 39.10
## 6 56 2008-01-03 25.23
library(pacman)
## Warning: package 'pacman' was built under R version 4.3.3
p_load(reshape2, xts, quantmod)
library(tidyr)
## Warning: package 'tidyr' was built under R version 4.3.3
## 
## Attaching package: 'tidyr'
## The following object is masked from 'package:reshape2':
## 
##     smiths
library(data.table)
## Warning: package 'data.table' was built under R version 4.3.3
## 
## Attaching package: 'data.table'
## The following objects are masked from 'package:xts':
## 
##     first, last
## The following objects are masked from 'package:zoo':
## 
##     yearmon, yearqtr
## The following objects are masked from 'package:reshape2':
## 
##     dcast, melt
etf6.l <- dcast(etf6, date ~ id, value.var = "price", fun.aggregate = mean)
## Warning: The dcast generic in data.table has been passed a data.frame and will
## attempt to redirect to the relevant reshape2 method; please note that reshape2
## is superseded and is no longer actively developed, and this redirection is now
## deprecated. Please do this redirection yourself like reshape2::dcast(etf6). In
## the next version, this warning will become an error.
head(etf6.l)
##         date    50    52    56
## 1 2008-01-02 60.01 40.14 25.70
## 2 2008-01-03 58.89 39.10 25.23
## 3 2008-01-04 59.01 38.64 25.51
## 4 2008-01-07 56.39 36.16 24.85
## 5 2008-01-08 56.98 35.82 25.38
## 6 2008-01-09 58.20 36.69 25.83
str(etf6.l)
## 'data.frame':    4009 obs. of  4 variables:
##  $ date: chr  "2008-01-02" "2008-01-03" "2008-01-04" "2008-01-07" ...
##  $ 50  : num  60 58.9 59 56.4 57 ...
##  $ 52  : num  40.1 39.1 38.6 36.2 35.8 ...
##  $ 56  : num  25.7 25.2 25.5 24.9 25.4 ...
library(xts)

# Remove rows with NA values in the date column
etf6.l <- etf6.l[complete.cases(etf6.l$date), ]

# Convert date column to Date format
etf6.l$date <- as.Date(etf6.l$date)

# Convert into xts
etf6.xts <- xts(etf6.l[, -1], order.by = etf6.l$date)

library(SIT) 
## Loading required package: SIT.date
## 
## Attaching package: 'SIT'
## The following object is masked from 'package:TTR':
## 
##     DVI
## The following object is masked from 'package:base':
## 
##     close
library(quantmod)

data <- new.env()

model <- list()
etf3 <- etf6.xts[, 1:3]
head(etf3)
##               50    52    56
## 2008-01-02 60.01 40.14 25.70
## 2008-01-03 58.89 39.10 25.23
## 2008-01-04 59.01 38.64 25.51
## 2008-01-07 56.39 36.16 24.85
## 2008-01-08 56.98 35.82 25.38
## 2008-01-09 58.20 36.69 25.83
names(etf3)
## [1] "50" "52" "56"
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)
  prices <- na.omit(data$prices)
  
  # Calculate the moving average
  sma <- SMA(prices, md)
  data$weight[] <- iif(data$prices >= sma, 1, 0)
  i <- paste(i, '.sma.cross', sep = '')
  model[[i]] <- bt.run(data)
}
## Latest weights :
##            e50
## 2024-04-29 100
## 
## Performance summary :
##  CAGR    Best    Worst   
##  6.6 16.5    -11.9   
## Warning in NextMethod(.Generic): number of items to replace is not a multiple
## of replacement length
## Latest weights :
##            e50
## 2024-04-29   0
## 
## Performance summary :
##  CAGR    Best    Worst   
##  34.5    16.5    -11.6   
## 
## Latest weights :
##            e52
## 2024-04-29 100
## 
## Performance summary :
##  CAGR    Best    Worst   
##  8   10  -11.6   
## Warning in NextMethod(.Generic): number of items to replace is not a multiple
## of replacement length
## Latest weights :
##            e52
## 2024-04-29   0
## 
## Performance summary :
##  CAGR    Best    Worst   
##  38.7    10  -11.6   
## 
## Latest weights :
##            e56
## 2024-04-29 100
## 
## Performance summary :
##  CAGR    Best    Worst   
##  2.8 7   -8.8    
## Warning in NextMethod(.Generic): number of items to replace is not a multiple
## of replacement length
## Latest weights :
##            e56
## 2024-04-29   0
## 
## Performance summary :
##  CAGR    Best    Worst   
##  26.7    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 = T)

##            e50                 e50.sma.cross       e52                
## Period     "Jan2008 - Apr2024" "Jan2008 - Apr2024" "Jan2008 - Apr2024"
## Cagr       "6.6"               "34.51"             "8.01"             
## Sharpe     "0.41"              "2.12"              "0.44"             
## DVR        "0.33"              "1.57"              "0.31"             
## Volatility "21.99"             "14.9"              "25.86"            
## MaxDD      "-52.26"            "-11.58"            "-58.47"           
## AvgDD      "-4.63"             "-1.56"             "-6.16"            
## VaR        "-1.95"             "-0.96"             "-2.56"            
## CVaR       "-3.19"             "-1.76"             "-3.81"            
## Exposure   "99.98"             "60.26"             "99.98"            
##            e52.sma.cross       e56                 e56.sma.cross      
## Period     "Jan2008 - Apr2024" "Jan2008 - Apr2024" "Jan2008 - Apr2024"
## Cagr       "38.66"             "2.83"              "26.74"            
## Sharpe     "2.03"              "0.25"              "2.57"             
## DVR        "1.3"               "0.15"              "2.03"             
## Volatility "17.25"             "17.01"             "9.64"             
## MaxDD      "-20.27"            "-50.81"            "-7.37"            
## AvgDD      "-2.06"             "-5.62"             "-1.2"             
## VaR        "-1.41"             "-1.65"             "-0.72"            
## CVaR       "-2.33"             "-2.91"             "-1.34"            
## Exposure   "61.26"             "99.98"             "58.84"
# --------------------------------------------------
# Add equal-weighted portfolio for 3 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$etf3.EqWeight.bh <- bt.run(data)
## Latest weights :
##              e50   e52   e56
## 2024-04-29 33.33 33.33 33.33
## 
## Performance summary :
##  CAGR    Best    Worst   
##  6.3 7.5 -6.5    
#
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 - Apr2024" "Jan2008 - Apr2024" "Jan2008 - Apr2024"
## Cagr       "6.6"               "34.51"             "8.01"             
## Sharpe     "0.41"              "2.12"              "0.44"             
## DVR        "0.33"              "1.57"              "0.31"             
## Volatility "21.99"             "14.9"              "25.86"            
## MaxDD      "-52.26"            "-11.58"            "-58.47"           
## AvgDD      "-4.63"             "-1.56"             "-6.16"            
## VaR        "-1.95"             "-0.96"             "-2.56"            
## CVaR       "-3.19"             "-1.76"             "-3.81"            
## Exposure   "99.98"             "60.26"             "99.98"            
##            e52.sma.cross       e56                 e56.sma.cross      
## Period     "Jan2008 - Apr2024" "Jan2008 - Apr2024" "Jan2008 - Apr2024"
## Cagr       "38.66"             "2.83"              "26.74"            
## Sharpe     "2.03"              "0.25"              "2.57"             
## DVR        "1.3"               "0.15"              "2.03"             
## Volatility "17.25"             "17.01"             "9.64"             
## MaxDD      "-20.27"            "-50.81"            "-7.37"            
## AvgDD      "-2.06"             "-5.62"             "-1.2"             
## VaR        "-1.41"             "-1.65"             "-0.72"            
## CVaR       "-2.33"             "-2.91"             "-1.34"            
## Exposure   "61.26"             "99.98"             "58.84"            
##            etf3.EqWeight.bh   
## Period     "Jan2008 - Apr2024"
## Cagr       "6.31"             
## Sharpe     "0.42"             
## DVR        "0.33"             
## Volatility "19.07"            
## MaxDD      "-56.2"            
## AvgDD      "-3.98"            
## VaR        "-1.92"            
## CVaR       "-2.93"            
## Exposure   "99.98"