## Q1. Download the data file 'hist_prices_df.rds' as your data set. This data set includes daily closing prices for all listed stocks in Taiwan stock market from 1999 to 2017. 

stock <- readRDS("~/hist_prices_df.rds")
#install SIT

con = gzcon(url('https://github.com/systematicinvestor/SIT/raw/master/sit.gz', 'rb'))
source(con)
close(con)
library(xts)
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## Registered S3 method overwritten by 'xts':
##   method     from
##   as.zoo.xts zoo
library(quantmod)
## Loading required package: TTR
## 
## Attaching package: 'TTR'
## The following object is masked _by_ '.GlobalEnv':
## 
##     DVI
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
## Version 0.4-0 included new data defaults. See ?getSymbols.
library(kernlab)
## 
## Attaching package: 'kernlab'
## The following object is masked _by_ '.GlobalEnv':
## 
##     cross
#install.packages('reshape2')
library(reshape2)
## Q2. You have to select at least 10 stocks from the data set. To avoid selecting all stocks from one specific industry, you should select stocks with ticker numbers starting with '1', '2', '3', '4', '5' and '6'. 

stock10 <- stock[,c("date","1110","1201","1713","2031", "6005","6191","2030","9937", "9902","9919")]

sum(is.na(stock10))
## [1] 0
stock.xts <- xts(stock10[,-1], order.by= as.Date(as.character(stock10[,1]), 
                                               format = '%Y%m%d'))
## Q3. Construct equal-weighted portfolio starting from 2007 to 2017. You can use monthly returns to generate the backtesting results.

#convert data into monthly
stock.monthly <- to.monthly(stock.xts, indexAt = 'lastof', OHLC=F)
monthlydata <- stock.monthly["2007/2017"]

#to create equal weight
#we need 5 inputs :
data <- new.env()
data$prices <- monthlydata
data$weight <- monthlydata
data$execution.price <- monthlydata
data$execution.price[] <- NA
data$symbolnames <- colnames(data$prices)
prices = data$prices
n = ncol(prices)
data$weight <- ntop(prices, n)
#1
model <- list()
model$equal.weight <- bt.run(data, trade.summary = T)
## Latest weights :
##            1110 1201 1713 2031 6005 6191 2030 9937 9902 9919
## 2017-12-31   10   10   10   10   10   10   10   10   10   10
## 
## Performance summary :
##  CAGR    Best    Worst   
##  5.5 24.6    -30.1   
#2
capital = 100000
data$weight[] = (capital / prices) * data$weight
equal.weight = bt.run(data, type='share')
## Latest weights :
##            1110 1201 1713 2031 6005 6191 2030 9937 9902 9919
## 2017-12-31   10   10   10   10   10   10   10   10   10   10
## 
## Performance summary :
##  CAGR    Best    Worst   
##  5.5 24.6    -30.1   
head(equal.weight$ret)
##                  1110
## 2007-01-31 0.00000000
## 2007-02-28 0.03707025
## 2007-03-31 0.02699263
## 2007-04-30 0.06698060
## 2007-05-31 0.01999322
## 2007-06-30 0.11529022
bt.detail.summary(model$equal.weight)
## $System
## $System$Period
## [1] "Jan2007 - Dec2017"
## 
## $System$Cagr
## [1] 5.46
## 
## $System$Sharpe
## [1] 0.34
## 
## $System$DVR
##      [,1]
## 1110 0.11
## 
## $System$Volatility
## [1] 24.36
## 
## $System$MaxDD
## [1] -54.32
## 
## $System$AvgDD
## [1] -21.72
## 
## $System$VaR
##     5% 
## -10.45 
## 
## $System$CVaR
## [1] -14.92
## 
## $System$Exposure
## [1] 99.24
## 
## 
## $Trade
## $Trade$Win.Percent
## [1] 70
## 
## $Trade$Avg.Trade
## [1] 4.8
## 
## $Trade$Avg.Win
## [1] 7.6
## 
## $Trade$Avg.Loss
## [1] -1.9
## 
## $Trade$Best.Trade
## [1] 17.77
## 
## $Trade$Worst.Trade
## [1] -4.69
## 
## $Trade$WinLoss.Ratio
## [1] 4.12
## 
## $Trade$Avg.Len
## [1] 131
## 
## $Trade$Num.Trades
## [1] 10
## 
## 
## $Period
## $Period$Win.Percent.Day
## [1] 55.3
## 
## $Period$Best.Day
## [1] 24.6
## 
## $Period$Worst.Day
## [1] -30.1
## 
## $Period$Win.Percent.Month
## [1] 55.3
## 
## $Period$Best.Month
## [1] 24.6
## 
## $Period$Worst.Month
## [1] -30.1
## 
## $Period$Win.Percent.Year
## [1] 54.5
## 
## $Period$Best.Year
## [1] 116
## 
## $Period$Worst.Year
## [1] -35.1
plotbt.monthly.table(model$equal.weight$equity)

##      Jan     Feb     Mar     Apr     May     Jun     Jul     Aug     Sep    
## 2007 "   NA" "  3.7" "  2.7" "  6.7" "  2.0" " 11.5" "  9.8" " -6.8" "  6.7"
## 2008 " -4.1" " 24.0" "  6.3" "  4.2" " -8.1" "-18.4" " -0.9" " -2.3" "-30.1"
## 2009 " -4.7" "  0.3" " 22.8" " 13.7" " 24.6" " -2.2" " 12.8" " -1.5" "  5.2"
## 2010 "-10.9" " -0.7" "  8.1" " -0.9" "-11.3" "  1.4" "  6.0" " -0.5" "  7.1"
## 2011 " -0.6" " -4.9" "  0.3" "  0.7" " -0.8" " -2.8" "  3.1" "-10.3" " -9.2"
## 2012 "  7.6" " 10.7" " -3.8" " -5.8" " -3.4" " -1.7" "  0.6" "  2.9" "  7.4"
## 2013 "  1.2" "  0.1" "  0.4" "  3.7" "  6.8" " -2.8" "  2.6" " -1.4" "  2.8"
## 2014 " -0.7" "  0.1" " -1.3" " -4.5" "  3.4" " -0.1" "  4.4" "  0.6" " -4.2"
## 2015 " -0.1" "  0.4" " -0.7" "  1.0" " -5.0" " -7.1" " -4.0" " -9.1" "  5.9"
## 2016 " -3.9" "  5.1" "  1.9" "  0.1" " -1.2" " -0.8" "  3.7" "  1.6" "  0.4"
## 2017 " -0.1" "  5.9" "  0.8" " -2.3" " -0.1" "  1.2" "  3.8" "  5.5" " -1.6"
## Avg  " -1.6" "  4.1" "  3.4" "  1.5" "  0.6" " -2.0" "  3.8" " -1.9" " -0.9"
##      Oct     Nov     Dec     Year    MaxDD  
## 2007 "-10.6" " -8.3" " -3.8" " 11.4" "-21.5"
## 2008 "-10.1" "  4.8" "  2.7" "-35.1" "-54.3"
## 2009 " -0.3" "  2.7" " 11.1" "116.0" " -4.7"
## 2010 " -2.7" " -1.3" " 10.4" "  2.2" "-15.9"
## 2011 "  5.3" "-12.2" "  1.6" "-27.3" "-28.5"
## 2012 "-10.9" "  3.9" "  7.3" " 13.2" "-14.8"
## 2013 "  4.5" " -2.1" "  3.9" " 21.0" " -2.8"
## 2014 " -6.3" "  2.0" "  4.5" " -2.7" "-10.2"
## 2015 "  5.3" " -6.7" "  3.3" "-16.7" "-23.0"
## 2016 "  0.1" "  6.0" "  2.2" " 15.7" " -3.9"
## 2017 "  3.5" " -1.2" "  3.7" " 20.3" " -2.4"
## Avg  " -2.0" " -1.1" "  4.3" " 10.7" "-16.5"
plotbt.transition.map(model$equal.weight$weight)

strategy.performance.snapshoot(model, T)

## NULL
sma.cross = bt.run(data, trade.summary=T)  
## Latest weights :
##                1110     1201    1713     2031    6005     6191     2030
## 2017-12-31 71174.38 51546.39 59171.6 38167.94 87719.3 76335.88 65359.48
##                9937    9902     9919
## 2017-12-31 25316.46 99009.9 81967.21
## 
## Performance summary :
##  CAGR    Best    Worst   
##  -100    114544.6    -100    
## Q4. Construct MVP portfolio starting from 2004-2017. Year 2004-2006 will be used as in sample data to compute covariance matrix for MVP.

data.monthly <- stock.monthly["2004/2017"]
data.monthly.1 <- stock.monthly["2004/2006"]
Sigma_monthly <- cov(data.monthly.1)
head(Sigma_monthly)
##           1110      1201      1713        2031       6005        6191      2030
## 1110 1.4811913 2.9526414 0.9320837   2.5599910  0.2077950   1.3766294 1.5821007
## 1201 2.9526414 7.0602600 1.9580214   2.4464729  0.5048214   4.1144071 3.3241100
## 1713 0.9320837 1.9580214 0.8667075   0.8199415  0.3474521   0.7908475 1.0728036
## 2031 2.5599910 2.4464729 0.8199415  25.5479094 -1.3473907 -10.6009413 1.6084350
## 6005 0.2077950 0.5048214 0.3474521  -1.3473907  0.4505850   1.0522607 0.5238679
## 6191 1.3766294 4.1144071 0.7908475 -10.6009413  1.0522607  15.6384847 1.3755379
##             9937        9902        9919
## 1110 -0.03836484  1.72698817  0.77693524
## 1201  0.40682143  2.18419000  1.89146571
## 1713  0.28893897  1.12644151  0.37708381
## 2031 -3.81664706  9.43056373  0.83046190
## 6005  0.53722643 -0.08482786 -0.02085714
## 6191  1.35344468 -1.14811563  1.45554667
ones = rep(1,10)     
one.vec = matrix(ones, ncol=1)
a = inv(Sigma_monthly)%*%one.vec
b = t(one.vec)%*%a
mvp.w.monthly =a / as.numeric(b)
mvp.w.monthly
##              [,1]
## 1110  0.355437346
## 1201 -0.196158142
## 1713 -0.074645212
## 2031 -0.004758405
## 6005  0.474764303
## 6191 -0.054887278
## 2030 -0.200969768
## 9937  0.092154782
## 9902  0.002625952
## 9919  0.606436422
mvp.ret<-sum((mvp.w.monthly)*colMeans(data.monthly.1))
mvp.ret
## [1] 6.886455
hist(mvp.w.monthly)

## Q5. Similar to question 4, however, you need to construct MVP portfolio using single factor model (CAPM) to compute covariance matrix and generate backtesting results.
data$prices = data$weight = data$execution.price = monthlydata
data$execution.price[] <- NA
prices <- data$prices
n <- ncol(prices)

constraints = new.constraints(n, lb = -Inf, ub = +Inf)
# SUM x.i = 1
constraints = add.constraints(rep(1, n), 1, type = '=', constraints)        
ret = prices / mlag(prices) - 1
weight = coredata(prices)
weight[] = NA
nrow(prices)
## [1] 132
hist <- na.omit(ret[1:36,])
cov(hist)
##             1110        1201        1713        2031        6005        6191
## 1110 0.018243806 0.012030526 0.012574063 0.015989613 0.015086846 0.006811481
## 1201 0.012030526 0.016363116 0.011593381 0.011610111 0.012064238 0.006641807
## 1713 0.012574063 0.011593381 0.015882476 0.015939212 0.013171598 0.008086392
## 2031 0.015989613 0.011610111 0.015939212 0.027504038 0.021576111 0.012902372
## 6005 0.015086846 0.012064238 0.013171598 0.021576111 0.033026821 0.011348404
## 6191 0.006811481 0.006641807 0.008086392 0.012902372 0.011348404 0.019321391
## 2030 0.013748476 0.010516726 0.013607931 0.018004663 0.016743330 0.010996121
## 9937 0.006013309 0.006149080 0.007142457 0.006573010 0.009182638 0.007118646
## 9902 0.018538958 0.014832400 0.016344588 0.017163931 0.021034044 0.009073662
## 9919 0.004737781 0.007267715 0.006948181 0.007912894 0.005967415 0.007773179
##             2030        9937        9902        9919
## 1110 0.013748476 0.006013309 0.018538958 0.004737781
## 1201 0.010516726 0.006149080 0.014832400 0.007267715
## 1713 0.013607931 0.007142457 0.016344588 0.006948181
## 2031 0.018004663 0.006573010 0.017163931 0.007912894
## 6005 0.016743330 0.009182638 0.021034044 0.005967415
## 6191 0.010996121 0.007118646 0.009073662 0.007773179
## 2030 0.018680911 0.007198008 0.018500762 0.006689200
## 9937 0.007198008 0.010752908 0.013451627 0.005474698
## 9902 0.018500762 0.013451627 0.042596166 0.008930896
## 9919 0.006689200 0.005474698 0.008930896 0.016259516
ia = create.historical.ia(hist,12)
s0 = apply(coredata(hist), 2 , sd)
ia$cov = cor(coredata(hist), use='complete.obs',method='pearson') * (s0 %*% t(s0))
weight[36,] = min.risk.portfolio(ia, constraints)
weight[36,]
##        1110        1201        1713        2031        6005        6191 
##  0.32860178  0.07220353  0.04066975 -0.11344441 -0.01813304  0.04288876 
##        2030        9937        9902        9919 
##  0.10251581  0.57388928 -0.24879832  0.21960686
sum(weight[36,])
## [1] 1
model$min.var.monthly <- bt.run(data, trade.summary = T)
## Latest weights :
##            1110 1201 1713 2031 6005 6191 2030 9937 9902 9919
## 2017-12-31 1405 1940 1690 2620 1140 1310 1530 3950 1010 1220
## 
## Performance summary :
##  CAGR    Best    Worst   
##  -100    1308    -100    
#data$weight[] = weight     
#capital = 100000
#data$weight[] = (capital / prices) * data$weight
# to verify the default do.lag  = 1 day
sum(as.numeric(weight[36,])*as.numeric(ret[37,]))
## [1] -0.11114
model$min.var.monthly$ret[37, ]
##            1110
## 2010-01-31   -1
plotbt.strategy.sidebyside(model, return.table=T, make.plot = T)
## Warning in max(mret, na.rm = T): no non-missing arguments to max; returning -Inf
## Warning in min(mret, na.rm = T): no non-missing arguments to min; returning Inf

##            equal.weight        min.var.monthly    
## Period     "Jan2007 - Dec2017" "Jan2007 - Dec2017"
## Cagr       "5.46"              "-100"             
## Sharpe     "0.34"              "-1.04"            
## DVR        "0.11"              "-0.02"            
## Volatility "24.36"             "699.81"           
## MaxDD      "-54.32"            "-100"             
## AvgDD      "-21.72"            "-100"             
## VaR        "-10.45"            "-100"             
## CVaR       "-14.92"            "NaN"              
## Exposure   "99.24"             "99.24"
plotbt(model)

## Q6. Similar to question 4, however, you need to construct MVP portfolio using Fama French three factor model to compute covariance matrix and generate backtesting results.

constraints = new.constraints(n, lb = -Inf, ub = +Inf)
# SUM x.i = 1
constraints = add.constraints(rep(1, n), 1, type = '=', constraints)   

ret = prices / mlag(prices) - 1
weight = coredata(prices)
weight[] = NA
#
weights = list()
# Equal Weight 1/N Benchmark
weights$equal.weight = weight
weights$equal.weight[] = ntop(prices, n)
start.i = 35
weights$equal.weight[1:start.i,] = NA
#
weights$min.var = weight
weights$min.maxloss = weight
weights$min.mad = weight
weights$min.cvar = weight
weights$min.cdar = weight
weights$min.cor.insteadof.cov = weight
weights$min.mad.downside = weight
weights$min.risk.downside = weight