SEBASTIEN LLEO and WILLIAM T. ZIEMBA
July 26, 2015
In a 2001 interview, Warren Buffett suggested that the ratio of the market value of all publicly traded stocks to the Gross National Product could identify potential overvaluations and underval- uations in the US equity market. In this paper, we investigate whether this ratio is a statistically significant predictor of equity market downturns.
Link to the original paper: http://papers.ssrn.com/sol3/papers.cfm?abstract_id=2630068
Blog post on Alpha Architect: http://blog.alphaarchitect.com/2015/08/03/daily-academic-alpha-warren-buffett-market-predictions/
import pandas as pd
import numpy as np
import scipy as sp
from math import sqrt
import matplotlib.pyplot as pyplot
datasource = local_csv('MarketCap_GDP.csv', date_column='Month').sort_index(ascending=True)
mkt_gnp = datasource['Wilshire 5000']/datasource['GNP']
# Horizont in months, 60 months = 5 years
mkt_gnp_h=4
# Moving Average
mkt_gnp_mean=pd.rolling_mean(mkt_gnp, mkt_gnp_h)
# Moving Unbiased Standard Deviation (normalized by N-1 by default)
mkt_gnp_std=pd.rolling_std(mkt_gnp, mkt_gnp_h)
# Interval of Confidence 95%
mkt_gnp_threshold = mkt_gnp_mean + 1.96 * mkt_gnp_std / sqrt(mkt_gnp_h)
data = pd.concat([mkt_gnp, mkt_gnp_mean, mkt_gnp_std, mkt_gnp_threshold], axis=1)
data.columns = ['MV t GNP', 'Mean', 'Std', 'Interval of Confidence 95%']
data
plotdata = pd.concat([mkt_gnp, mkt_gnp_threshold], axis=1)
plotdata.columns=['MV to GNP','Interval of Confidence 95%']
plotdata
plot=plotdata.plot()
# S&P 500 Crashes between October 1, 1970 and March 31, 2015
plot.axvspan('1971-04-28', '1971-11-23', color='gray', alpha=0.5, lw=0)
plot.axvspan('1973-01-11', '1974-10-03', color='gray', alpha=0.5, lw=0)
plot.axvspan('1975-07-15', '1975-09-16', color='gray', alpha=0.5, lw=0)
plot.axvspan('1976-09-21', '1978-03-06', color='gray', alpha=0.5, lw=0)
plot.axvspan('1978-09-12', '1978-11-14', color='gray', alpha=0.5, lw=0)
plot.axvspan('1979-10-05', '1979-11-07', color='gray', alpha=0.5, lw=0)
plot.axvspan('1980-02-13', '1980-03-27', color='gray', alpha=0.5, lw=0)
plot.axvspan('1980-11-28', '1981-09-25', color='gray', alpha=0.5, lw=0)
plot.axvspan('1983-10-10', '1984-07-24', color='gray', alpha=0.5, lw=0)
plot.axvspan('1987-08-25', '1987-12-04', color='gray', alpha=0.5, lw=0)
plot.axvspan('1989-10-09', '1990-01-30', color='gray', alpha=0.5, lw=0)
plot.axvspan('1990-07-16', '1990-10-11', color='gray', alpha=0.5, lw=0)
plot.axvspan('1997-10-07', '1997-10-27', color='gray', alpha=0.5, lw=0)
plot.axvspan('1998-07-17', '1998-08-31', color='gray', alpha=0.5, lw=0)
plot.axvspan('1999-07-16', '1999-10-15', color='gray', alpha=0.5, lw=0)
plot.axvspan('2000-03-24', '2001-04-04', color='gray', alpha=0.5, lw=0)
plot.axvspan('2007-10-09', '2009-03-09', color='gray', alpha=0.5, lw=0)
plot.axvspan('2010-04-23', '2010-07-02', color='gray', alpha=0.5, lw=0)
plot.axvspan('2011-04-29', '2011-10-03', color='gray', alpha=0.5, lw=0)
# 80% level
plot.axhline(y=0.8, color='r')
# 120% level
plot.axhline(y=1.2, color='g')
plot.plot(mkt_gnp_mean)
# Draw a marker at the signal points
# The signal indicator S t takes the value 1 if the measure crosses the threshold on quarter t ...
s0 = mkt_gnp > mkt_gnp_threshold
# ... but not on quarter t − 1, and 0 otherwise.
s1 = mkt_gnp.shift(1) < mkt_gnp_threshold.shift(1)
signals = s0 & s1
signals_index = mkt_gnp[signals].index
pyplot.plot(signals_index, mkt_gnp[signals_index], 'D', markersize=5, color='b')
print "Number of signals: %d" % len(mkt_gnp[signals_index])