# Mean-Reversion Risk Tuning

This is just a test for fun. What if we buy everything that goes down to a certain point, say -%1 or -%5 at the end of the day everyday? There are probably a bunch of programs out there can do this but I prefer something home-made.

To get a list of all publicly traded stocks on NASDAQ, I went to EOData and grabbed a txt file for all NASDAQ tickers. But the trouble was even though the calculation I wanted to perform was simple, the volume was too large for my computer to handle. So I had to push everything to github, start an Amazon EC2 instance, configure it, pull from my own repository, run my script, then push everything back. The process itself is not complicated, just a lot of annoying details.

Anyhow, before everybody gets bored with my geeky life story, here are the results. The numbers in the legend represent mean-reversion signals. For instance, -0.12 means “what if we buy everything that goes down more than 12%?

It seems as we moveing the signal further away from 0, the strategy becomes more aggressive and performance improves gradually, except for -0.19 and -0.20, which might be two outliers or trend changers.

Source code in R.

```## functions
EODMR <- function(returnsData, shockRates = seq(-0.01, -0.2, by = -0.01)) {
output <- mrTest(returnsData, shockRate = 0)
output <- calcRet(output)
outputRet <- output
annRet <- prod(1+output)^(250/length(output))-1
annSd <- sd(output)*sqrt(250)
Sharpe <- annRet/annSd
output <- data.frame(shock0 = rbind(annRet, annSd, Sharpe))
for (i in seq(along = shockRates)) {
testData <- mrTest(returnsData, shockRate = shockRates[i])
finalRet <- calcRet(testData)
outputRet <- merge(outputRet, finalRet)
names(outputRet)[i + 1] <- shockRates[i]
annRet <- prod(1+finalRet)^(250/length(finalRet))-1
annSd <- sd(finalRet)*sqrt(250)
Sharpe <- annRet/annSd
finalRet <- data.frame(rbind(annRet, annSd, Sharpe))
names(finalRet) <- shockRates[i]
output <- cbind(output, finalRet)
print(paste(i, "out of ", length(shockRates), " finished"))
}
return(list(testStat = output, testReturns = outputRet))
}

getReturns <- function(tickers, start = Sys.Date() - 2520,
minVol = 100000) {
returnsData <- get.hist.quote("^GSPC", start = start,
returnsData <- merge(ROC(returnsData), Next(ROC(returnsData)))
names(returnsData) <- paste("SPX", c("Ret0", "Ret1"), sep = ".")

for (i in seq(along = tickers)) {
nextTicker <- NULL
nextTicker <- try(get.hist.quote(tickers[i], start = start,

if (!is.character(nextTicker[1])) {

meanVol <- as.numeric(mean(nextTicker))
if (meanVol >= minVol) {
} else next

nextTicker <- nextTicker[!duplicated(index(nextTicker))]
nextTicker <- merge(ROC(nextTicker), Next(ROC(nextTicker)))
names(nextTicker) <- paste(tickers[i], c("Ret0", "Ret1"), sep = ".")
returnsData <- merge(retournsData, nextTicker)
} else next
print(paste(i, "out of", length(tickers), sep = " "))
}
return(returnsData)
}

# perform MR test
mrTest <- function(returnsData, shockRate = -0.05) {
testRets <- returnsData[, 1:2]
thisName <- gsub(".Ret0", "", names(testRets)[1])
testRets <- ifelse(testRets[, 1] <= shockRate, testRets[, 2], 0)
dim(testRets) <- c(length(testRets), 1)
names(testRets) <- thisName

secNum <- ncol(returnsData) / 2
for (i in 2:secNum) {
thisSec <- returnsData[, (i * 2 - 1):(i * 2)]
thisName <- gsub(".Ret0", "", names(thisSec)[1])
thisSec <- ifelse(thisSec[, 1] <= shockRate, thisSec[, 2], 0)
dim(thisSec) <- c(length(thisSec), 1)
names(thisSec) <- thisName
testRets <- merge(testRets, thisSec)
testRets[is.na(testRets)] <- 0
}
return(testRets)
}

# calculate strategy results
calcRet <- function(testRets) {
timeLength <- nrow(testRets)
finalRet <- rep(0, timeLength)
for (i in 1:timeLength) {
tmp <- as.numeric(testRets[i, ])
tmp <- tmp[tmp != 0]
finalRet[i] <- mean(tmp)
}
finalRet[is.na(finalRet)] <- 0
finalRet <- zoo(finalRet, order.by = index(testRets))
return(finalRet)
}

#### run code
library(tseries)
library(quantmod)
library(PerformanceAnalytics)

# perform test
sep = "\t")[-1, 1])
testNasdaq <- EODMR(returnsNasdaq)

# visualize results
charts.PerformanceSummary(testNasdaq\$testReturns, colorset = rainbow(21), ylog = 1)
chart.RiskReturnScatter(testNasdaq\$testReturns, colorset = rainbow(21), symbolset = rep(3, 21))
```