Varying Window Length for Linear Models on Stocks

April 24, 2012

(This article was first published on » R, and kindly contributed to R-bloggers)

In a previous post, we discussed ideas generated by a Timely Portfolio post about Linear Models on Stock.

I wanted to see if there was a relationship between the window length of the running mean of the linear regression slope estimate and the running mean of the correlation between fitted and observed values.

The parameters are:

  • daily closing values since 2008 for the S&P 500
  • Linear Regression done on periods of 16 data points
  • If running mean of the last n slope coefficients is greater than 0, and running mean of correlation coefficients of fitted vs observed values is greater than 0.25, go long on the index
  • Otherwise, sit aside and wait

Vary n, and see how total return behaves (now that I think of it, I should want to change the size of the data points per linear regression). Results are below, and we have a peak at n = 5 days. The information captured by the linear model seems to be lost as n grows, since we don’t have better return than the index itself at large values of n.

It shouldn’t hard to change the different time period to test the same idea on various historical periods. Alternatively, one could parametrize how far in the past one wants to test this. Here’s the code, in R as usual. I will come back to this with improvements when I get bored.

#GSPC <- to.weekly(GSPC)[,4]
GSPC <- GSPC[,4]
width = 16
for (i in (width+1):NROW(GSPC)) {
        linmod <- lm(GSPC[((i-width):i),1]~index(GSPC[((i-width):i)]))
        ifelse(i==width+1,signal <- coredata(linmod$residuals[length(linmod$residuals)]),
                signal <- rbind(signal,coredata(linmod$residuals[length(linmod$residuals)])))
        ifelse(i==width+1,signal2 <- coredata(linmod$coefficients[2]),
                signal2 <- rbind(signal2,coredata(linmod$coefficients[2])))
        ifelse(i==width+1,signal3 <- cor(linmod$fitted.values,GSPC[((i-width):i),1]),
                signal3 <- rbind(signal3,cor(linmod$fitted.values,GSPC[((i-width):i),1])))
signal <- as.xts(signal,[(width+1):NROW(GSPC)]))
signal2 <- as.xts(signal2,[(width+1):NROW(GSPC)]))
signal3 <- as.xts(signal3,[(width+1):NROW(GSPC)]))
price_ret_signal <- merge(GSPC,lag(signal,k=1),
price_ret_signal[,2] <- price_ret_signal[,2]/price_ret_signal[,1]
price_ret_signal[,3] <- price_ret_signal[,3]/price_ret_signal[,1]
getTotalReturn <- function(i) {
        p <- ifelse(runMean(price_ret_signal[,3],n=i) > 0 & runMean(price_ret_signal[,4],n=i) > 0.25, 1, 0)
        p <- 1+(na.omit(p * price_ret_signal[,5]))
        Reduce("*", coredata(p))
qplot(1:30, unlist(lapply(1:30, getTotalReturn)), geom="line", xlab="x", ylab="total return")

To leave a comment for the author, please follow the link and comment on their blog: » R. offers daily e-mail updates about R news and tutorials on topics such as: Data science, Big Data, R jobs, visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...

If you got this far, why not subscribe for updates from the site? Choose your flavor: e-mail, twitter, RSS, or facebook...

Comments are closed.

Search R-bloggers


Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)