def nyse_dates_advanced(self): ''' Tests the dates between two dates with the lookBack and lookForward parameters ''' # Test: with lookbackDays without lookforwardDays start = datetime(2009, 1, 1) end = datetime(2011, 1, 1) dates = DateUtils.nyse_dates(start=start, end=end, lookbackDays=10, lookforwardDays=0) self.assertEquals(dates[0], datetime(2008, 12, 17)) self.assertEquals(dates[-1], datetime(2010, 12, 31)) # Test: without lookbackDays with lookforwardDays start = datetime(2009, 1, 1) end = datetime(2011, 1, 1) dates = DateUtils.nyse_dates(start=start, end=end, lookbackDays=0, lookforwardDays=10) self.assertEquals(dates[0], datetime(2009, 1, 2)) self.assertEquals(dates[-1], datetime(2011, 1, 14)) # Test: with lookbackDays with lookforwardDays start = datetime(2009, 1, 1) end = datetime(2011, 1, 1) dates = DateUtils.nyse_dates(start=start, end=end, lookbackDays=10, lookforwardDays=10) self.assertEquals(dates[0], datetime(2008, 12, 17)) self.assertEquals(dates[-1], datetime(2011, 1, 14))
def search(self, oneEventPerEquity=True, useCache=True, save=True): self.oneEventPerEquity = oneEventPerEquity # 1. Load the data if requested and available self.matrix = self.data_access.load(self.generate_filename(), '.evt_matrix') if useCache and self.matrix is not None: pass else: # 2. Data was not loaded # 2.1 Get the dates, and Download/Import the data nyse_dates = DateUtils.nyse_dates(start=self.start_date, end=self.end_date) data = self.data_access.get_data(self.symbols, nyse_dates[0], nyse_dates[-1], self.field) # Special case if len(data.columns) == 1: data.columns = self.symbols # 2.2 Create and fill the matrix of events data = data[self.start_date:self.end_date] self.matrix = pd.DataFrame(index=data.index, columns=self.symbols) for symbol in self.symbols: i = 0 for item in data[symbol][1:]: e = self.condition.function(i, item, data[symbol][1:]) if e: self.matrix[symbol][i + 1] = 1 if oneEventPerEquity == True: break i = i + 1 # 3. Calculate other results and save if requested # Reduce Matrix: Sum each row and columns: if is greater than 0 there is an event self.matrix = self.matrix[self.matrix.fillna(value=0).sum(axis=1) > 0] valid_cols = self.matrix.columns[self.matrix.fillna(value=0).sum( axis=0) > 0].values self.matrix = self.matrix[valid_cols] # 3.2 Create list of events self.list = pd.Series(index=self.matrix.index, name='Equity', dtype=str) for idx, row in self.matrix.iterrows(): equity = row[row == 1].index[0] self.list.ix[idx] = equity # 3.3 Save self.num_events = len(self.list) if save: self.data_access.save(self.matrix, self.generate_filename(), '.evt_matrix')
def search(self, oneEventPerEquity=True, useCache=True, save=True): self.oneEventPerEquity = oneEventPerEquity # 1. Load the data if requested and available self.matrix = self.data_access.load(self.generate_filename(), '.evt_matrix') if useCache and self.matrix is not None: pass else: # 2. Data was not loaded # 2.1 Get the dates, and Download/Import the data nyse_dates = DateUtils.nyse_dates(start=self.start_date, end=self.end_date) data = self.data_access.get_data(self.symbols, nyse_dates[0], nyse_dates[-1], self.field) # Special case if len(data.columns) == 1: data.columns = self.symbols # 2.2 Create and fill the matrix of events data = data[self.start_date:self.end_date] self.matrix = pd.DataFrame(index=data.index, columns=self.symbols) for symbol in self.symbols: i = 0 for item in data[symbol][1:]: e = self.condition.function(i, item, data[symbol][1:]) if e: self.matrix[symbol][i+1] = 1 if oneEventPerEquity == True: break i = i + 1 # 3. Calculate other results and save if requested # Reduce Matrix: Sum each row and columns: if is greater than 0 there is an event self.matrix = self.matrix[self.matrix.fillna(value=0).sum(axis=1) > 0] valid_cols = self.matrix.columns[self.matrix.fillna(value=0).sum(axis=0) > 0].values self.matrix = self.matrix[valid_cols] # 3.2 Create list of events self.list = pd.Series(index=self.matrix.index, name='Equity') for idx, row in self.matrix.iterrows(): equity = row[row == 1].index[0] self.list.loc[idx] = equity # 3.3 Save self.num_events = len(self.list) if save: self.data_access.save(self.matrix, self.generate_filename(), '.evt_matrix')
from datetime import datetime from finance.utils import DateUtils all_dates = DateUtils.nyse_dates() print(all_dates) print(DateUtils.nyse_dates(start=datetime(2008,1,1))) index = DateUtils.search_closer_date(datetime(2009,1,1), all_dates) print(index, all_dates[index])
def run(self): """ Assess the events |-----100-----|-------20-------|-|--------20--------| estimation lookback event lookforward Prerequisites ------------- self.matrix self.market = 'SPY' self.lookback_days = 20 self.lookforward_days = 20 self.estimation_period = 200 self.field = 'Adj Close' """ # 0. Get the dates and Download/Import the data symbols = list(set(self.list)) start_date = self.list.index[0] end_date = self.list.index[-1] nyse_dates = DateUtils.nyse_dates( start=start_date, end=end_date, lookbackDays=self.lookback_days + self.estimation_period + 1, lookforwardDays=self.lookforward_days, ) data = self.data_access.get_data(symbols, nyse_dates[0], nyse_dates[-1], self.field) market = self.data_access.get_data(self.market, nyse_dates[0], nyse_dates[-1], self.field) if len(data.columns) == 1: data.columns = symbols if len(data) > len(market): market = market.reindex(data.index) market.columns = [self.field] data = data.fillna(method="ffill").fillna(method="bfill") market = market.fillna(method="ffill").fillna(method="bfill") # 1. Create DataFrames with the data of each event windows_indexes = range(-self.lookback_days, self.lookforward_days + 1) estimation_indexes = range(-self.estimation_period - self.lookback_days, -self.lookback_days) self.equities_window = pd.DataFrame(index=windows_indexes) self.equities_estimation = pd.DataFrame(index=estimation_indexes) self.market_window = pd.DataFrame(index=windows_indexes) self.market_estimation = pd.DataFrame(index=estimation_indexes) dr_data = Calculator.returns(data) dr_market = Calculator.returns(market) self.dr_equities_window = pd.DataFrame(index=windows_indexes) self.dr_equities_estimation = pd.DataFrame(index=estimation_indexes) self.dr_market_window = pd.DataFrame(index=windows_indexes) self.dr_market_estimation = pd.DataFrame(index=estimation_indexes) # 2. Iterate over the list of events and fill the DataFrames for i in range(len(self.list)): symbol = self.list[i] evt_date = self.list.index[i].to_pydatetime() col_name = symbol + " " + evt_date.strftime("%Y-%m-%d") evt_idx = DateUtils.search_closer_date(evt_date, data[symbol].index, exact=True) # 1.1 Data on the estimation period: self.equities_estimation start_idx = evt_idx - self.lookback_days - self.estimation_period # estimation start idx on self.data end_idx = evt_idx - self.lookback_days # estimation end idx on self.data new_equities_estimation = data[symbol][start_idx:end_idx] new_equities_estimation.index = self.equities_estimation.index self.equities_estimation[col_name] = new_equities_estimation # Daily return of the equities on the estimation period new_dr_equities_estimation = dr_data[symbol][start_idx:end_idx] new_dr_equities_estimation.index = self.dr_equities_estimation.index self.dr_equities_estimation[col_name] = new_dr_equities_estimation # 1.4 Market on the estimation period: self.market_estimation new_market_estimation = market[self.field][start_idx:end_idx] new_market_estimation.index = self.market_estimation.index self.market_estimation[col_name] = new_market_estimation # Daily return of the market on the estimation period new_dr_market_estimation = dr_market[start_idx:end_idx] new_dr_market_estimation.index = self.dr_market_estimation.index self.dr_market_estimation[col_name] = new_dr_market_estimation # 1.3 Equities on the event window: self.equities_window start_idx = evt_idx - self.lookback_days # window start idx on self.data end_idx = evt_idx + self.lookforward_days + 1 # window end idx on self.data new_equities_window = data[symbol][start_idx:end_idx] new_equities_window.index = self.equities_window.index self.equities_window[col_name] = new_equities_window # Daily return of the equities on the event window new_dr_equities_window = dr_data[symbol][start_idx:end_idx] new_dr_equities_window.index = self.dr_equities_window.index self.dr_equities_window[col_name] = new_dr_equities_window # 1.4 Market on the event window: self.market_window new_market_window = market[self.field][start_idx:end_idx] new_market_window.index = self.market_window.index self.market_window[col_name] = new_market_window # Daily return of the market on the event window new_dr_market_window = dr_market[start_idx:end_idx] new_dr_market_window.index = self.dr_market_window.index self.dr_market_window[col_name] = new_dr_market_window # 3. Calculate the linear regression -> expected return self.reg_estimation = pd.DataFrame( index=self.dr_market_estimation.columns, columns=["Intercept", "Slope", "Std Error"] ) self.er = pd.DataFrame(index=self.dr_market_window.index, columns=self.dr_market_window.columns) # For each column (event) on the estimation period for col in self.dr_market_estimation.columns: # 3.1 Calculate the regression x = self.dr_market_estimation[col] y = self.dr_equities_estimation[col] slope, intercept, r_value, p_value, slope_std_error = stats.linregress(x, y) self.reg_estimation["Slope"][col] = slope self.reg_estimation["Intercept"][col] = intercept self.reg_estimation["Std Error"][col] = slope_std_error # 3.2 Calculate the expected return of each date using the regression self.er[col] = intercept + self.dr_market_window[col] * slope # 4. Final results self.er.columns.name = "Expected return" self.mean_er = self.er.mean(axis=1) self.mean_er.name = "Mean ER" self.std_er = self.er.std(axis=1) self.std_er.name = "Std ER" self.ar = self.dr_equities_window - self.er self.ar.columns.name = "Abnormal return" self.mean_ar = self.ar.mean(axis=1) self.mean_ar.name = "Mean AR" self.std_ar = self.ar.std(axis=1) self.std_ar.name = "Std AR" self.car = self.ar.apply(np.cumsum) self.car.columns.name = "Cum Abnormal Return" self.mean_car = self.car.mean(axis=1) self.mean_car.name = "Mean CAR" self.std_car = self.car.std(axis=1) self.mean_car.name = "Mean CAR"
def run(self): ''' Assess the events |-----100-----|-------20-------|-|--------20--------| estimation lookback event lookforward Prerequisites ------------- self.matrix self.market = 'SPY' self.lookback_days = 20 self.lookforward_days = 20 self.estimation_period = 200 self.field = 'Adj Close' ''' # 0. Get the dates and Download/Import the data symbols = list(set(self.list)) start_date = self.list.index[0] end_date = self.list.index[-1] nyse_dates = DateUtils.nyse_dates( start=start_date, end=end_date, lookbackDays=self.lookback_days + self.estimation_period + 1, lookforwardDays=self.lookforward_days) data = self.data_access.get_data(symbols, nyse_dates[0], nyse_dates[-1], self.field) market = self.data_access.get_data(self.market, nyse_dates[0], nyse_dates[-1], self.field) if len(data.columns) == 1: data.columns = symbols if len(data) > len(market): market = market.reindex(data.index) market.columns = [self.field] data = data.fillna(method='ffill').fillna(method='bfill') market = market.fillna(method='ffill').fillna(method='bfill') # 1. Create DataFrames with the data of each event windows_indexes = range(-self.lookback_days, self.lookforward_days + 1) estimation_indexes = range( -self.estimation_period - self.lookback_days, -self.lookback_days) self.equities_window = pd.DataFrame(index=windows_indexes) self.equities_estimation = pd.DataFrame(index=estimation_indexes) self.market_window = pd.DataFrame(index=windows_indexes) self.market_estimation = pd.DataFrame(index=estimation_indexes) dr_data = Calculator.returns(data) dr_market = Calculator.returns(market) self.dr_equities_window = pd.DataFrame(index=windows_indexes) self.dr_equities_estimation = pd.DataFrame(index=estimation_indexes) self.dr_market_window = pd.DataFrame(index=windows_indexes) self.dr_market_estimation = pd.DataFrame(index=estimation_indexes) # 2. Iterate over the list of events and fill the DataFrames for i in range(len(self.list)): symbol = self.list[i] evt_date = self.list.index[i].to_pydatetime() col_name = symbol + ' ' + evt_date.strftime('%Y-%m-%d') evt_idx = DateUtils.search_closer_date(evt_date, data[symbol].index, exact=True) # 1.1 Data on the estimation period: self.equities_estimation start_idx = evt_idx - self.lookback_days - self.estimation_period # estimation start idx on self.data end_idx = evt_idx - self.lookback_days # estimation end idx on self.data new_equities_estimation = data[symbol][start_idx:end_idx] new_equities_estimation.index = self.equities_estimation.index self.equities_estimation[col_name] = new_equities_estimation # Daily return of the equities on the estimation period new_dr_equities_estimation = dr_data[symbol][start_idx:end_idx] new_dr_equities_estimation.index = self.dr_equities_estimation.index self.dr_equities_estimation[col_name] = new_dr_equities_estimation # 1.4 Market on the estimation period: self.market_estimation new_market_estimation = market[self.field][start_idx:end_idx] new_market_estimation.index = self.market_estimation.index self.market_estimation[col_name] = new_market_estimation # Daily return of the market on the estimation period new_dr_market_estimation = dr_market[start_idx:end_idx] new_dr_market_estimation.index = self.dr_market_estimation.index self.dr_market_estimation[col_name] = new_dr_market_estimation # 1.3 Equities on the event window: self.equities_window start_idx = evt_idx - self.lookback_days # window start idx on self.data end_idx = evt_idx + self.lookforward_days + 1 # window end idx on self.data new_equities_window = data[symbol][start_idx:end_idx] new_equities_window.index = self.equities_window.index self.equities_window[col_name] = new_equities_window # Daily return of the equities on the event window new_dr_equities_window = dr_data[symbol][start_idx:end_idx] new_dr_equities_window.index = self.dr_equities_window.index self.dr_equities_window[col_name] = new_dr_equities_window # 1.4 Market on the event window: self.market_window new_market_window = market[self.field][start_idx:end_idx] new_market_window.index = self.market_window.index self.market_window[col_name] = new_market_window # Daily return of the market on the event window new_dr_market_window = dr_market[start_idx:end_idx] new_dr_market_window.index = self.dr_market_window.index self.dr_market_window[col_name] = new_dr_market_window # 3. Calculate the linear regression -> expected return self.reg_estimation = pd.DataFrame( index=self.dr_market_estimation.columns, columns=['Intercept', 'Slope', 'Std Error']) self.er = pd.DataFrame(index=self.dr_market_window.index, columns=self.dr_market_window.columns) # For each column (event) on the estimation period for col in self.dr_market_estimation.columns: # 3.1 Calculate the regression x = self.dr_market_estimation[col] y = self.dr_equities_estimation[col] slope, intercept, r_value, p_value, slope_std_error = stats.linregress( x, y) self.reg_estimation['Slope'][col] = slope self.reg_estimation['Intercept'][col] = intercept self.reg_estimation['Std Error'][col] = slope_std_error # 3.2 Calculate the expected return of each date using the regression self.er[col] = intercept + self.dr_market_window[col] * slope # 4. Final results self.er.columns.name = 'Expected return' self.mean_er = self.er.mean(axis=1) self.mean_er.name = 'Mean ER' self.std_er = self.er.std(axis=1) self.std_er.name = 'Std ER' self.ar = self.dr_equities_window - self.er self.ar.columns.name = 'Abnormal return' self.mean_ar = self.ar.mean(axis=1) self.mean_ar.name = 'Mean AR' self.std_ar = self.ar.std(axis=1) self.std_ar.name = 'Std AR' self.car = self.ar.apply(np.cumsum) self.car.columns.name = 'Cum Abnormal Return' self.mean_car = self.car.mean(axis=1) self.mean_car.name = 'Mean CAR' self.std_car = self.car.std(axis=1) self.mean_car.name = 'Mean CAR'
def nyse_dates_basic(self): ''' Tests the dates without the lookBack and lookForward parameters ''' # We assume this works: because sometime today is not and open day today = datetime(datetime.today().year, datetime.today().month, datetime.today().day) dates = DateUtils.nyse_dates() today = DateUtils.search_closer_date(today, dates) today = dates[today] # End of assumssion # Test: Returns a list dates = DateUtils.nyse_dates() self.assertEquals(type(dates), list) # Test: Returns a pd.Series if requested dates = DateUtils.nyse_dates(series=True) self.assertEquals(type(dates), pd.TimeSeries) # Test: Default startdate is 2007-1-1 dates = DateUtils.nyse_dates() ans = dates[0] self.assertEquals(ans, datetime(2007,1,3)) # Test: Default enddate is today ans = dates[-1] self.assertEquals(ans, today) # Test: Values: start date after 2007-1-1 start = datetime(2008, 1, 1) # Test: returns list dates = DateUtils.nyse_dates(start=start) self.assertEquals(type(dates), list) self.assertEquals(dates[0], datetime(2008, 1, 2)) self.assertEquals(dates[-1], today) # Test: returns pd.Series dates = DateUtils.nyse_dates(start=start, series=True) self.assertEquals(type(dates), pd.TimeSeries) self.assertEquals(dates[0], datetime(2008, 1, 2)) self.assertEquals(dates[-1], today) # Test: Values: start date before 2007-1-1 start = datetime(1995, 1, 1) # Test: with list dates = DateUtils.nyse_dates(start=start) self.assertEquals(type(dates), list) self.assertEquals(dates[0], datetime(1995, 1, 3)) self.assertEquals(dates[-1], today) # Test: with pd.Series dates = DateUtils.nyse_dates(start=start, series=True) self.assertEquals(type(dates), pd.TimeSeries) self.assertEquals(dates[0], datetime(1995, 1, 3)) self.assertEquals(dates[-1], today) # Test: end date after 2007-1-1 end = datetime(2009, 6, 6) dates = DateUtils.nyse_dates(end=end) self.assertEquals(type(dates), list) self.assertEquals(dates[0], datetime(2007, 1, 3)) self.assertEquals(dates[-1], datetime(2009, 6, 5)) # Test: end date before 2007-1-1 end = datetime(2005, 6, 6) dates = DateUtils.nyse_dates(end=end) self.assertEquals(type(dates), list) self.assertEquals(dates[0], datetime(1962, 7, 5)) self.assertEquals(dates[-1], datetime(2005, 6, 6)) # Test: Values and lenght between 2 dates - No. 1 start = datetime(2000, 1, 1) end = datetime(2002, 1, 1) # Test: with list dates = DateUtils.nyse_dates(start=start, end=end) self.assertEquals(type(dates), list) self.assertEquals(dates[0], datetime(2000, 1, 3)) self.assertEquals(dates[-1], datetime(2001, 12, 31)) self.assertEquals(len(dates), 500) # Test: with pd.Series dates = DateUtils.nyse_dates(start=start, end=end, series=True) self.assertEquals(type(dates), pd.TimeSeries) self.assertEquals(dates[0], datetime(2000, 1, 3)) self.assertEquals(dates[-1], datetime(2001, 12, 31)) self.assertEquals(len(dates), 500) # Test: Values and lenght between 2 dates - No. 2 start = datetime(2009, 1, 1) end = datetime(2011, 1, 1) # Test: Lenght: Section - list dates = DateUtils.nyse_dates(start=start, end=end) self.assertEquals(type(dates), list) self.assertEquals(dates[0], datetime(2009, 1, 2)) self.assertEquals(dates[-1], datetime(2010, 12, 31)) self.assertEquals(len(dates), 504) # Test: Lenght: Section - pd.Series dates = DateUtils.nyse_dates(start=start, end=end, series=True) self.assertEquals(type(dates), pd.TimeSeries) self.assertEquals(dates[0], datetime(2009, 1, 2)) self.assertEquals(dates[-1], datetime(2010, 12, 31)) self.assertEquals(len(dates), 504)
from datetime import datetime from finance.utils import DateUtils all_dates = DateUtils.nyse_dates() print(all_dates) print(DateUtils.nyse_dates(start=datetime(2015,1,1))) index = DateUtils.search_closer_date(datetime(2017,1,1), all_dates) print(index, all_dates[index])