def find_best_index(stock, indices, lookback=252, stock_ceiling_params=DEFAULT_STOCK_CEILING_PARAMS, index_floor_params=DEFAULT_INDEX_FLOOR_PARAMS, best_fit_param=BEST_FIT_PERCENTILE): """For a given stock and group of indices, find the index that has the best fit based on OLS regression""" scrub_params_all = [ get_scrub_params(stock, index, lookback, stock_ceiling_params, index_floor_params, best_fit_param) for index in indices ] betas = [ create_beta_object_from_scrub_params(stock, indices[i], lookback, scrub_params_all[i]) for i in range(len(indices)) ] # OLS Info corrs = [beta.corr for beta in betas] highest_corr = max(corrs) highest_corr_index = corrs.index(highest_corr) best_index = indices[highest_corr_index] return best_index
def run(): stock = 'NBIX' stock2 = 'NBIX' index = 'XBI' beta_lookback = 252 chart_lookback = beta_lookback base = 100 scrub_params = ScrubParams(.125, .01, 90) stock_ceiling_params = Stock_Ceiling_Params(initial_ceiling=.20, SD_multiplier=4.0) index_floor_params = Index_Floor_Params(SD_multiplier=1.0) scrub_params = get_scrub_params(stock, index, stock_ceiling_params=stock_ceiling_params, index_floor_params=index_floor_params) beta = Beta(stock, index, beta_lookback, scrub_params) print(beta.num_days_in_calculation) # print(beta_value.degrees_of_freedom) print(beta.beta_value) print(beta.beta1) # beta_value.describe() beta.show_scrub_trajectory() # beta2 = Beta(stock2, index, beta_lookback, scrub_params).beta_value # beta_value, beta2 = 0.0, 0.0 # Stock Lines to plot stock_line = StockLineSimple(stock, chart_lookback, base) index_line = StockLineSimple(index, chart_lookback, base) stock_line_adj = StockLineBetaAdjusted(stock, chart_lookback, beta.beta_value, index, base) stock_lines = [stock_line.stock_line(color='red'), index_line.stock_line(color='black'), stock_line_adj.stock_line(color='blue'), ] StockChart(stock_lines).run() Beta(stock, index, beta_lookback, ScrubParams(.075, .01, 95)).show_scrub_trajectory() print('End of Module')
def best_beta_value(self): index = 'XBI' beta_lookback = 252 stock_ceiling_params = Stock_Ceiling_Params(initial_ceiling=.20, SD_multiplier=4.0) index_floor_params = Index_Floor_Params(SD_multiplier=1.0) best_fit_param = 95 scrub_params = get_scrub_params( self.stock, index, stock_ceiling_params=stock_ceiling_params, index_floor_params=index_floor_params, best_fit_param=best_fit_param) beta_value = Beta(self.stock, index, beta_lookback, scrub_params).beta_value return beta_value
def calculate_adjusted_beta(stock, index, lookback, stock_ceiling_params, index_floor_params, best_fit_param): """Calculate the adjusted beta_value measurement for the stock and index over a lookback based on the three core adjustments: - Stock Ceiling: Scrub data points where the stock moved more than the specified threshold. - Index Floor: Scrub data points where the index moved less than the specified threshold. - Best Fit Param: Keep only the n-percentile best fit points in the OLS regression""" scrub_params = get_scrub_params(stock, index, lookback=lookback, stock_ceiling_params=stock_ceiling_params, index_floor_params=index_floor_params, best_fit_param=best_fit_param) beta_value = Beta(stock, index, lookback, scrub_params).beta_value return beta_value
def __init__( self, stock: 'str', index: 'str', lookback: 'int' = 252, scrub_params: 'obj' = None, # Optional Parameters as an alternative to entering scrub_params stock_ceiling_params=DEFAULT_STOCK_CEILING_PARAMS, index_floor_params=DEFAULT_INDEX_FLOOR_PARAMS, best_fit_param=BEST_FIT_PERCENTILE): """The Beta object takes as parameters the stock, index, lookback, and scrub_params object. The user can enter scrub_params OR a set of stock_ceiling_params, index_floor_params, and best_fit_param , which map to scrub_params.""" """Calculate the adjusted beta_value measurement for the stock and index over a lookback... based on the three core adjustments: - Stock Ceiling: Scrub data points where the stock moved more than the specified threshold. - Index Floor: Scrub data points where the index moved less than the specified threshold. - Best Fit Param: Keep only the n-percentile best fit points in the OLS regression """ self.stock = stock self.index = index self.lookback = lookback if scrub_params is None: self.scrub_params = get_scrub_params( stock, index, lookback=252, stock_ceiling_params=DEFAULT_STOCK_CEILING_PARAMS, index_floor_params=DEFAULT_INDEX_FLOOR_PARAMS, best_fit_param=BEST_FIT_PERCENTILE) else: self.scrub_params = scrub_params self.price_table = PriceTable.head( self.lookback)[[self.stock, self.index]] self.daily_returns = daily_returns(self.price_table) self.num_data_points = self.daily_returns.shape[0]
def get_betas_over_iterable(stock, index, lookback=252, stock_ceiling_params=DEFAULT_STOCK_CEILING_PARAMS, index_floor_params=DEFAULT_INDEX_FLOOR_PARAMS, best_fit_param=BEST_FIT_PERCENTILE, save_to_file=False): stock_ceiling_params = [stock_ceiling_params] index_floor_params = [index_floor_params] best_fit_param = [best_fit_param] param_combos = list( itertools.product(stock, index, lookback, stock_ceiling_params, index_floor_params, best_fit_param)) counter = range(len(param_combos)) stocks = [i[0] for i in param_combos] indices = [i[1] for i in param_combos] lookbacks = [i[2] for i in param_combos] #scrub_params_all = [get_scrub_params(stock, index, lookback, stock_ceiling_params, index_floor_params, best_fit_param) for params in param_combos] scrub_params_all = [get_scrub_params(*params) for params in param_combos] scrub_param_combos = list(zip(stocks, indices, lookbacks, scrub_params_all)) betas = [ Beta(stocks[i], indices[i], lookbacks[i], scrub_params_all[i]) for i in counter ] # OLS Info beta_values = [beta.beta_value for beta in betas] corrs = [beta.corr for beta in betas] # Scrubbing Info stock_cutoffs = [ scrub_params.stock_cutoff for scrub_params in scrub_params_all ] index_cutoffs = [ scrub_params.index_cutoff for scrub_params in scrub_params_all ] percentile_cutoffs = [ scrub_params.percentile_cutoff for scrub_params in scrub_params_all ] percent_days_in_calc = [beta.percent_days_in_calculation for beta in betas] # Beta to SPY Info index_betas_to_SPY = [get_ETF_beta_to_SPY(index) for index in indices] betas_to_SPY = [index_betas_to_SPY[i] * beta_values[i] for i in counter] # Returns Info stock_returns = [ get_total_return(stocks[i], lookbacks[i]) for i in counter ] index_returns = [ get_total_return(indices[i], lookbacks[i]) for i in counter ] idio_returns = [ (1 + stock_returns[i]) / (1 + index_returns[i] * beta_values[i]) - 1 for i in counter ] # Unadjusted OLS Info unadjusted_betas = [ Beta(stocks[i], indices[i], lookbacks[i], ScrubParams(False, False, False)) for i in counter ] unadjusted_beta_values = [beta.beta_value for beta in unadjusted_betas] unadjusted_corrs = [beta.corr for beta in unadjusted_betas] # Prepare Information for the DataFrame in an Ordered Dictionary table_info_dict = OrderedDict([ #Unadjusted OLS Info ('Unadj. Beta', unadjusted_beta_values), ('Unadj. Corr', unadjusted_corrs), # OLS Info ('Beta', beta_values), ('Corr', corrs), # Beta to SPY Info ('Index_Beta_to_SPY', index_betas_to_SPY), ('Beta_to_SPY', betas_to_SPY), # Returns Info ('Stock_Return', stock_returns), ('Index_Return', index_returns), ('Idio_return', idio_returns), # Scrubbing Info ('Stock_Cutoff', stock_cutoffs), ('Index_Cutoff', index_cutoffs), ('Percentile_Cutoff', percentile_cutoffs), ('Percent_Days', percent_days_in_calc) ]) parameters = [stock, index, lookback] for parameter in parameters: if len(parameter) > 1: iterable = parameter else: pass if iterable == stock: not_iterable = index[0] elif iterable == index: not_iterable = stock[0] elif iterable == lookback: not_iterable = 'Stock: {}, Index {}'.format(stock[0], index[0]) else: raise ValueError # Create DataFrame column_labels = table_info_dict.keys() table_info = list(zip(*table_info_dict.values())) #index_row = pd.Index(indices, name = 'Index') index_row = pd.Index(iterable, name='Index') iterables_columns = [[not_iterable], column_labels] #iterables_columns = [[stock], column_labels] index_column = pd.MultiIndex.from_product(iterables_columns, names=['Stock', 'Beta_Info']) df = pd.DataFrame(table_info, index=index_row, columns=index_column) if save_to_file: to_pickle_and_CSV(df, file_name) return df
def get_betas_multiple_stocks( stocks: 'iterable of stocks', index: 'one index', lookback=252, stock_ceiling_params=DEFAULT_STOCK_CEILING_PARAMS, index_floor_params=DEFAULT_INDEX_FLOOR_PARAMS, best_fit_param=BEST_FIT_PERCENTILE, save_to_file=False): scrub_params_all = [ get_scrub_params(stock, index, lookback, stock_ceiling_params, index_floor_params, best_fit_param) for stock in stocks ] #betas = [create_beta_object_from_scrub_params(stocks[i], index, lookback, scrub_params_all[i]) for i in range(len(stocks))] betas = [ Beta(stocks[i], index, lookback, scrub_params_all[i]) for i in range(len(stocks)) ] beta_values = [beta.beta_value for beta in betas] # Returns Info returns = [get_total_return(stock, lookback) for stock in stocks] index_returns = [ get_total_return(index, lookback) for _ in range(len(stocks)) ] idio_returns = [ (1 + returns[i]) / (1 + index_returns[i] * beta_values[i]) - 1 for i in range(len(stocks)) ] # Beta to SPY Info index_betas_to_SPY = [get_ETF_beta_to_SPY(stock) for stock in stocks] betas_to_SPY = [ index_betas_to_SPY[i] * beta_values[i] for i in range(len(stocks)) ] # Prepare Information for the DataFrame in an Ordered Dictionary info = OrderedDict([ # Index Symbol ('Index', [index for _ in range(len(stocks))]), # OLS Info ('Beta', beta_values), ('Corr', [beta.corr for beta in betas]), # Beta to SPY Info ('Index_Beta_to_SPY', index_betas_to_SPY), ('Beta_to_SPY', betas_to_SPY), # Returns Info ('Stock_Return', returns), ('Index_Return', index_returns), ('Idio_Return', idio_returns), # Scrubbing Info ('Stock_Cutoff', [scrub_params.stock_cutoff for scrub_params in scrub_params_all]), ('Index_Cutoff', [scrub_params.index_cutoff for scrub_params in scrub_params_all]), ('Percentile_Cutoff', [scrub_params.percentile_cutoff for scrub_params in scrub_params_all]), ('Percent_Days', [beta.percent_days_in_calculation for beta in betas]) ]) # Create DataFrame column_labels = info.keys() table_info = list(zip(info.values())) index_row = pd.Index(stocks, name='Stock') #iterables_columns = [[index], column_labels] iterables_columns = [['Index'], column_labels] index_column = pd.MultiIndex.from_product(iterables_columns, names=['Index', 'Beta_Info']) df = pd.DataFrame(table_info, index=index_row, columns=index_column) if save_to_file: to_pickle_and_CSV(df, file_name) return df
def get_betas_multiple_indices( stock, indices: 'iterable of indices', lookback=252, stock_ceiling_params=DEFAULT_STOCK_CEILING_PARAMS, index_floor_params=DEFAULT_INDEX_FLOOR_PARAMS, best_fit_param=BEST_FIT_PERCENTILE, save_to_file=False): scrub_params_all = [ get_scrub_params(stock, index, lookback, stock_ceiling_params, index_floor_params, best_fit_param) for index in indices ] betas = [ Beta(stock, indices[i], lookback, scrub_params_all[i]) for i in range(len(indices)) ] # OLS Info beta_values = [beta.beta_value for beta in betas] corrs = [beta.corr for beta in betas] # Scrubbing Info stock_cutoffs = [ scrub_params.stock_cutoff for scrub_params in scrub_params_all ] index_cutoffs = [ scrub_params.index_cutoff for scrub_params in scrub_params_all ] percentile_cutoffs = [ scrub_params.percentile_cutoff for scrub_params in scrub_params_all ] percent_days_in_calc = [beta.percent_days_in_calculation for beta in betas] # Beta to SPY Info index_betas_to_SPY = [get_ETF_beta_to_SPY(index) for index in indices] betas_to_SPY = [ index_betas_to_SPY[i] * beta_values[i] for i in range(len(indices)) ] # Returns Info returns = [get_total_return(stock, lookback) for _ in indices] index_returns = [get_total_return(index, lookback) for index in indices] idio_returns = [ (1 + returns[i]) / (1 + index_returns[i] * beta_values[i]) - 1 for i in range(len(indices)) ] # Unadjusted OLS Info unadjusted_betas = [ Beta(stock, indices[i], lookback, ScrubParams(False, False, False)) for i in range(len(indices)) ] unadjusted_beta_values = [beta.beta_value for beta in unadjusted_betas] unadjusted_corrs = [beta.corr for beta in unadjusted_betas] # Prepare Information for the DataFrame in an Ordered Dictionary table_info_dict = OrderedDict([ #Unadjusted OLS Info ('Unadj. Beta', unadjusted_beta_values), ('Unadj. Corr', unadjusted_corrs), # OLS Info ('Beta', beta_values), ('Corr', corrs), # Beta to SPY Info ('Index_Beta_to_SPY', index_betas_to_SPY), ('Beta_to_SPY', betas_to_SPY), # Returns Info ('Stock_Return', returns), ('Index_Return', index_returns), ('Idio_return', idio_returns), # Scrubbing Info ('Stock_Cutoff', stock_cutoffs), ('Index_Cutoff', index_cutoffs), ('Percentile_Cutoff', percentile_cutoffs), ('Percent_Days', percent_days_in_calc) ]) # Create DataFrame column_labels = table_info_dict.keys() table_info = list(zip(*table_info_dict.values())) index_row = pd.Index(indices, name='Index') iterables_columns = [[stock], column_labels] index_column = pd.MultiIndex.from_product(iterables_columns, names=['Stock', 'Beta_Info']) df = pd.DataFrame(table_info, index=index_row, columns=index_column) if save_to_file: to_pickle_and_CSV(df, file_name) return df