Created
November 19, 2012 05:16
-
-
Save ipl31/4109078 to your computer and use it in GitHub Desktop.
Tweaked karl's eventprofiler hacks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# (c) 2011, 2012 Georgia Tech Research Corporation | |
# This source code is released under the New BSD license. Please see | |
# http://wiki.quantsoftware.org/index.php?title=QSTK_License | |
# for license details. | |
# | |
# Created on October <day>,2011 | |
# @author: Vishal Shekhar, Tucker Balch | |
# @contact: [email protected] | |
# @summary: Event Profiler Application | |
# | |
# kv - MODIFIED THIS by commenting lines 134 and 153 (clf and savefig). | |
# Removed coded that had been commented out anyway | |
# Now passing the color used for drawing | |
import numpy as np | |
from pylab import * | |
import qstkutil.qsdateutil as du | |
import qstkutil.tsutil as tsu | |
import datetime as dt | |
import qstkutil.DataAccess as da | |
class EventProfiler(): | |
def __init__(self, | |
eventMatrix, | |
startday, | |
endday, | |
lookback_days = 20, | |
lookforward_days =20, | |
verbose=False): | |
""" Event Profiler class construtor | |
Parameters : evenMatrix | |
: startday | |
: endday | |
: plt - A pylot plt object | |
(optional) : lookback_days ( default = 20) | |
(optional) : lookforward_days( default = 20) | |
eventMatrix is a pandas DataMatrix | |
eventMatrix must have the following structure: | |
|IBM |GOOG|XOM |MSFT| GS | JP | | |
(d1)|nan |nan | 1 |nan |nan | 1 | | |
(d2)|nan | 1 |nan |nan |nan |nan | | |
(d3)| 1 |nan | 1 |nan | 1 |nan | | |
(d4)|nan | 1 |nan | 1 |nan |nan | | |
................................... | |
................................... | |
Also, d1 = start date | |
nan = no information about any event. | |
= status bit(positively confirms the event occurence) | |
""" | |
self.eventMatrix = eventMatrix | |
self.startday = startday | |
self.endday = endday | |
self.symbols = eventMatrix.columns | |
self.lookback_days = lookback_days | |
self.lookforward_days = lookforward_days | |
self.total_days = lookback_days + lookforward_days + 1 | |
self.dataobj = da.DataAccess('Yahoo') | |
self.timeofday = dt.timedelta(hours=16) | |
self.timestamps = du.getNYSEdays(startday,endday,self.timeofday) | |
self.verbose = verbose | |
if verbose: | |
print __name__ + " reading historical data" | |
self.close = self.dataobj.get_data(self.timestamps,\ | |
self.symbols, "close", verbose=self.verbose) | |
self.close = (self.close.fillna()).fillna(method='backfill') | |
def study(self, | |
plt, | |
method="mean", | |
plotMarketNeutral = True, | |
plotErrorBars = False, | |
plotEvents = False, | |
marketSymbol='$SPX', | |
PlotColor='#0000FF'): | |
""" | |
Creates an event study plot | |
the marketSymbol must exist in the data if plotMarketNeutral | |
is True This method plots the average of market neutral | |
cumulative returns, along with error bars The X-axis is the | |
relative time frame from -self.lookback_days to self.lookforward_days | |
Size of error bar on each side of the mean value on the i | |
relative day = abs(mean @ i - standard dev @ i) | |
""" | |
# compute 0 centered daily returns | |
self.dailyret = self.close.copy() | |
tsu.returnize0(self.dailyret.values) | |
# make it market neutral | |
if plotMarketNeutral: | |
# assuming beta = 1 for all stocks --this is unrealistic.but easily fixable. | |
self.mktneutDM = self.dailyret - self.dailyret[marketSymbol] | |
# remove the market column from consideration | |
del(self.mktneutDM[marketSymbol]) | |
del(self.eventMatrix[marketSymbol]) | |
else: | |
self.mktneutDM = self.dailyret | |
# Wipe out events which are on the boundary. | |
self.eventMatrix.values[0:self.lookback_days,:] = NaN | |
self.eventMatrix.values[-self.lookforward_days:,:] = NaN | |
# prepare to build impact matrix | |
rets = self.mktneutDM.values | |
events = self.eventMatrix.values | |
numevents = nansum(events) | |
numcols = events.shape[1] | |
# create a blank impact matrix | |
impact = np.zeros((self.total_days,numevents)) | |
currcol = 0 | |
# step through each column in event matrix | |
for col in range(0,events.shape[1]): | |
# search each column for events | |
for row in range(0,events.shape[0]): | |
# when we find an event | |
if events[row,col]==1.0: | |
# copy the daily returns in to the impact matrix | |
impact[:,currcol] = \ | |
rets[row-self.lookback_days:row+self.lookforward_days+1,col] | |
currcol = currcol+1 | |
# now compute cumulative daily returns | |
impact = cumprod(impact+1,axis=0) | |
impact = impact / impact[0,:] | |
# normalize everything to the time of the event | |
impact = impact / impact[self.lookback_days,:] | |
# prepare data for plot | |
studystat = mean(impact,axis=1) | |
studystd = std(impact,axis=1) | |
studyrange = range(-self.lookback_days,self.lookforward_days+1) | |
# PLOTTING now | |
# plt.clr ##! | |
# draw a horizontal line at Y = 1.0 | |
plt.axhline(y=1.0,xmin=-self.lookback_days,xmax=self.lookforward_days+1,color='#000000') | |
if plotErrorBars==True: # draw errorbars if user wants them | |
plt.errorbar(studyrange[self.lookback_days:],\ | |
studystat[self.lookback_days:],\ | |
yerr=studystd[self.lookback_days:],\ | |
ecolor=PlotColor, ##! | |
alpha=0.1) | |
plt.plot(studyrange,studystat,color=PlotColor,linewidth=3,label='mean') ##! | |
# set the limits of the axes to appropriate ranges | |
plt.ylim(min(min(studystat),0.5),max(max(studystat),1.2)) | |
plt.xlim(min(studyrange)-1,max(studyrange)+1) | |
# draw titles and axes | |
plt.title(('Comparison of dead-cat bounces')) ##! | |
plt.xlabel('Days') | |
plt.ylabel('Cumulative Abnormal Returns') | |
plt.draw() | |
# Return our plot object to the caller | |
return plt |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment