Overview

Architecture

Primary Variables

Methods

Code


# Filter to determine if pair of assets pass the ADF test with a p value requirement of .05

def cointegration_filter(cur_stock):  
  
    cur_pair=get_time_period(list(cur_stock[0:2]), custom_data=True, num_data_points=500,shift=cur_stock[2],freq='5m').dropna()  
    model = m.OLS(cur_pair[cur_stock[0]], m.add_constant(cur_pair[cur_stock[1]])).fit()  

    resudials = model.resid
    adf_result = adfuller(resudials)  
    if adf_result[1] < .0501:  
        return model.params.iloc[1]  
    else:  
        return -1000000  
  

# Executes efficient parallel processing where the joblib class, specifically pool, is used. 15 concurrent processes are being run in this situation. Note also there's a splitting based on the time period being run on by the data, which is characterized by the shift parameter
## args is an optional argument which stores time period related information. An example would be the beta values which can be used in the beta based weighing of stocks when executing a portfolio backtest

def runner(stock_pair: pd.Series, shift_parameter: int,filter_func,args= None):  
  
    if args is not None:  
	    p_list = [list(x) + [shift_parameter] + [float(y)] for x,y in zip(stock_pair.index,args)]  
	else:  
        p_list = [list(x) + [shift_parameter] for x in stock_pair.index]  
  
    with Pool(processes=15) as pool:  
        filter_results = pool.map(filter_func, p_list)  
    series_coint = pd.Series(index=stock_pair.index,data= filter_results)  
  
    filt = series_coint[[x for x in series_coint.index if -1000000 not in  series_coint[x]]]  
  
    return pd.Series(data=[[x] for x in filt],index=filt.index)  


# Handles the iteration of each of the stock pairs by time period.

def runner_multiple(stock_pair_list: pd.Series, shift_parameter_list: list,filter_func,args=None):  
	
    if all([len(x) == 1 for x in stock_pair_list]):
        args = pd.DataFrame([x[:len(x)-1] for x in args],index=stock_pair_list.index)  
        args = [list(args.iloc[:,x]) for x in range(len(args.columns))]  
  
    stock_pairs_final = runner(stock_pair_list,shift_parameter_list[0],filter_func,args[0])  
  
    if len(shift_parameter_list) == 1:  
        return (stock_pairs_final + stock_pair_list).dropna()  
    return runner_multiple((stock_pairs_final + stock_pair_list).dropna(),shift_parameter_list[1:],  
                           filter_func,args[1:])

def run():
	
    # Example pair of stock pairs and shift parameters
	stock_pair_list = pd.Series([('AAPL','AMAC'),('FICO','GE')])
	shift_parameter_list = [0,50]
	
	runner_multiple(stock_pair_list,shift_parameter_list,cointegration_filter)