required_pkgs <- c("PerformanceAnalytics", "quantmod", "pbapply", "data.table")
new_pkgs <- required_pkgs[!(required_pkgs %in% installed.packages()[, "Package"])]
if(length(new_pkgs)) install.packages(new_pkgs)
lapply(required_pkgs, require, character.only = TRUE)
## Loading required package: PerformanceAnalytics
## Loading required package: xts
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## 
## Attaching package: 'PerformanceAnalytics'
## The following object is masked from 'package:graphics':
## 
##     legend
## Loading required package: quantmod
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
## Loading required package: pbapply
## Loading required package: data.table
## 
## Attaching package: 'data.table'
## The following objects are masked from 'package:xts':
## 
##     first, last
## The following objects are masked from 'package:zoo':
## 
##     yearmon, yearqtr
## [[1]]
## [1] TRUE
## 
## [[2]]
## [1] TRUE
## 
## [[3]]
## [1] TRUE
## 
## [[4]]
## [1] TRUE
e <- new.env()
tickers <- c("AMZN","BIDU","GLD","GOOGL","GS","IWM","NFLX","MMM","DIA","SPY")
getSymbols(tickers, from = "2003-01-01", env = e)
##  [1] "AMZN"  "BIDU"  "GLD"   "GOOGL" "GS"    "IWM"   "NFLX"  "MMM"   "DIA"  
## [10] "SPY"
PRC <- do.call(merge, eapply(e, Ad)) 
if (last(index(PRC)) != Sys.Date()) {
  last <- pblapply(as.list(gsub(".Adjusted", "", names(PRC))), getQuote)
  PRC <- rbind(PRC, xts(coredata(t(rbindlist(last)$Last)), order.by = Sys.Date()))
}

NOM <- colnames(PRC) <- gsub(".Adjusted", "", names(PRC))
MOMO60 <- round(ROC(PRC, n = 60, type = "discrete"), 4)
MOMO60 <- MOMO60["2003-03-31::"]
PRC <- PRC["2003-03-31::"]
print(head(MOMO60))
##                 GS GLD     IWM GOOGL   NFLX   AMZN     DIA BIDU    MMM     SPY
## 2003-03-31 -0.0209  NA -0.0736    NA 0.7773 0.3301 -0.0691   NA 0.0313 -0.0658
## 2003-04-01 -0.0091  NA -0.0560    NA 0.7523 0.2446 -0.0598   NA 0.0416 -0.0543
## 2003-04-02 -0.0066  NA -0.0483    NA 0.7874 0.2744 -0.0513   NA 0.0564 -0.0482
## 2003-04-03 -0.0032  NA -0.0428    NA 0.8232 0.2367 -0.0562   NA 0.0589 -0.0504
## 2003-04-04  0.0178  NA -0.0360    NA 0.7134 0.2474 -0.0332   NA 0.0715 -0.0308
## 2003-04-07 -0.0175  NA -0.0493    NA 0.6993 0.2503 -0.0505   NA 0.0436 -0.0475
indx <- seq(as.Date("2003-03-31"), length.out = 300, by = "4 weeks")
indx2 <- ifelse(!(indx %in% index(MOMO60)), paste(indx + 1), paste(indx))

SELECT <- MOMO60[paste(indx2)]
PRC2 <- PRC[paste(indx2)]
print(dim(SELECT))
## [1] 287  10
print(head(SELECT))
##                 GS GLD     IWM GOOGL    NFLX   AMZN     DIA BIDU     MMM
## 2003-03-31 -0.0209  NA -0.0736    NA  0.7773 0.3301 -0.0691   NA  0.0313
## 2003-04-28  0.1369  NA  0.0765    NA  0.7546 0.3341  0.0753   NA  0.0287
## 2003-05-27  0.1318  NA  0.1881    NA  0.3261 0.5834  0.1125   NA  0.0112
## 2003-06-23  0.2102  NA  0.1944    NA -0.0106 0.2812  0.1142   NA -0.0106
## 2003-07-21  0.1097  NA  0.1691    NA  0.0686 0.4064  0.0855   NA  0.0903
## 2003-08-18  0.1644  NA  0.1634    NA  0.1000 0.3036  0.1017   NA  0.1568
##                SPY
## 2003-03-31 -0.0658
## 2003-04-28  0.0916
## 2003-05-27  0.1282
## 2003-06-23  0.1334
## 2003-07-21  0.0796
## 2003-08-18  0.0777
ASSETS4 <- combn(NOM, 4)
print(dim(ASSETS4))
## [1]   4 210
MOMO <- function(x) {
  y <- ASSETS4[, x]
  S <- SELECT[, y]
  SEQ <- as.numeric(apply(S, 1, which.max))
  
  prc2 <- round(PRC2[, y], 2)
  RETS <- CalculateReturns(prc2, method = "discrete")
  
  ALL <- do.call(merge, lapply(as.list(1:ncol(RETS)), function(x) {
    Lag(reclass(ifelse(SEQ == x, 1, 0), match.to = S) * RETS[, x])
  }))
  
  colnames(ALL) <- names(prc2)
  ALL[is.na(ALL)] <- 0
  
  EQT <- reclass(rowSums(ALL), match.to = ALL)
  EQT[is.na(EQT)] <- 0
  colnames(EQT) <- paste(names(prc2), collapse = "-")
  EQT
}
example_result <- MOMO(1)
print(head(example_result))
##            GS-GLD-IWM-GOOGL
## 2003-03-31       0.00000000
## 2003-04-28       0.00000000
## 2003-05-27       0.12551020
## 2003-06-23       0.08577263
## 2003-07-21       0.08661835
## 2003-08-18       0.04296161
STRAT <- pblapply(as.list(1:ncol(ASSETS4)), function(x) MOMO(x))
AAA <- pblapply(STRAT, colSums)
df <- STRAT[order(sapply(AAA, "[[", 1))]
df <- df[(length(df) - 9):length(df)]
TOP10 <- do.call(merge, df)

print(head(TOP10))
##            GOOGL.NFLX.DIA.BIDU GS.GOOGL.NFLX.BIDU GOOGL.NFLX.BIDU.MMM
## 2003-03-31         0.000000000        0.000000000          0.00000000
## 2003-04-28         0.000000000        0.000000000          0.00000000
## 2003-05-27         0.089655172        0.089655172          0.08965517
## 2003-06-23         0.025316456        0.025316456          0.02531646
## 2003-07-21         0.037249815        0.086618349         -0.04938272
## 2003-08-18         0.004109344        0.004880429          0.05263158
##            GS.NFLX.AMZN.BIDU IWM.NFLX.AMZN.BIDU NFLX.AMZN.BIDU.MMM
## 2003-03-31       0.000000000        0.000000000        0.000000000
## 2003-04-28       0.000000000        0.000000000        0.000000000
## 2003-05-27       0.089655172        0.089655172        0.089655172
## 2003-06-23       0.191780822        0.191780822        0.191780822
## 2003-07-21       0.022988506        0.022988506        0.022988506
## 2003-08-18      -0.005617978       -0.005617978       -0.005617978
##            NFLX.AMZN.BIDU.SPY GOOGL.NFLX.AMZN.BIDU NFLX.AMZN.DIA.BIDU
## 2003-03-31        0.000000000          0.000000000        0.000000000
## 2003-04-28        0.000000000          0.000000000        0.000000000
## 2003-05-27        0.089655172          0.089655172        0.089655172
## 2003-06-23        0.191780822          0.191780822        0.191780822
## 2003-07-21        0.022988506          0.022988506        0.022988506
## 2003-08-18       -0.005617978         -0.005617978       -0.005617978
##            GLD.NFLX.AMZN.BIDU
## 2003-03-31        0.000000000
## 2003-04-28        0.000000000
## 2003-05-27        0.089655172
## 2003-06-23        0.191780822
## 2003-07-21        0.022988506
## 2003-08-18       -0.005617978
stats_top10 <- table.Stats(TOP10)
print(stats_top10)
##                 GOOGL.NFLX.DIA.BIDU GS.GOOGL.NFLX.BIDU GOOGL.NFLX.BIDU.MMM
## Observations               287.0000           287.0000            287.0000
## NAs                          0.0000             0.0000              0.0000
## Minimum                     -0.2156            -0.2156             -0.2156
## Quartile 1                   0.0000             0.0000              0.0023
## Median                       0.0555             0.0648              0.0585
## Arithmetic Mean              0.0807             0.0819              0.0827
## Geometric Mean               0.0737             0.0747              0.0757
## Quartile 3                   0.1343             0.1376              0.1347
## Maximum                      1.0086             1.0086              1.0086
## SE Mean                      0.0076             0.0078              0.0077
## LCL Mean (0.95)              0.0657             0.0666              0.0676
## UCL Mean (0.95)              0.0957             0.0972              0.0978
## Variance                     0.0168             0.0173              0.0168
## Stdev                        0.1295             0.1314              0.1298
## Skewness                     1.9317             1.7816              1.8658
## Kurtosis                     8.9886             8.3251              8.7902
##                 GS.NFLX.AMZN.BIDU IWM.NFLX.AMZN.BIDU NFLX.AMZN.BIDU.MMM
## Observations             287.0000           287.0000           287.0000
## NAs                        0.0000             0.0000             0.0000
## Minimum                   -0.2605            -0.2156            -0.2605
## Quartile 1                 0.0000             0.0000             0.0048
## Median                     0.0673             0.0648             0.0635
## Arithmetic Mean            0.0832             0.0839             0.0843
## Geometric Mean             0.0751             0.0762             0.0764
## Quartile 3                 0.1443             0.1438             0.1433
## Maximum                    1.0086             1.0086             1.0086
## SE Mean                    0.0081             0.0080             0.0081
## LCL Mean (0.95)            0.0671             0.0681             0.0684
## UCL Mean (0.95)            0.0992             0.0996             0.1002
## Variance                   0.0190             0.0184             0.0187
## Stdev                      0.1380             0.1358             0.1368
## Skewness                   1.5464             1.6751             1.5653
## Kurtosis                   6.8450             7.2874             7.1458
##                 NFLX.AMZN.BIDU.SPY GOOGL.NFLX.AMZN.BIDU NFLX.AMZN.DIA.BIDU
## Observations              287.0000             287.0000           287.0000
## NAs                         0.0000               0.0000             0.0000
## Minimum                    -0.2156              -0.2605            -0.2156
## Quartile 1                  0.0014               0.0008             0.0004
## Median                      0.0631               0.0659             0.0631
## Arithmetic Mean             0.0845               0.0846             0.0849
## Geometric Mean              0.0769               0.0766             0.0774
## Quartile 3                  0.1438               0.1433             0.1438
## Maximum                     1.0086               1.0086             1.0086
## SE Mean                     0.0079               0.0081             0.0079
## LCL Mean (0.95)             0.0688               0.0686             0.0693
## UCL Mean (0.95)             0.1001               0.1005             0.1005
## Variance                    0.0181               0.0188             0.0180
## Stdev                       0.1346               0.1371             0.1342
## Skewness                    1.7391               1.5609             1.7533
## Kurtosis                    7.5639               7.0367             7.6410
##                 GLD.NFLX.AMZN.BIDU
## Observations              287.0000
## NAs                         0.0000
## Minimum                    -0.1739
## Quartile 1                  0.0040
## Median                      0.0659
## Arithmetic Mean             0.0860
## Geometric Mean              0.0787
## Quartile 3                  0.1402
## Maximum                     1.0086
## SE Mean                     0.0078
## LCL Mean (0.95)             0.0706
## UCL Mean (0.95)             0.1013
## Variance                    0.0174
## Stdev                       0.1318
## Skewness                    1.8295
## Kurtosis                    8.3242
chart.RiskReturnScatter(TOP10, add.sharpe = c(1), Rf = 0.03 / sqrt(252),
                        colorset = rich10equal, xlim = c(0.45, 0.55), ylim = c(1.4, 1.75))
## Warning in rug(side = 2, returns, col = element.color): some values will be
## clipped

AAA_top10 <- lapply(df, colSums)  # re-calculate sums for just top 10
best_index <- which.max(sapply(AAA_top10, "[[", 1))
EQT <- df[[best_index]]

charts.PerformanceSummary(EQT, geometric = TRUE)

table.Stats(EQT)
##                 GLD-NFLX-AMZN-BIDU
## Observations              287.0000
## NAs                         0.0000
## Minimum                    -0.1739
## Quartile 1                  0.0040
## Median                      0.0659
## Arithmetic Mean             0.0860
## Geometric Mean              0.0787
## Quartile 3                  0.1402
## Maximum                     1.0086
## SE Mean                     0.0078
## LCL Mean (0.95)             0.0706
## UCL Mean (0.95)             0.1013
## Variance                    0.0174
## Stdev                       0.1318
## Skewness                    1.8295
## Kurtosis                    8.3242
table.Drawdowns(EQT)
##         From     Trough         To   Depth Length To Trough Recovery
## 1 2008-10-06 2008-12-01 2009-03-23 -0.3173      7         3        4
## 2 2004-08-16 2004-12-06 2005-05-23 -0.2490     11         5        6
## 3 2016-01-19 2016-02-16 2016-06-06 -0.1997      6         2        4
## 4 2021-04-05 2021-05-03 2021-08-23 -0.1963      6         2        4
## 5 2011-10-31 2012-01-23 2012-02-21 -0.1906      5         4        1