def get_best_betas():
    best_indices = []
    best_betas = []
    best_corrs = []

    for stock in stocks:
        indices = ['SPY', 'XLV', 'IBB', 'XBI']
        index_cutoffs = {'SPY': .015, 'XLV': .015, 'IBB': .015, 'XBI': .0225}
        outcomes = []
        for index in indices:
            index_cutoff = index_cutoffs[index]
            scrub_params = ScrubParams(stock_cutoff, index_cutoff,
                                       percentile_cutoff)
            beta = Beta(stock, index, lookback, scrub_params)
            outcomes.append((index, beta.beta_value, beta.corr))
        max_corr = max([i[2] for i in outcomes])
        best_fit = [i for i in outcomes if i[2] == max_corr][0]
        best_indices.append(best_fit[0])
        best_betas.append(best_fit[1])
        best_corrs.append(best_fit[2])

    info = {
        'Stock': stocks,
        'Index': best_indices,
        'Beta': best_betas,
        'Corr': best_corrs
    }

    return pd.DataFrame(info).set_index('Stock').loc[:,
                                                     ['Index', 'Beta', 'Corr']]
def get_scrub_params_from_cutoff_params(stock, index, lookback, cutoff_params,
                                        percentile_cutoff):
    stock_cutoff = get_stock_cutoff(stock, lookback,
                                    cutoff_params.Percentile_Cutoff,
                                    cutoff_params.Stock_STD_Cutoff)
    index_cutoff = get_index_cutoff(index, lookback,
                                    cutoff_params.Percentile_Cutoff,
                                    cutoff_params.Index_STD_Cutoff)
    return ScrubParams(stock_cutoff, index_cutoff, percentile_cutoff)
import copy

from beta_model.beta_class import Beta, ScrubParams
from beta_model.StockLine_Module import StockLineBetaAdjusted

if __name__ == '__Main__':
    stock = 'ABBV'
    index = 'XLV'
    beta_lookback = 400
    lookback = beta_lookback
    scrub_params = ScrubParams(.075, .01, .8)
    beta = Beta(stock, index, beta_lookback, scrub_params).beta_value

    stock_line = StockLineBetaAdjusted(stock, lookback, beta, index)
    adjusted_returns = stock_line.adjusted_returns
    #print(adjusted_returns)


class Beta_StepTwo(Beta):
    def __init__(self, stock: 'str', index: 'str', lookback: 'int',
                 scrub_params: 'obj'):
        super().__init__(stock, index, lookback, scrub_params)

        beta_value = Beta(self.stock, self.index, self.lookback,
                          self.scrub_params).beta_value
        #print("{}, {}, Beta: {}".format(self.stock, self.index, beta_value))
        self.stock_line = copy.deepcopy(
            StockLineBetaAdjusted(self.stock, self.lookback, beta_value,
                                  self.index))
        self.adjusted_returns = self.stock_line.adjusted_returns
        self.adjusted_returns_df_column_name = self.stock_line.adjusted_returns_df_column_name
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_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