Are High Frequency Traders Prudent and Temperate? R/Finance Chicago 2015 Jerzy Pawlowski jp3900@nyu.edu NYU Polytechnic School of Engineering May 28, 2015 Jerzy Pawlowski (NYU Polytechnic) Are High Frequency Traders Prudent and Temperate? May 28, 2015 1 / 10
Prudence and Temperance Prudence and Temperance Risk averse investors prefer positive means (first moment) and small variance (second moment), Investors may also have preferences for higher moments - they may prefer large positive odd moments and small even moments, Prudence refers to the preference for large positive skewness (third moment), Temperance refers to the preference for small kurtosis (fourth moment), Amaya et al., Does Realized Skewness Predict the Cross-Section of Equity Returns? papers.ssrn.com/sol3/papers.cfm? abstract id=1898735 > sym_bol <- load(file.path(output_dir, 6e 05 4e 05 2e 05 0e+00 2e 05 4e 05 6e 05 + paste0(sym_bol, ".RData"))) Returns > re_turns <- calc_rets(xts_data=to.daily(get(sym_bol))) > len_rets <- nrow(re_turns) # number of observations > library(performanceanalytics) > mean_rets <- mean(re_turns[, 1]) # calculate mean > chart.histogram(re_turns[, 1], main="", > sd_rets <- sd(re_turns[, 1]) # calculate standard + xlim=c(-6e-5, deviation 6e-5), > # calculate skew and kurtosis + methods = c("add.density", "add.normal")) > (sum(((re_turns[, 1] - mean_rets)/sd_rets)^3))/len_rets > # add title [1] -0.3773046 > title(main=paste(sym_bol, > (sum(((re_turns[, 1] - mean_rets)/sd_rets)^4))/len_rets + "density"), line=-1) [1] 7.448475 Jerzy Pawlowski (NYU Polytechnic) Are High Frequency Traders Prudent and Temperate? May 28, 2015 2 / 10 Density 0 10000 20000 30000 40000 50000 SPY density
Package HighFreq for Managing High Frequency Data Package HighFreq for Managing High Frequency Data Package HighFreq contains functions for managing high frequency TAQ and OHLC market data: reading and writing data from files, managing time zones and alligning indices, chaining and joining time series, scrubbing bad data points, converting TAQ data to OHLC format, aggregating data to lower frequency, HighFreq is inspired by the package highfrequency, and follows many of its conventions, HighFreq depends on packages xts, quantmod, lubridate, and catools, The function scrub agg() scrubs a single day of TAQ data, aggregates it, and converts it to OHLC format, The function save scrub agg() loads, scrubs, aggregates, and binds multiple days of TAQ data for a single symbol, and saves the OHLC > # install package "HighFreq" from github > install.packages("devtools") > library(devtools) > install_github(repo="algoquant/highfreq") > # load package "HighFreq" > library(highfreq) > # set data directories > data_dir <- "C:/Develop/data/hfreq/src/" > output_dir <- "C:/Develop/data/hfreq/scrub/" > # define sym_bol > sym_bol <- "SPY" > # load a single day of TAQ data > sym_bol <- load( + file.path(data_dir, + paste0(sym_bol, "/2014.05.02.", + sym_bol, ".RData"))) > # scrub, aggregate single day of TAQ data to OH > ohlc_data <- scrub_agg(taq_data=get(sym_bol)) > # aggregate TAQ data for symbol, save to file > save_scrub_agg(sym_bol, + data_dir=data_dir, + output_dir=output_dir, + period="minutes") Jerzy Pawlowski (NYU Polytechnic) Are High Frequency Traders Prudent and Temperate? May 28, 2015 3 / 10
High Frequency OHLC Data High Frequency OHLC Data Aggregating high frequency TAQ data into OHLC format with lower periodicity allows for data compression while maintaining some information about volatility, SPY [2013 11 11 09:31:00/2013 11 11 10:30:00] Last.245 > # load package "HighFreq" > library(highfreq) > # define sym_bol > sym_bol <- "SPY" > # load OHLC data > output_dir <- "C:/Develop/data/hfreq/scrub/" > sym_bol <- load( + file.path(output_dir, + paste0(sym_bol, ".RData"))) > ran_ge <- "2013-11-11 09:30:00/ + 2013-11-11 10:30:00" > chartseries(get(sym_bol)[ran_ge], + name=sym_bol, + theme=charttheme("white")) 80 60 40 20 Volume (10,000s): 122,079 Nov 11 09:31 Nov 11 09:45 Nov 11 10:00 Nov 11 10:15 Nov 11 10:30 176 Jerzy Pawlowski (NYU Polytechnic) Are High Frequency Traders Prudent and Temperate? May 28, 2015 4 / 10
Estimating Volatility From OHLC Data Estimating Volatility From OHLC Data Package TTR contains statistical estimators and technical indicators implemented in fast C code, The function volatility() from package TTR estimates the volatility from OHLC data, volatility() includes the Garman-Klass estimator: σ 2 = 1 n (0.5(H i L i ) 2 (2 log 2 1)(C i O i ) 2 ) n i=1 and the Rogers-Satchell estimator: σ 2 = 1 n ((H i O i )(H i C i )+(L i O i )(L i C i )) n i=1 SPY vol w/ ON spikes [2013 11 11 09:31:00/2013 11 15 16:01:00] Last 212285482358945 Nov 11 09:31 Nov 12 11:00 Nov 13 13:00 Nov 14 15:00 Nov 15 16:01 SPY vol w/o ON spikes [2013 11 11 09:31:00/2013 11 15 16:01:00] > library(ttr) Last 202356368280286 > ran_ge <- "2013-11-11/2013-11-15" > vol_at <- volatility(ohlc=get(sym_bol), + calc="yang.zhang", n=20) > chartseries(vol_at[ran_ge], + name=paste(sym_bol, "vol w/ ON spikes"), + theme=charttheme("white")) > vol_at <- volatility(ohlc=get(sym_bol), + calc="rogers.satchell", n=20) > chartseries(vol_at[ran_ge], + name=paste(sym_bol, "vol w/o ON spikes"), + theme=charttheme("white")) Jerzy Pawlowski (NYU Polytechnic) Are High Frequency Traders Prudent and Temperate? May 28, 2015 5 / 10 1 1
Estimating Skew From OHLC Data Estimating Skew From OHLC Data The function skew ohlc() from package HighFreq calculates a skew-like indicator: s 2 = 1 n ((H i O i )(H i C i )(H i 0.5(O i +C i ))+ n i=1 (L i O i )(L i C i )(L i 0.5(O i + C i )) The function run moment ohlc() calculates running, volume weighted moment estimators, SPY volatility [2013 11 11 09:31:00/2013 11 15 16:01:00] Last 2.99307888786467e 07 2.0e 1.5e 1.0e 5.0e > library(highfreq) # load package "HighFreq" > # running volatility > vol_at <- run_moment_ohlc(ohlc=get(sym_bol)) > # running skew Nov 11 09:31 Nov 12 11:00 Nov 13 13:00 Nov 14 15:00 Nov 15 16:01 > sk_ew <- run_moment_ohlc(ohlc=get(sym_bol), SPY Skew [2013 11 11 09:31:00/2013 11 15 16:01:00] + mom_fun="skew_ohlc") Last 0.172289096995354 1.0 > sk_ew <- sk_ew/(vol_at)^(1.5) > sk_ew[1, ] <- 0 > sk_ew <- na.locf(sk_ew) 0.5 > ran_ge <- "2013-11-11/2013-11-15" > chartseries(vol_at[ran_ge], + name=paste(sym_bol, "volatility"), + theme=charttheme("white")) > chartseries(sk_ew[ran_ge], + name=paste(sym_bol, "Skew"), + theme=charttheme("white"), + yrange=c(-1, 1)) Jerzy Pawlowski (NYU Polytechnic) Are High Frequency Traders Prudent and Temperate? May 28, 2015 6 / 10 e 0.5 1.0
Daily Volatility and Skew From OHLC Data 1.0 Daily Volatility and Skew From OHLC Data The function moment ohlc() calculates the volume weighted moment of a OHLC time series, SPY volatility [2013 06 03 16:01:00/2014 05 19 16:01:00] Last 4.2222840587386e 08 5e > library(highfreq) # load package "HighFreq" > # daily volatility and skew > vol_at <- apply.daily(x=get(sym_bol), + FUN=moment_ohlc) > colnames(vol_at) <- paste( + strsplit(colnames(get(sym_bol))[1], + split="[.]")[[1]][1], "Vol", sep=".") > sk_ew <- apply.daily(x=get(sym_bol), + FUN=moment_ohlc, mom_fun="skew_ohlc") > sk_ew <- sk_ew/(vol_at)^(1.5) > colnames(sk_ew) <- paste( + strsplit(colnames(get(sym_bol))[1], + split="[.]")[[1]][1], "Skew", sep=".") > ran_ge <- "2013-06-01/" > chartseries(vol_at[ran_ge], + name=paste(sym_bol, "volatility"), + theme=charttheme("white")) > chartseries(sk_ew[ran_ge], + name=paste(sym_bol, "Skew"), + theme=charttheme("white"), + yrange=c(-1, 1)) 4e 3e 2e 1e 0e+ Jun 03 2013 Sep 03 2013 Dec 02 2013 Mar 03 2014 May 19 2014 SPY Skew [2013 06 03 16:01:00/2014 05 19 16:01:00] Last 358323452179414 1.0 0.5 0.5 Jerzy Pawlowski (NYU Polytechnic) Are High Frequency Traders Prudent and Temperate? May 28, 2015 7 / 10
Daily Strategy Using Skew Oscillator Daily Strategy Using Skew Oscillator > # daily contrarian trading strategy > re_turns <- get(sym_bol)[index(sk_ew), 4] > re_turns <- diff(log(re_turns)) > colnames(re_turns) <- paste(sym_bol, "Ret", sep=".") > po_sition <- -lag(sk_ew) > colnames(po_sition) <- paste0(sym_bol, ".Position") > po_sition <- na.omit(merge(po_sition, re_turns)) > # scatterplot of sk_ew and re_turns > ran_ge <- "2008-09/2009-05" > plot(coredata(po_sition[ran_ge])) > cor.test(coredata(po_sition[ran_ge])[, 1], + coredata(po_sition[ran_ge])[, 2]) 0.10 5 5 0.10 SPY.Ret SPY.Position 1.5 1.0 0.5 0.5 1.0 Pearson's product-moment correlation po_sition 2008 01 03 16:01:00 / 2014 05 19 16:01:00 data: coredata(po_sition[ran_ge])[, 1] and coredata(po_sition[ran_ge])[, 0.4 2] t = 1.9637, df = 185, p-value = 5107 alternative hypothesis: true correlation is not equal 0.3 to 0 95 percent confidence interval: -06168158 0.2806284438 0.2 sample estimates: cor 0.1 0.1428891 > po_sition <- cumsum(po_sition[, 1]*po_sition[, 2]) > plot(po_sition) 0.4 0.3 0.2 0.1 Jan 03 2008 Jan 02 2009 Jan 04 2010 Jan 03 2011 Jan 03 2012 Jan 02 2013 Dec 31 2013 Jerzy Pawlowski (NYU Polytechnic) Are High Frequency Traders Prudent and Temperate? May 28, 2015 8 / 10
Intraday Strategy Using Skew Oscillator Intraday Strategy Using Skew Oscillator cumu_pnl 2008 01 02 09:31:00 / 2014 05 19 16:01:00 > # intraday contrarian trading strategy > re_turns <- calc_rets(xts_data=get(sym_bol)) 0.8 > thresh_old <- 0.2 # signal threshold trading level > po_sition <- NA*numeric(nrow(sk_ew)) > po_sition <- ifelse(sk_ew>thresh_old, -1, po_sition) 0.6 > po_sition <- ifelse(sk_ew<(-thresh_old), 1, po_sition) > po_sition <- ifelse((sk_ew*lag(sk_ew))<0, 0, po_sition) > # lag the po_sition > po_sition <- c(0, po_sition) > po_sition <- po_sition[-length(po_sition)] > po_sition <- na.locf(po_sition) > po_sition <- merge(sk_ew, po_sition) > colnames(po_sition)[2] <- + paste0(sym_bol, ".Position") > # cumulative PnL > cumu_pnl <- cumsum(po_sition[, 2]*re_turns[, 1]) > plot(cumu_pnl, format.labels="%y-%m") 0.4 0.2 2008 01 2008 07 2009 01 2009 07 2010 01 2010 07 2011 01 2011 07 2012 01 2012 07 2013 01 2013 07 2013 12 0.8 0.6 0.4 0.2 Jerzy Pawlowski (NYU Polytechnic) Are High Frequency Traders Prudent and Temperate? May 28, 2015 9 / 10
Conclusion Conclusion Open questions: is there any interaction between volatility and skew? what is relationship between returns and cross-section of skew? does firm size have any effect? persistence of anomaly over time, Acknowledgements: Brian Peterson for Thomson Reuters tick data, Jeffrey Ryan, Joshua Ulrich, and Brian Peterson for packages xts, quantmod, PerformanceAnalytics, and TTR, Jerzy Pawlowski (NYU Polytechnic) Are High Frequency Traders Prudent and Temperate? May 28, 2015 10 / 10