TrendValue.R (Source)

# Trend Value
#https://www.valuesignals.com/Screens/Details/OShaughnessy_Trending_Value
#fix dplr undef13
if(!require("pacman")){
  install.packages("pacman")
}
rm(list = ls(all = TRUE))
# library(dplyr)
# library(quantmod)
# library(xlsx)
pacman::p_load(bindrcpp,dplyr, quantmod, xlsx, rio)
#Momentum will be Regression Relative Strength instead. 126 == 6 month
# 21,42,63,126,189
trenddays <- 126
SIGMA <- 0
ifelse(dir.exists("C:/Users/msghe/OneDrive/Stocks/R"),
       setwd("C:/Users/msghe/OneDrive/Stocks/R"), setwd("C:/Users/michael/SkyDrive/Stocks/R"))
  
stockdata <-
  read.csv("data/WEEKLY.TXT",
           header = FALSE,
           stringsAsFactors = FALSE,
           na.strings = '-99999999.990')
stocknames <-
  read.csv(
    "data/WEEKLY_KEY.TXT",
    header = FALSE,
    stringsAsFactors = FALSE,
    na.strings = '-99999999.990'
  )
stocknames[, 1]
names(stockdata) <- stocknames[, 1]
#clean ticker name for yahoo finance
stockdata$TICKER <- gsub('.', '-', stockdata$TICKER, fixed = TRUE)
# Remove bad tickers
#NA bad data
# stockdata[stockdata == -99999999.990] <- NA
stockdata <- stockdata[complete.cases(stockdata$TICKER),]
#Create all stock universe
# All stocks is 150 million in  1995 $$. It is adjusted to todays dollors. All
# stocks exclude over the counter.
# min.mark.cap <- quantile(stockdata$MKTCAP, na.rm = TRUE)[[2]]
#find inflation Market Cap 150 @ 1995
getSymbols("CPIAUCSL", src = "FRED")
deflator  <-
  last(Cl(to.yearly(CPIAUCSL)))[[1]] / Cl(to.yearly(CPIAUCSL))['1995'][[1]]
tvminmarketcap <- 150 * deflator
allstock <- stockdata[stockdata$MKTCAP >  tvminmarketcap,]
# stockdata[stockdata$MKTCAP > quantile(stockdata$MKTCAP, na.rm = TRUE)[[4]],]
#Minimum market cap for later sanity
#I will not invest in over the counter
condition <- c("N - New York", "A - American", "M - Nasdaq")
allstock <- filter(allstock, EXCHG_DESC %in% condition)
# min.mark.cap <- median(allstock$MKTCAP, na.rm = TRUE)
# min.mark.cap <- quantile(allstock$MKTCAP, na.rm = TRUE)[[2]]
#add market cap requirement
# allstock <- filter(allstock, MKTCAP > min.mark.cap)
#Minimum Market Cap
min(allstock$MKTCAP)
#Start Ranking the stocks
#Calculate VC2
#subtract ntile from 101 to reverse (correct) Order. So Small is big
allstock$PBVPS.Rank <- 101 - ntile(allstock$PBVPS, 100)
allstock$PE.Rank <- 101 - ntile(allstock$PE, 100)
allstock$PSPS.Rank <- 101 - ntile(allstock$PSPS, 100)
allstock$EVEDA_12M.Rank <- 101 - ntile(allstock$EVEDA_12M, 100)
allstock$PCFPS.Rank <- 101 - ntile(allstock$PCFPS, 100)
allstock$SHY.Rank <- ntile(allstock$SHY, 100)
#Stocks with no rank get 50
allstock$PBVPS.Rank[is.na(allstock$PBVPS.Rank)] <- 50
allstock$PE.Rank[is.na(allstock$PE.Rank)] <- 50
allstock$PSPS.Rank[is.na(allstock$PSPS.Rank)] <- 50
allstock$EVEDA_12M.Rank[is.na(allstock$EVEDA_12M.Rank)] <- 50
allstock$PCFPS.Rank[is.na(allstock$PCFPS.Rank)] <- 50
allstock$SHY.Rank[is.na(allstock$SHY.Rank)] <- 50
#Sum the Ranks
allstock$SumRank <-
  allstock$PBVPS.Rank + allstock$PE.Rank + allstock$PSPS.Rank + allstock$EVEDA_12M.Rank + allstock$PCFPS.Rank + allstock$SHY.Rank
# Calculate VC2
allstock$VC2 <- ntile(allstock$SumRank, 100)
#Get top 10% of allstock
tvstocks <- filter(allstock, VC2 > 70)
#I like Fscore >= 5, Z score >=3
# However, just use Fscore >= 7
#Clean data
tvstocks <- tvstocks[complete.cases(tvstocks$FSCORE_12M),]
# tvstocks <- tvstocks[complete.cases(tvstocks$ZSCORE_Q1),]
#Zscore Prime
# tvstocks <- tvstocks[complete.cases(tvstocks$UDEF13),]
#weed out must sells
# tvstocks <- filter(tvstocks, FSCORE_12M >= 4, ZSCORE_Q1 >= 1.8)
tvstocks <- filter(tvstocks, FSCORE_12M >= 7)
#My Market Cap Needs
# tvstocks <- filter(tvstocks, MKTCAP > min.mark.cap)
# tvstocks <- filter(, YIELD > 0)
#Final Cleaning
# tvstocks <- tvstocks[complete.cases(tvstocks$RPS_6M),]
# tvstocks <- tvstocks[complete.cases(tvstocks$RS_26W),]
# tvstocks <- filter(tvstocks,RS_26W > 0)
# tvstocks <- filter(tvstocks,RS_26W >= median(allstock$PRCHG_26W, na.rm = TRUE))
tvstocks <- filter(tvstocks,PRCHG_13W >= median(allstock$PRCHG_13W, na.rm = TRUE))
# head((screen[order(as.numeric(screen$SCORE), decreasing =  TRUE),]),25) #[1]
# head((screen[order(as.numeric(screen$SCORE), decreasing =  TRUE),]),25) #[1]
# names(stockdata) <- stocknames$V1
# screen.rpt <- left_join(screen, stockdata, by = "TICKER")
# screen.rpt <- arrange(screen.rpt, desc(as.numeric(SCORE)))
# screen.rpt$SCORE <- round(as.numeric(screen.rpt$SCORE), 4)
# # screen.rpt <- arrange(screen.rpt, desc(as.numeric(PRCHG_26W)))
# nrow(screen.rpt)
# stockenv <- new.env()
# getSymbols(tvstocks$TICKER, env = stockenv, adjust=TRUE)
# getSymbols(tvstocks$TICKER, env = stockenv)
# rm(screen)
# Keep it simple, stop using RRS
# tvstocks[,"krs26"] <- NA
# for (i in ls(stockenv)) {
#     print(i)
#     # tvstocks[tvstocks$TICKER == i,"krs26"] <- last(Ad(stockenv[[i]]),1)[[1]]/last(SMA(Ad(stockenv[[i]]),126),1)[[1]]
#     tvstocks[tvstocks$TICKER == i,"krs26"] <- last(Ad(stockenv[[i]]),1)[[1]]/ mean(last(Ad(stockenv[[i]]),126))
# }
screen.rpt <- arrange(tvstocks,desc(as.numeric(PRCHG_26W)))
# screen.rpt <- arrange(tvstocks,desc(as.numeric(RPS_6M)))
# screen.rpt <- arrange(tvstocks,desc(as.numeric(krs26)))
screen.rpt <-
  select(screen.rpt, TICKER, COMPANY, SMG_DESC, PRCHG_26W, MKTCAP,FSCORE_12M,VC2)
head(screen.rpt,25)
write.xlsx(
  head(screen.rpt, 25),
  "MoneyPicks.xlsx",
  sheetName = "Money",
  append = FALSE,
  row.names = FALSE
)
rio::export(head(screen.rpt, 25),"MoneyPicks.csv")