Skewness Revisited

In my last post http://gekkoquant.com/2013/03/03/trend-following-skewness-signal/ I suggested that measuring the skewness of asset returns can possibly be used to identify trends. Or mathematically more accurately put, it can identify when the return distribution is symmetric and hence NOT in a trending environment (assuming returns are Gaussian with 0 mean).

This post presents a simple regression of Skewness vs Asset returns. The skewness is calculated at time t using OpenCloseReturns[t-1,t-2,…..,t-lookback]. It is then regressed against OpenCloseReturn[t]. Where t donates today, and t-1 donates yesterday.

The data set is 2000 to present.

The red line in the above plot is a linear regression. It’s clear to see that the skewness doesn’t explain the Open Close Returns. I must eat humble pie, the returns seen in the previous post are down to a lucky parameter selection. Thanks must go to Pietro for testing over a longer period.

Onto the code:

?View Code RSPLUS
library("quantmod")
library("PerformanceAnalytics")
library(e1071)     #For the skewness command
 
 
#Script parameters
symbol <- "^GSPC"     #Symbol
 
#Specify dates for downloading data
startDate = as.Date("2000-01-01") #Specify what date to get the prices from
symbolData <- new.env() #Make a new environment for quantmod to store data in
getSymbols(symbol, env = symbolData, src = "yahoo", from = startDate)
mktdata <- eval(parse(text=paste("symbolData$",sub("^","",symbol,fixed=TRUE))))
mktdata <- head(mktdata,-1) #Hack to fix some stupid duplicate date problem with yahoo
OpClRet  <- (Cl(mktdata)/Op(mktdata))    - 1
colnames(OpClRet) <- "OpClRet"
mktdata <- cbind(mktdata,OpClRet)
 
 
getSkewnessFromReturns <- function(mktdata,skewLookback){
   #Calculate the skew
  rollingSkew <- Lag(rollapply(mktdata$OpClRet ,FUN="skewness",width=skewLookback, align="right",na.pad=TRUE),1)
   colnames(rollingSkew) <- "Skew"
  getSkewnessFromReturns <- na.omit(cbind(mktdata$OpClRet,rollingSkew))
}
 
 
 
dev.new()
par(mfrow=c(3,3))
startSkew <-30
stepSize <- 30
numOfSteps <- 9
 
doPlot <- function(x,y,title,xlabel,ylabel){
  #Function to plot data and add regression line
  plotData <-cbind(x,y)
  print(head(plotData))
  colnames(plotData) <-c("x","y")
  plot(coredata(plotData),type="p",main=title, xlab=xlabel,ylab=ylabel)
  abline(lm(y~x),col="red",lwd=1.5)
}
 
 
for(i in seq(startSkew,numOfSteps*stepSize,stepSize)){
dat <- getSkewnessFromReturns(mktdata,i)
colnames(dat) <- c("OpClRet","Skew")
doPlot(dat$Skew,dat$OpClRet,paste("Skewness vs Open Close Returns (lookback=",i,")"),"Skewness","Open Close Returns")
}

 

6 thoughts on “Skewness Revisited

  1. Perhaps skewness isn’t relevant at the index level, but it is an important factor when looking at individual stocks. Historical skewness is a reasonably good estimate for future skewness (a month back and foward), and higher expected skewness = lower expected returns (the lottery stock effect, which has the same behavioral basis as the low volatility effect).

    • Hi Eran,

      I like your blog, I’ve actually visited it previously for some R help 🙂

      Interesting paper will definitely have to give it a more detailed read, both for the skewness element and vol estimation side. I too am generally suspicious of these papers as well.

  2. Linear Regression may not be the best method to measure predictive power of any particular indicator. It is often the case that a linear regression of an indicator with predictive power against future x-day returns has negative R-squared (worse than random) because it’s predictive power “activates” once it reaches a certain threshold.

  3. Nice article and good to have come across your most interesting blog. See my post “Backtesting – toos for fools” at Traders Place. Of course, that headline was tongue in cheek but my experience iover many years is that it is all too easy to be caught out. I am about to link your blog at Traders’ Place. Very enjoyable.

Leave a Reply

Your email address will not be published. Required fields are marked *