Monday, July 1, 2013

Mean Reversion revisited: S&P 500 (What changed in 1987?)

18 Months ago I posted an article about my mean reversion trading in the S&P 500 and a larger view on the history with index data. The data shown is a composite of 8 different strategies in the S&P 500 I monitor. Some of them I trade with the eMini S&P Future. The data used here is daily index data from Yahoo.

Most striking was that the overall systematic approach to mean reversion trading was not working before '87. Especially between 1963 and 1973 it was horrible - a system that you would like to trade, but exactly the other side of each trade. Something that I still cannot explain. But obviously the structure of market movements changed strongly. Thus mean reversion in equity trading is something everyone trading should monitor closely.  

The updated long term chart:
S&P 500 Index - Mean reversion composite





This looks still quite compelling. The big picture is still on track. Zooming in to the recent out-of-sample period......
S&P 500 Index - Mean reversion composite

Still an uptrend but the it looks a bit choppy now. This is also what I experienced by trading mean reversion systems in the last 2 years. Mean reversion needs a larger range for worst case stops, otherwise the expected return suffers. Thus in case of a stopped out trade it is quite hurting the performance as in January 2012 and April/May 2013.

Looking at the distributions....
S&P 500 Index - Mean reversion composite / Distribution of returns

.... and the numbers*:














What is the conclusion out of this? As a lot others in the quant trading blogosphere noted before: The best times for mean reversion systems seem to be over. Pure, unfiltered signals are even more problematic since 2010. I slightly reduced the exposure to mean reversion in my trading portfolio in the last year. But I am still trading 'my' markets monitoring the results and risks closely.   


* please note that the numbers differ a bit from the former post. In addition the Max DD % 'After Crash '87' was wrong/too high in the last post.


Disclaimer

The information on this site is provided for statistical and informational purposes only. Nothing herein should be interpreted or regarded as personalized investment advice or to state or imply that past results are an indication of future performance. The author of this website is not a licensed financial advisor and will not accept liability for any loss or damage, including without limitation to, any loss of profit, which may arise directly or indirectly from use of or reliance on the content of this website(s).  


Under no circumstances does this information represent an advice or recommendation to buy, sell or hold any security.

Tuesday, December 27, 2011

Mean Reversion: What changed in 1987?

Since 8 months I am actively trading some mean reversion strategies as a great diversifier to my intraday trading approach. Until now it worked out quite well.
However to diversify also within the strategy set of mean reversion I use different indicators as entry signals like RSI, DV, CCI and Simple vs. Exponential Moving Averages. To improve Draw Down, Hit Ratio and overall system stability I use multiple filters like trend direction, trend strength and the volatility level.
Last week I spoke with Joachim (has also a German blog) about my approach and he showed me long term chart about a common mean reversion strategy posted in a German forum some time ago. I was quite shocked, as I wasn't aware of these very different time periods for mean reversion before and after the crash of 1987. I don't know if this phenomenon is commonly known.

I trade also the eMini S&P, but was only testing back to 1997 for this market. In order to find out how my current setup would have suffered in former times I have tested my S&P mean reversion 'composite' (consisting of 8 different strategies, no leverage here) back to 1963 with index data from Yahoo. It's 1963 because untill '62 the history has no OHLC data, which I need for some indicators and filters.


S&P 500 Index - Mean reversion composite

The results are horrible till the early '90s. From 1963 until 1973 the equity line drops constantly for ten years and is then building a bottom for almost twenty years. Interesting indeed is that since the crash in 1987 the results are much better. It seems that the market has changed somehow dramatically after these two crash days . For futher analysis I have divided the single trades in two parts before and after the market crash end of october 1987.

Looking at the distributions....

S&P 500 Index - Mean reversion composite / Distribution of returns

.... and the statistics:



After the crash '87 the mean reversion composite shows almost no skew while the returns of the back tested trades before '87 are negatively skewed. However, because of the market offering more opportunities for mean reversion after '87 the back test shows clearly more trades, while having less return volatility. The two periods show a totally different market environment for mean reversion approaches.

So what changed in 1987, leading to an overall great market environment for mean reversion trades? In the forum -I mentioned above- members were discussing about Alan Greenspan taking the Fed office in early 1987. Mr. Greenspan had for sure a huge impact on the equities markets and may be responsible for the long term bull market between 1987 and 2002. But in my opinion this is to simple. In addition the forum members were talking about the existence of a Plunge Protection Team, buying huge equity in heavily falling markets (and selling them later in rising, I guess) leading to more reversion than before. It would be an almost perfect explanation of this phenomenon. However this is a conspiracy theory....

When I think about what changed in the crash 1987, the black scholes option pricing formula comes to my mind. Before 1987 options were priced with a flat implied volatility by mistake. This changed afterwards. And this might have had huge impact on the behaviour of the hedging of option market makers in the underlying stock markets. But I have no clue how this could work out exactly....

So would do you think? Has anyone a proper explanation for this phenomenon?

So I learned that trading mean reversion style systems shows some nice and stable results, but obviously there is evidence to be very careful in monitoring the market changes that might be coming.





Disclaimer

The information on this site is provided for statistical and informational purposes only. Nothing herein should be interpreted or regarded as personalized investment advice or to state or imply that past results are an indication of future performance. The author of this website is not a licensed financial advisor and will not accept liability for any loss or damage, including without limitation to, any loss of profit, which may arise directly or indirectly from use of or reliance on the content of this website(s).  


Under no circumstances does this information represent an advice or recommendation to buy, sell or hold any security.


Tuesday, December 13, 2011

EOM Momentum Stocks Strategy with R

Currently I am learning how to use R for my research. I have found a lot of great sites and blogs giving me a lot of insight into the language as well as useful resources like toolboxes and packages for R.

As I was investigating the turn/end of month (EOM) effekt in some former posts I will now use the R-code and great toolbox from Systematic Investor to show how a momentum stocks strategy may be combined with an EOM strategy. The original code was used to test this effect with sector ETFs. 
Thus I simply changed the code in order to test my idea to use high momentum stocks (see code) for a 2 days holding period from closing of the last day of the month. In addition to the momentum selection criteria, only stocks are chosen if the closing was above the 89 day moving average. This idea has been taken from the sector strategy of the Quanting Dutchman blog.

As the total return stocks data of the current NASDAQ 100 components from Yahoo is used, the results show a huge systematic survivourship bias. Just look at the green equal weight portfolio results. But the possible edge of the strategy can be observed by the comparison of the EOM equal weight (red line) and the EOM Top 3 momentum ranked stocks (black line).    


The results are not very promising as there is somehow a positive edge for the momentum selection (eom.top.rank1 vs eom.equal.weight) but not for the EOM strategy (eom.equal.weight vs. equal weight).
So I decided to apply the WMA filter in a different way. Now trades will only be made when the index is above the 89 period WMA. Something I use in a quite similar way for filtering my seasonal trading.





The results improve dramatically. On the one hand performance is much better and even more interesting the max draw down is only -11% vs -32,6% before.
The R-code using the Systematic Investor Toolbox:  

###############################################################################
# maQuant Rotational Trading EOM : 
# based on work of
# http://www.etfscreen.com/sectorstrategy.php (Strategy)
# Quanting Dutchman: http://quantingdutchman.wordpress.com/2010/06/30/strategy-2-monthly-end-of-the-month-meom/ (Strategy)
# Systematic Investor: http://systematicinvestor.wordpress.com/2011/12/09/simple-and-profitable/ (R-code and Toolbox SIT!)
###############################################################################
# Load Systematic Investor Toolbox (SIT)
 setInternet2(TRUE)
 con = gzcon(url('https://github.com/systematicinvestor/SIT/raw/master/sit.gz', 'rb'))
     source(con)
 close(con)
 
 #*****************************************************************
 # Load components & historical data
 #****************************************************************** 
 load.packages('quantmod')
 
 source="yahoo"
 index="^NDX"
 start='2000-01-01'
 
 # Components from NASDAQ Website
 url = paste('http://www.nasdaq.com/markets/indices/nasdaq-100.aspx',sep="")
 txt = join(readLines(url)) 
 
 # extract tables from this pages
 temp = extract.table.from.webpage(txt, 'Symbol', hasHeader = T)
 temp[,2]
 
 # Symbols
 symbols = c(temp[,2])[2:101]
 
 data = new.env() # Stock Data
 data2 = new.env() # Index
 getSymbols(c(index), src=source, from=start, env = data2, auto.assign=T, warnings=FALSE)
 getSymbols(symbols, src=source, from=start,  env = data, auto.assign=T, warnings=FALSE) 
        for(i in ls(data)) data[[i]] = adjustOHLC(data[[i]], use.Adjusted=T)
 bt.prep(data, align='keep.all', dates='2000::2011')
 bt.prep(data2, align='keep.all', dates='2000::2011')
 
 #*****************************************************************
 # Begin code strategies
 #****************************************************************** 
 prices = data$prices   
 prices2 = data2$prices 
 
 n = ncol(prices)
 nperiods = nrow(prices)
 
 #*****************************************************************
 # FOR COMPARISON: 
 #*****************************************************************
 
 # Equal Weight for Comparison !Survivorship Bias!
 data$weight[] = ntop(prices, n)
 equal.weight = bt.run(data) 
 
 # find month ends, entry and exit dates
 holding.period=2 
 month.ends = endpoints(prices, 'months')
  month.ends = month.ends[month.ends > 0]  
 month.ends2 = iif(month.ends + holding.period > nperiods, nperiods, month.ends + holding.period)
 
 # EOM INDEX Strategy
 data2$weight[] = NA
  data2$weight[month.ends,] =  ntop(prices2, 1)[month.ends,]
  data2$weight[month.ends2,] = 0
  capital = 100000
  data2$weight[] = (capital / prices2) * data2$weight
 eom.index = bt.run(data2, type='share')
 
 # EOM Equal Weight Strategy 
 data$weight[] = NA
  data$weight[month.ends,] = ntop(prices, n)[month.ends,] 
  data$weight[month.ends2,] = 0
 
  capital = 100000
  data$weight[] = (capital / prices) * data$weight
 eom.equal.weight = bt.run(data, type='share')
 
 #*****************************************************************
 # MOMENTUM EOM STRATEGY: 
 #*****************************************************************
 
 # BuyRule = C > WMA(C, WMA.period)
 WMA.period=89 # Apply x day average for Index
 buy.rule = prices2 > bt.apply.matrix(prices2, function(x) { WMA(x, WMA.period) } )  
  buy.rule = ifna(buy.rule, F)
 buy.rule2=prices
  buy.rule2[,1:n]=buy.rule
 
 lag.period=20 # Apply x day momentum for Stocks
 ret2 = ifna(prices / mlag(prices, lag.period), 0)
 
 # Rank1 = MA( C/Ref(C,-lag.period), 5 ) * MA( C/Ref(C,-lag.period), 40 ) / Simply taken from original Systematic Investor Post
 position.score = bt.apply.matrix(ret2, SMA, 5) * bt.apply.matrix(ret2, SMA, 40) 
  position.score[!buy.rule2] = NA
 
 pos.number=3 # Number of Stocks choosen 
 # Strategy EOM - top X    
 data$weight[] = NA;
  data$weight[month.ends,] = ntop(position.score[month.ends,], pos.number)  
  data$weight[month.ends2,] = 0  
 
  capital = 100000
  data$weight[] = (capital / prices) * data$weight
 eom.top.rank1 = bt.run(data, type='share', trade.summary=T)
 
 #*****************************************************************
 # Create Report
 #****************************************************************** 
 
 report.name=paste('EOM2', start, index, 'WMA', WMA.period, 'lag',lag.period, 'posnum',pos.number, 'hold',holding.period, sep=" ")
 
 # put all reports into one pdf file
 pdf(file = paste(report.name,'.pdf',sep=""), width=8.5, height=11)
  plotbt.custom.report(eom.top.rank1, eom.equal.weight, equal.weight, eom.index, trade.summary=T)
 dev.off() 
 
 png(filename =  paste(report.name,' 1.png',sep=""), width = 600, height = 500, units = 'px', pointsize = 12, bg = 'white')          
  plotbt.custom.report.part1(eom.top.rank1, eom.equal.weight, equal.weight, eom.index,trade.summary=T)
 dev.off() 
 
 png(filename = paste(report.name,' 2.png',sep=""), width = 1200, height = 800, units = 'px', pointsize = 12, bg = 'white') 
  plotbt.custom.report.part2(eom.top.rank1, eom.equal.weight, equal.weight, eom.index,trade.summary=T)
 dev.off() 
 
 png(filename = paste(report.name,' 3.png',sep=""), width = 1200, height = 2000, units = 'px', pointsize = 12, bg = 'white') 
  plotbt.custom.report.part3(eom.top.rank1, eom.equal.weight, equal.weight, eom.index,trade.summary=T)
 dev.off()

I am sure that there is a lot of room for further improvement. Some of the selected stocks might be too heavily overbought. The holding period of the first two trading days of the month seems to be optimal for the EOM strategy but some systematic reaction to the performance of the single trades (stops, targets, holding period) might be useful in order to improve the overall results. Please keep in mind that the results are hypothetical not reflecting any costs of trading. 


Disclaimer

The information on this site is provided for statistical and informational purposes only. Nothing herein should be interpreted or regarded as personalized investment advice or to state or imply that past results are an indication of future performance. The author of this website is not a licensed financial advisor and will not accept liability for any loss or damage, including without limitation to, any loss of profit, which may arise directly or indirectly from use of or reliance on the content of this website(s).  

Under no circumstances does this information represent an advice or recommendation to buy, sell or hold any security.


Saturday, December 10, 2011

Switching to english and what the heck I do for a living

Almost all blogs I follow (see blogroll) and most of the news I read are in english. Last week I spoke with Frank from Engineering Returns and found out that he is a German, too. So I finally decided to switch to the english in my posts. It is the language of the quant traders community.  I hope that I won't make too many mistakes.

In the near future I plan some posts about my current research regarding rotational stock and ETF-trading (Yes, Delta 1 products, ask UBS...) . I will use R as I currently learn that script language and I will use very usefull stuff and ideas from other blogs, especially the oustanding SIT (toolbox for backtests and charting in R) from Systematic Investor. I will focus more on the European ans Asian markets as I have a home bias as well. However because of a lag of accurate long term total return stock and ETF quotes I will also use US data.

My expierence and my current quantitative systems in live trading are more tilted to short term Futures. When someone asks me what the heck I am doing for a living I automatically remember this video. I like it, because it exactly describes my mixed feelings about my 'investments'.



 

Monday, November 14, 2011

Saisonalität: Fosback Teil VI - Last but not least: Oil

Nachdem ich in Teil V zeigen konnte, dass auch Anleihen durchaus positive Anomalien am Monatsende aufweisen, will ich zum Abschluss noch Commodites untersuchen. Ich habe hierfür Öl (Nymex Crude Oil Futures/ICE Brent Crude Oil Futures) gewählt.
In meinen Überlegungen zu den Märkten und dem Fosback-Modell kamen mir Commodites in den Sinn, weil Sie in den letzten Jahren auch bei klassischen Investoren als Long-only Investment in die Portfolien aufgenommen wurden. Stichwort: Alternative Investments und deren positiven Effekte auf die Stabilität sowie die risikoadjustierte Performance eines traditionellen Portfolios.
Die Erwartung ist also, dass Öl in den letzten Jahren einen Effekt am Monatsende aufzeigt und dass dieser früher nicht so ausgeprägt war, als der Markt noch stärker von Supply/Demand bestimmt war. Die Endlos-Zeitreihe im Crude Öl Future beginnt März 1983. Der durchschnittliche Handelstag ist diesem Zeitraum war +0,008505 Punkte. Die Ergebnisse der Tabelle sind darum bereinigt und zeigen die Überrendite an. 
Anbei die Ergebnisse +- 5 Tage um den Ultimo nach Monaten getrennt:

Crude Oil Futures Mar '83 - Nov '11










Insgesamt zeigten die Tage rund um den Ultimo keinen positiven Effekt (negative Überrendite: -0,001 Punkte). Und bezüglich der Verteilung auf die Monate sind die Ergebnisse nicht so klar zyklisch wie bei Aktien. Der April und der November sind unterdurchschnittlich, während der Februar ein 'guter' Monat ist. Spannend ist aber der Blick auf die Verteilung der Ergebnisse vor und nach Ultimo. Die letzten 4 Handelstage eines Monats sind klar über Durchschnitt, der erste Tag des Monats ist neutral, während danach eine Periode 4 schlechter Tage folgte.

Der "gute" Zeitraum sieht im Zeitverlauf absolut betrachtet wie folgt aus:

Crude Oil Futures Mar '83 - Nov '11. Kauf 4 Tage vor, Verkauf am Ultimo
Bis 2005 ist mit dem einfachen Modell auch in diesem positiven Zeitraum vor Ultimo kein Gewinn erzielbar gewesen. Bemerkenswert ist jedoch was sich mit Beginn der Blase im Öl ab 2006 getan hat. Während es keine Überraschung ist, dass im extremen Bullmarkt auch ein Longinvestment am Monatsende Profit abwirft, so hat sich der positive Effekt bis heute durch die massive Korrektur gerettet. Dies könnte tatsächlich damit erklärbar sein, dass andere Player in den Markt gekommen sind, die Ihr Geld mehrheitlich zu bestimmten Terminen allokieren. Dies wird vielleicht auch von anderen Marktteilnehmern antizipiert, was den frühen Effekt vor Ultimo erklären könnte?

Lohnt sich der Blick auf den Zeitraum ab 2005 bis heute. Dabei wiederum die Ergebnisse der Tabelle um die durchschnittliche Tagesveränderung bereinigt (-0,00903):

Crude Oil Futures Jan' 05 - Nov '11
Der Performanceunterschied vor und nach Ultimo ist noch deutlicher als im Gesamtzeitraum. Insgesamt überwiegt der positive Effekt, was den Durchschnitt über alle Tage rund um den Ultimo absolut und relativ positiv werden lässt. Die Ergebnisse beim Nordseeöl (Brent Crude) fallen ähnlich aus.

Im Zeitverlauf  (Kauf  4 Handelstage vor, Verkauf am Ultimo):

Crude Oil Futures Jan '05- Nov '11. Kauf 4 Tage vor, Verkauf am Ultimo


Natürlich ist das eine Optimierung sich jeweils einen Zeitraum (ab 2005 und Kauf 4 Tage vor Ultimo) aus der Gesamtheit der Ergebnisse auszuwählen.
Falls allerdings jemand an Energiemärkten handelt, sollte er meiner Ansicht nach doch auf derart ausgeprägte Effekte achten. Ob meine Erklärungsversuche nun ausreichend sind, wage ich nicht zu sagen. Vielleicht hat jemand eine fundierte Erklärung parat?   

 

Es handelt sich bei diesem Blogeintrag um eine reine historische Betrachtung. 
Dies ist keine Empfehlung für etwaige Investitionsentscheidungen !