def get_summary_stats(pnl_series): output = dict() output['total_pnl'] = float('NaN') output['mean_pnl'] = float('NaN') output['downside20'] = float('NaN') output['downside5'] = float('NaN') output['reward_risk'] = float('NaN') if len(pnl_series)==0: return output output['total_pnl'] = np.nansum(pnl_series) output['mean_pnl'] = np.nanmean(pnl_series) if len(pnl_series) >= 10: output['downside20'] = stats.get_number_from_quantile(y=pnl_series, quantile_list=[20])[0] if len(pnl_series) >= 40: output['downside5'] = stats.get_number_from_quantile(y=pnl_series, quantile_list=[5])[0] output['reward_risk'] = output['mean_pnl']/abs(output['downside20'] ) return output
def get_summary_stats(pnl_series): output = dict() output['total_pnl'] = float('NaN') output['mean_pnl'] = float('NaN') output['downside20'] = float('NaN') output['downside5'] = float('NaN') output['reward_risk'] = float('NaN') if len(pnl_series) == 0: return output output['total_pnl'] = np.nansum(pnl_series) output['mean_pnl'] = np.nanmean(pnl_series) if len(pnl_series) >= 10: output['downside20'] = stats.get_number_from_quantile( y=pnl_series, quantile_list=[20])[0] if len(pnl_series) >= 40: output['downside5'] = stats.get_number_from_quantile( y=pnl_series, quantile_list=[5])[0] output['reward_risk'] = output['mean_pnl'] / abs(output['downside20']) return output
def calc_theo_spread_move_from_ratio_normalization(**kwargs): ratio_time_series = kwargs['ratio_time_series'] starting_quantile = kwargs['starting_quantile'] num_price = kwargs['num_price'] den_price = kwargs['den_price'] favorable_quantile_move_list = kwargs['favorable_quantile_move_list'] ratio_target_list = [np.NAN]*len(favorable_quantile_move_list) if starting_quantile > 50: ratio_target_list = stats.get_number_from_quantile(y=ratio_time_series, quantile_list=[starting_quantile-x for x in favorable_quantile_move_list]) elif starting_quantile < 50: ratio_target_list = stats.get_number_from_quantile(y=ratio_time_series, quantile_list=[starting_quantile+x for x in favorable_quantile_move_list]) theo_spread_move_list = \ [calc_spread_move_from_new_ratio(num_price=num_price, den_price=den_price, new_ratio=x) if np.isfinite(x) else np.NAN for x in ratio_target_list] return {'ratio_target_list': ratio_target_list, 'theo_spread_move_list': theo_spread_move_list}
def calc_theo_spread_move_from_ratio_normalization(**kwargs): ratio_time_series = kwargs['ratio_time_series'] starting_quantile = kwargs['starting_quantile'] num_price = kwargs['num_price'] den_price = kwargs['den_price'] favorable_quantile_move_list = kwargs['favorable_quantile_move_list'] ratio_target_list = [np.NAN] * len(favorable_quantile_move_list) if starting_quantile > 50: ratio_target_list = stats.get_number_from_quantile( y=ratio_time_series, quantile_list=[ starting_quantile - x for x in favorable_quantile_move_list ]) elif starting_quantile < 50: ratio_target_list = stats.get_number_from_quantile( y=ratio_time_series, quantile_list=[ starting_quantile + x for x in favorable_quantile_move_list ]) theo_spread_move_list = \ [calc_spread_move_from_new_ratio(num_price=num_price, den_price=den_price, new_ratio=x) if np.isfinite(x) else np.NAN for x in ratio_target_list] return { 'ratio_target_list': ratio_target_list, 'theo_spread_move_list': theo_spread_move_list }
def get_chisquare_independence_results(**kwargs): indicator_name = kwargs['indicator_name'] target_name = kwargs['target_name'] dataframe_input = kwargs['dataframe_input'] dataframe_input = dataframe_input[ dataframe_input[indicator_name].notnull() & dataframe_input[target_name].notnull()] dataframe_input['target_category'] = 0 dataframe_input['indicator_category'] = 0 quantile_values = stats.get_number_from_quantile( y=dataframe_input[target_name].values, quantile_list=[33, 66]) dataframe_input.loc[dataframe_input[target_name] < quantile_values[0], 'target_category'] = -1 dataframe_input.loc[dataframe_input[target_name] > quantile_values[1], 'target_category'] = 1 quantile_values = stats.get_number_from_quantile( y=dataframe_input[indicator_name].values, quantile_list=[10, 90]) dataframe_input.loc[dataframe_input[indicator_name] < quantile_values[0], 'indicator_category'] = -1 dataframe_input.loc[dataframe_input[indicator_name] > quantile_values[1], 'indicator_category'] = 1 dataframe_input = dataframe_input[ dataframe_input['indicator_category'] != 0] contingency_table = [[ sum((dataframe_input['indicator_category'] == cat1) & (dataframe_input['target_category'] == cat2)) for cat2 in [-1, 0, 1] ] for cat1 in [-1, 1]] chi_square_output = scs.chi2_contingency(contingency_table) chi_square_stat = chi_square_output[0] return { 'chi_square': chi_square_stat, 'cramers_v': np.sqrt(chi_square_stat / len(dataframe_input.index)) }
def bucket_data(**kwargs): data_input = kwargs['data_input'] bucket_var = kwargs['bucket_var'] if 'ascending_q' in kwargs.keys(): ascending_q = kwargs['ascending_q'] else: ascending_q = True if 'num_buckets' in kwargs.keys(): num_buckets = kwargs['num_buckets'] else: num_buckets = 10 quantile_limits = get_equal_length_partition(min_value=0, max_value=100, num_parts=num_buckets) bucket_limits = stats.get_number_from_quantile( y=data_input[bucket_var].values.astype(np.float64), quantile_list=quantile_limits) bucket_data_list = [] for i in range(num_buckets): if i == 0: bucket_data = data_input.loc[ data_input[bucket_var] <= bucket_limits[i]] elif i < num_buckets - 1: bucket_data = data_input.loc[ (data_input[bucket_var] > bucket_limits[i - 1]) & (data_input[bucket_var] <= bucket_limits[i])] else: bucket_data = data_input.loc[ data_input[bucket_var] > bucket_limits[i - 1]] bucket_data_list.append(bucket_data) if not ascending_q: bucket_data_list.reverse() bucket_limits = np.flipud(bucket_limits) return { 'bucket_data_list': bucket_data_list, 'bucket_limits': bucket_limits }
def bucket_data(**kwargs): data_input = kwargs['data_input'] bucket_var = kwargs['bucket_var'] if 'ascending_q' in kwargs.keys(): ascending_q = kwargs['ascending_q'] else: ascending_q = True if 'num_buckets' in kwargs.keys(): num_buckets = kwargs['num_buckets'] else: num_buckets = 10 quantile_limits = get_equal_length_partition(min_value=0, max_value=100, num_parts=num_buckets) bucket_limits = stats.get_number_from_quantile(y=data_input[bucket_var].values, quantile_list=quantile_limits) bucket_data_list = [] for i in range(num_buckets): if i == 0: bucket_data = data_input.loc[data_input[bucket_var] <= bucket_limits[i]] elif i < num_buckets-1: bucket_data = data_input.loc[(data_input[bucket_var] > bucket_limits[i-1])& (data_input[bucket_var] <= bucket_limits[i])] else: bucket_data = data_input.loc[data_input[bucket_var] > bucket_limits[i-1]] bucket_data_list.append(bucket_data) if not ascending_q: bucket_data_list.reverse() bucket_limits = np.flipud(bucket_limits) return {'bucket_data_list' : bucket_data_list, 'bucket_limits' : bucket_limits}
def get_order_book_signals_4date(**kwargs): trade_date = kwargs['trade_date'] ticker = kwargs['ticker'] calibration_date = exp.doubledate_shift_bus_days(double_date=trade_date, shift_in_days=1) trading_data = obf.get_orderbook_signals(ticker=ticker, date_to=trade_date) calibration_data = obf.get_orderbook_signals(ticker=ticker, date_to=calibration_date) y = calibration_data.loc[:, 'target'] # response X = calibration_data.loc[:, [ 'voi', 'voi1', 'voi2', 'voi3', 'voi4', 'voi5', 'oir', 'oir1', 'oir2', 'oir3', 'oir4', 'oir5' ]] # predictor X = sm.add_constant(X) olsmod = sm.OLS(y, X) olsres = olsmod.fit() calibration_data['predict'] = olsres.predict(X) pred_levels = stats.get_number_from_quantile(y=calibration_data['predict'], quantile_list=[10, 90]) X = trading_data.loc[:, [ 'voi', 'voi1', 'voi2', 'voi3', 'voi4', 'voi5', 'oir', 'oir1', 'oir2', 'oir3', 'oir4', 'oir5' ]] # predictor X = sm.add_constant(X) trading_data['predict'] = olsres.predict(X) trading_data['bias'] = 0 trading_data.loc[trading_data['predict'] <= pred_levels[0], 'bias'] = -1 trading_data.loc[trading_data['predict'] >= pred_levels[1], 'bias'] = 1 return trading_data
def get_results_4tickerhead(**kwargs): ticker_head = kwargs['ticker_head'] date_to = kwargs['date_to'] ticker_class = cmi.ticker_class[ticker_head] indicator_list = [ 'change_1_high_volume', 'change_5_high_volume', 'change_10_high_volume', 'change_20_high_volume', 'change_1_low_volume', 'change_5_low_volume', 'change_10_low_volume', 'change_20_low_volume', 'change_1Normalized', 'change_5Normalized', 'change_10Normalized', 'change_20Normalized', 'comm_net_change_1_normalized', 'comm_net_change_2_normalized', 'comm_net_change_4_normalized', 'spec_net_change_1_normalized', 'spec_net_change_2_normalized', 'spec_net_change_4_normalized', 'comm_z', 'spec_z' ] date_from = cu.doubledate_shift(date_to, 5 * 365) datetime_to = cu.convert_doubledate_2datetime(date_to) panel_data = gfp.get_futures_price_preloaded(ticker_head=ticker_head, settle_date_from=date_from, settle_date_to=date_to) panel_data = panel_data[panel_data['tr_dte'] >= 40] panel_data.sort(['settle_date', 'tr_dte'], ascending=[True, True], inplace=True) rolling_data = panel_data.drop_duplicates(subset=['settle_date'], take_last=False) daily_noise = np.std(rolling_data['change_1']) average_volume = rolling_data['volume'].mean() rolling_data['change_40'] = pd.rolling_sum(rolling_data['change_1'], 40, min_periods=30) rolling_data['change_20'] = pd.rolling_sum(rolling_data['change_1'], 20, min_periods=15) rolling_data['change_10'] = pd.rolling_sum(rolling_data['change_1'], 10, min_periods=7) rolling_data['change_1Normalized'] = rolling_data['change_1'] / daily_noise rolling_data['change_5Normalized'] = rolling_data['change_5'] / daily_noise rolling_data[ 'change_10Normalized'] = rolling_data['change_10'] / daily_noise rolling_data[ 'change_20Normalized'] = rolling_data['change_20'] / daily_noise rolling_data[ 'change_40Normalized'] = rolling_data['change_40'] / daily_noise rolling_data['change1Normalized'] = rolling_data['change1'] / daily_noise rolling_data['change1_InstantNormalized'] = rolling_data[ 'change1_instant'] / daily_noise rolling_data['change1_InstantNormalized'] = rolling_data[ 'change1_instant'] / daily_noise rolling_data['high1_InstantNormalized'] = ( rolling_data['high1_instant'] - rolling_data['close_price']) / daily_noise rolling_data['low1_InstantNormalized'] = ( rolling_data['low1_instant'] - rolling_data['close_price']) / daily_noise rolling_data['change5Normalized'] = rolling_data['change5'] / daily_noise rolling_data['change10Normalized'] = rolling_data['change10'] / daily_noise rolling_data['change20Normalized'] = rolling_data['change20'] / daily_noise rolling_data['volume_mean20'] = pd.rolling_mean(rolling_data['volume'], 20, min_periods=15) rolling_data['volume_mean10'] = pd.rolling_mean(rolling_data['volume'], 10, min_periods=7) rolling_data['volume_mean5'] = pd.rolling_mean(rolling_data['volume'], 5, min_periods=4) rolling_data['volume_mean20Normalized'] = rolling_data[ 'volume_mean20'] / average_volume rolling_data['volume_mean10Normalized'] = rolling_data[ 'volume_mean10'] / average_volume rolling_data['volume_mean5Normalized'] = rolling_data[ 'volume_mean5'] / average_volume rolling_data['volume_Normalized'] = rolling_data['volume'] / average_volume rolling_data['change_1_high_volume'] = ( rolling_data['volume'] > average_volume) * rolling_data['change_1Normalized'] rolling_data['change_5_high_volume'] = ( rolling_data['volume_mean5'] > average_volume) * rolling_data['change_5Normalized'] rolling_data['change_10_high_volume'] = ( rolling_data['volume_mean10'] > average_volume) * rolling_data['change_10Normalized'] rolling_data['change_20_high_volume'] = ( rolling_data['volume_mean20'] > average_volume) * rolling_data['change_20Normalized'] rolling_data['change_1_low_volume'] = ( rolling_data['volume'] <= average_volume) * rolling_data['change_1Normalized'] rolling_data['change_5_low_volume'] = ( rolling_data['volume_mean5'] <= average_volume) * rolling_data['change_5Normalized'] rolling_data['change_10_low_volume'] = ( rolling_data['volume_mean10'] <= average_volume) * rolling_data['change_10Normalized'] rolling_data['change_20_low_volume'] = ( rolling_data['volume_mean20'] <= average_volume) * rolling_data['change_20Normalized'] cot_output = cot.get_cot_data(ticker_head=ticker_head, date_from=date_from, date_to=date_to) dictionary_out = { 'vote1': np.nan, 'vote1_instant': np.nan, 'vote12_instant': np.nan, 'vote13_instant': np.nan, 'vote5': np.nan, 'vote10': np.nan, 'vote20': np.nan, 'regress_forecast1': np.nan, 'regress_forecast2': np.nan, 'regress_forecast3': np.nan, 'svr_forecast1': np.nan, 'svr_forecast2': np.nan, 'norm_pnl1': np.nan, 'norm_pnl1Instant': np.nan, 'long_tight_stop_pnl1Instant': np.nan, 'long_loose_stop_pnl1Instant': np.nan, 'short_tight_stop_pnl1Instant': np.nan, 'short_loose_stop_pnl1Instant': np.nan, 'norm_pnl5': np.nan, 'norm_pnl10': np.nan, 'norm_pnl20': np.nan, 'rolling_data': pd.DataFrame() } for ind in indicator_list: dictionary_out[ind] = np.nan if len(cot_output.index) < 20: return dictionary_out cot_net = pd.DataFrame() if ticker_class in ['FX', 'STIR', 'Index', 'Treasury']: cot_net['comm_net'] = cot_output['Dealer Longs'] - cot_output[ 'Dealer Shorts'] cot_net['spec_net'] = cot_output['Asset Manager Longs'] - cot_output[ 'Asset Manager Shorts'] + cot_output[ 'Leveraged Funds Longs'] - cot_output['Leveraged Funds Shorts'] else: cot_net['comm_net'] = cot_output[ 'Producer/Merchant/Processor/User Longs'] - cot_output[ 'Producer/Merchant/Processor/User Shorts'] cot_net['spec_net'] = cot_output['Money Manager Longs'] - cot_output[ 'Money Manager Shorts'] cot_net['comm_net_change_1'] = cot_net['comm_net'] - cot_net[ 'comm_net'].shift(1) cot_net['comm_net_change_2'] = cot_net['comm_net'] - cot_net[ 'comm_net'].shift(2) cot_net['comm_net_change_4'] = cot_net['comm_net'] - cot_net[ 'comm_net'].shift(4) cot_net['spec_net_change_1'] = cot_net['spec_net'] - cot_net[ 'spec_net'].shift(1) cot_net['spec_net_change_2'] = cot_net['spec_net'] - cot_net[ 'spec_net'].shift(2) cot_net['spec_net_change_4'] = cot_net['spec_net'] - cot_net[ 'spec_net'].shift(4) comm_net_change_1_avg = np.std(cot_net['comm_net_change_1']) comm_net_change_2_avg = np.std(cot_net['comm_net_change_2']) comm_net_change_4_avg = np.std(cot_net['comm_net_change_4']) spec_net_change_1_avg = np.std(cot_net['spec_net_change_1']) spec_net_change_2_avg = np.std(cot_net['spec_net_change_2']) spec_net_change_4_avg = np.std(cot_net['spec_net_change_4']) cot_net['comm_net_change_1_normalized'] = cot_net[ 'comm_net_change_1'] / comm_net_change_1_avg cot_net['comm_net_change_2_normalized'] = cot_net[ 'comm_net_change_2'] / comm_net_change_2_avg cot_net['comm_net_change_4_normalized'] = cot_net[ 'comm_net_change_4'] / comm_net_change_4_avg cot_net['spec_net_change_1_normalized'] = cot_net[ 'spec_net_change_1'] / spec_net_change_1_avg cot_net['spec_net_change_2_normalized'] = cot_net[ 'spec_net_change_2'] / spec_net_change_2_avg cot_net['spec_net_change_4_normalized'] = cot_net[ 'spec_net_change_4'] / spec_net_change_4_avg cot_net['comm_z'] = (cot_net['comm_net'] - np.mean( cot_net['comm_net'])) / np.std(cot_net['comm_net']) cot_net['spec_z'] = (cot_net['spec_net'] - np.mean( cot_net['spec_net'])) / np.std(cot_net['spec_net']) cot_net['settle_date'] = cot_net.index cot_net['settle_date'] = [ x + dt.timedelta(days=3) for x in cot_net['settle_date'] ] combined_data = pd.merge(rolling_data, cot_net, how='left', on='settle_date') combined_data['comm_net_change_1_normalized'] = combined_data[ 'comm_net_change_1_normalized'].fillna(method='pad') combined_data['comm_net_change_2_normalized'] = combined_data[ 'comm_net_change_2_normalized'].fillna(method='pad') combined_data['comm_net_change_4_normalized'] = combined_data[ 'comm_net_change_4_normalized'].fillna(method='pad') combined_data['spec_net_change_1_normalized'] = combined_data[ 'spec_net_change_1_normalized'].fillna(method='pad') combined_data['spec_net_change_2_normalized'] = combined_data[ 'spec_net_change_2_normalized'].fillna(method='pad') combined_data['spec_net_change_4_normalized'] = combined_data[ 'spec_net_change_4_normalized'].fillna(method='pad') combined_data['comm_z'] = combined_data['comm_z'].fillna(method='pad') combined_data['spec_z'] = combined_data['spec_z'].fillna(method='pad') test_data = combined_data[combined_data['settle_date'] == datetime_to] training_data = combined_data[combined_data['settle_date'] < datetime_to + dt.timedelta(days=-30)] if test_data.empty or training_data.empty: return dictionary_out sharp1_list = [] sharp1_instant_list = [] sharp5_list = [] sharp10_list = [] sharp20_list = [] higher_level_list = [] lower_level_list = [] for i in range(len(indicator_list)): selected_data = training_data[training_data[ indicator_list[i]].notnull()] indicator_levels = stats.get_number_from_quantile( y=selected_data[indicator_list[i]].values, quantile_list=[10, 90]) lower_level_list.append(indicator_levels[0]) higher_level_list.append(indicator_levels[1]) low_data = selected_data[ selected_data[indicator_list[i]] < indicator_levels[0]] high_data = selected_data[ selected_data[indicator_list[i]] > indicator_levels[1]] high_data['pnl1'] = high_data['change1Normalized'] low_data['pnl1'] = -low_data['change1Normalized'] high_data['pnl1_instant'] = high_data['change1_InstantNormalized'] low_data['pnl1_instant'] = -low_data['change1_InstantNormalized'] high_data['pnl5'] = high_data['change5Normalized'] low_data['pnl5'] = -low_data['change5Normalized'] high_data['pnl10'] = high_data['change10Normalized'] low_data['pnl10'] = -low_data['change10Normalized'] high_data['pnl20'] = high_data['change20Normalized'] low_data['pnl20'] = -low_data['change20Normalized'] merged_data = pd.concat([high_data, low_data]) sharp1_list.append(16 * merged_data['pnl1'].mean() / merged_data['pnl1'].std()) sharp1_instant_list.append(16 * merged_data['pnl1_instant'].mean() / merged_data['pnl1_instant'].std()) sharp5_list.append(7.2 * merged_data['pnl5'].mean() / merged_data['pnl5'].std()) sharp10_list.append(5.1 * merged_data['pnl10'].mean() / merged_data['pnl10'].std()) sharp20_list.append(3.5 * merged_data['pnl20'].mean() / merged_data['pnl20'].std()) sharp_frame = pd.DataFrame.from_items([('indicator', indicator_list), ('lower_level', lower_level_list), ('higher_level', higher_level_list), ('sharp1', sharp1_list), ('sharp1_instant', sharp1_instant_list), ('sharp5', sharp5_list), ('sharp10', sharp10_list), ('sharp20', sharp20_list)]) vote1 = 0 for i in range(len(indicator_list)): indicator_value = test_data[indicator_list[i]].iloc[0] selected_sharp_row = sharp_frame[sharp_frame['indicator'] == indicator_list[i]] if (selected_sharp_row['sharp1'].iloc[0] > 0.75) & ( indicator_value > selected_sharp_row['higher_level'].iloc[0]): vote1 += 1 elif (selected_sharp_row['sharp1'].iloc[0] > 0.75) & ( indicator_value < selected_sharp_row['lower_level'].iloc[0]): vote1 -= 1 elif (selected_sharp_row['sharp1'].iloc[0] < -0.75) & ( indicator_value > selected_sharp_row['higher_level'].iloc[0]): vote1 -= 1 elif (selected_sharp_row['sharp1'].iloc[0] < -0.75) & ( indicator_value < selected_sharp_row['lower_level'].iloc[0]): vote1 += 1 vote1_instant = 0 for i in range(len(indicator_list)): indicator_value = test_data[indicator_list[i]].iloc[0] selected_sharp_row = sharp_frame[sharp_frame['indicator'] == indicator_list[i]] if (selected_sharp_row['sharp1_instant'].iloc[0] > 0.75) & ( indicator_value > selected_sharp_row['higher_level'].iloc[0]): vote1_instant += 1 elif (selected_sharp_row['sharp1_instant'].iloc[0] > 0.75) & ( indicator_value < selected_sharp_row['lower_level'].iloc[0]): vote1_instant -= 1 elif (selected_sharp_row['sharp1_instant'].iloc[0] < -0.75) & ( indicator_value > selected_sharp_row['higher_level'].iloc[0]): vote1_instant -= 1 elif (selected_sharp_row['sharp1_instant'].iloc[0] < -0.75) & ( indicator_value < selected_sharp_row['lower_level'].iloc[0]): vote1_instant += 1 vote12_instant = 0 indicator_t_list = [ 'change_1_high_volume', 'change_5_high_volume', 'change_10_high_volume', 'change_20_high_volume', 'change_1_low_volume', 'change_5_low_volume', 'change_10_low_volume', 'change_20_low_volume' ] for i in range(len(indicator_t_list)): indicator_value = test_data[indicator_t_list[i]].iloc[0] selected_sharp_row = sharp_frame[sharp_frame['indicator'] == indicator_t_list[i]] if (selected_sharp_row['sharp1_instant'].iloc[0] > 0.75) & ( indicator_value > selected_sharp_row['higher_level'].iloc[0]): vote12_instant += 1 elif (selected_sharp_row['sharp1_instant'].iloc[0] > 0.75) & ( indicator_value < selected_sharp_row['lower_level'].iloc[0]): vote12_instant -= 1 elif (selected_sharp_row['sharp1_instant'].iloc[0] < -0.75) & ( indicator_value > selected_sharp_row['higher_level'].iloc[0]): vote12_instant -= 1 elif (selected_sharp_row['sharp1_instant'].iloc[0] < -0.75) & ( indicator_value < selected_sharp_row['lower_level'].iloc[0]): vote12_instant += 1 vote13_instant = 0 for i in range(len(indicator_t_list)): indicator_value = test_data[indicator_t_list[i]].iloc[0] selected_sharp_row = sharp_frame[sharp_frame['indicator'] == indicator_t_list[i]] if (selected_sharp_row['sharp1_instant'].iloc[0] > 1) & ( indicator_value > selected_sharp_row['higher_level'].iloc[0]): vote13_instant += 1 elif (selected_sharp_row['sharp1_instant'].iloc[0] > 1) & ( indicator_value < selected_sharp_row['lower_level'].iloc[0]): vote13_instant -= 1 elif (selected_sharp_row['sharp1_instant'].iloc[0] < -1) & ( indicator_value > selected_sharp_row['higher_level'].iloc[0]): vote13_instant -= 1 elif (selected_sharp_row['sharp1_instant'].iloc[0] < -1) & ( indicator_value < selected_sharp_row['lower_level'].iloc[0]): vote13_instant += 1 vote5 = 0 for i in range(len(indicator_list)): indicator_value = test_data[indicator_list[i]].iloc[0] selected_sharp_row = sharp_frame[sharp_frame['indicator'] == indicator_list[i]] if (selected_sharp_row['sharp5'].iloc[0] > 0.75) & ( indicator_value > selected_sharp_row['higher_level'].iloc[0]): vote5 += 1 elif (selected_sharp_row['sharp5'].iloc[0] > 0.75) & ( indicator_value < selected_sharp_row['lower_level'].iloc[0]): vote5 -= 1 elif (selected_sharp_row['sharp5'].iloc[0] < -0.75) & ( indicator_value > selected_sharp_row['higher_level'].iloc[0]): vote5 -= 1 elif (selected_sharp_row['sharp5'].iloc[0] < -0.75) & ( indicator_value < selected_sharp_row['lower_level'].iloc[0]): vote5 += 1 vote10 = 0 for i in range(len(indicator_list)): indicator_value = test_data[indicator_list[i]].iloc[0] selected_sharp_row = sharp_frame[sharp_frame['indicator'] == indicator_list[i]] if (selected_sharp_row['sharp10'].iloc[0] > 0.75) & ( indicator_value > selected_sharp_row['higher_level'].iloc[0]): vote10 += 1 elif (selected_sharp_row['sharp10'].iloc[0] > 0.75) & ( indicator_value < selected_sharp_row['lower_level'].iloc[0]): vote10 -= 1 elif (selected_sharp_row['sharp10'].iloc[0] < -0.75) & ( indicator_value > selected_sharp_row['higher_level'].iloc[0]): vote10 -= 1 elif (selected_sharp_row['sharp10'].iloc[0] < -0.75) & ( indicator_value < selected_sharp_row['lower_level'].iloc[0]): vote10 += 1 vote20 = 0 for i in range(len(indicator_list)): indicator_value = test_data[indicator_list[i]].iloc[0] selected_sharp_row = sharp_frame[sharp_frame['indicator'] == indicator_list[i]] if (selected_sharp_row['sharp20'].iloc[0] > 0.75) & ( indicator_value > selected_sharp_row['higher_level'].iloc[0]): vote20 += 1 elif (selected_sharp_row['sharp20'].iloc[0] > 0.75) & ( indicator_value < selected_sharp_row['lower_level'].iloc[0]): vote20 -= 1 elif (selected_sharp_row['sharp20'].iloc[0] < -0.75) & ( indicator_value > selected_sharp_row['higher_level'].iloc[0]): vote20 -= 1 elif (selected_sharp_row['sharp20'].iloc[0] < -0.75) & ( indicator_value < selected_sharp_row['lower_level'].iloc[0]): vote20 += 1 #svr_rbf = SVR(kernel='rbf', C=1e3, gamma=0.1) #svr_forecast = svr_rbf.fit(x,y).predict(test_data[indicator_list].values)[0] #svc_rbf1 = SVC(kernel='rbf', C=1, gamma=0.1) #svc_forecast1 = svc_rbf1.fit(x,y).predict(test_data[indicator_list].values)[0] regress_forecast1 = np.nan regress_forecast2 = np.nan regress_forecast3 = np.nan svr_forecast1 = np.nan svr_forecast2 = np.nan try: regress_input = training_data[[ 'change_1Normalized', 'change_10Normalized', 'change1_InstantNormalized' ]].dropna() y = regress_input['change1_InstantNormalized'] X = regress_input[['change_1Normalized', 'change_10Normalized']] X = sm.add_constant(X) params1 = sm.OLS(y, X).fit().params regress_forecast1 = params1['const']+\ params1['change_1Normalized']*test_data['change_1Normalized'].iloc[0]+\ params1['change_10Normalized']*test_data['change_10Normalized'].iloc[0] except: pass try: regress_input = training_data[[ 'change_1Normalized', 'change_10Normalized', 'change1_InstantNormalized', 'comm_net_change_1_normalized' ]].dropna() y = regress_input['change1_InstantNormalized'] X = regress_input[[ 'change_1Normalized', 'change_10Normalized', 'comm_net_change_1_normalized' ]] X = sm.add_constant(X) params2 = sm.OLS(y, X).fit().params regress_forecast2 = params2['const']+\ params2['change_1Normalized']*test_data['change_1Normalized'].iloc[0]+\ params2['change_10Normalized']*test_data['change_10Normalized'].iloc[0]+\ params2['comm_net_change_1_normalized']*test_data['comm_net_change_1_normalized'].iloc[0] except: pass try: regress_input = training_data[[ 'change_1Normalized', 'change_10Normalized', 'change1_InstantNormalized', 'spec_net_change_1_normalized' ]].dropna() y = regress_input['change1_InstantNormalized'] X = regress_input[[ 'change_1Normalized', 'change_10Normalized', 'spec_net_change_1_normalized' ]] X = sm.add_constant(X) params3 = sm.OLS(y, X).fit().params regress_forecast3 = params3['const']+\ params3['change_1Normalized']*test_data['change_1Normalized'].iloc[0]+\ params3['change_10Normalized']*test_data['change_10Normalized'].iloc[0]+\ params3['spec_net_change_1_normalized']*test_data['spec_net_change_1_normalized'].iloc[0] except: pass regress_input = training_data[[ 'change_1Normalized', 'change_10Normalized', 'change1_InstantNormalized', 'comm_net_change_1_normalized' ]].dropna() try: svr_rbf1 = SVR(kernel='rbf', C=1, gamma=0.04) y = regress_input['change1_InstantNormalized'] X = regress_input[[ 'change_1Normalized', 'change_10Normalized', 'comm_net_change_1_normalized' ]] svr_forecast1 = svr_rbf1.fit(X, y).predict(test_data[[ 'change_1Normalized', 'change_10Normalized', 'comm_net_change_1_normalized' ]].values)[0] except: pass try: svr_rbf2 = SVR(kernel='rbf', C=50, gamma=0.04) y = regress_input['change1_InstantNormalized'] X = regress_input[[ 'change_1Normalized', 'change_10Normalized', 'comm_net_change_1_normalized' ]] svr_forecast2 = svr_rbf2.fit(X, y).predict(test_data[[ 'change_1Normalized', 'change_10Normalized', 'comm_net_change_1_normalized' ]].values)[0] except: pass if test_data['low1_InstantNormalized'].iloc[0] < -0.25: long_tight_stop_pnl1Instant = -0.25 else: long_tight_stop_pnl1Instant = test_data[ 'change1_InstantNormalized'].iloc[0] if test_data['low1_InstantNormalized'].iloc[0] < -0.5: long_loose_stop_pnl1Instant = -0.5 else: long_loose_stop_pnl1Instant = test_data[ 'change1_InstantNormalized'].iloc[0] if test_data['high1_InstantNormalized'].iloc[0] > 0.25: short_tight_stop_pnl1Instant = -0.25 else: short_tight_stop_pnl1Instant = -test_data[ 'change1_InstantNormalized'].iloc[0] if test_data['high1_InstantNormalized'].iloc[0] > 0.5: short_loose_stop_pnl1Instant = -0.5 else: short_loose_stop_pnl1Instant = -test_data[ 'change1_InstantNormalized'].iloc[0] dictionary_out['vote1'] = vote1 dictionary_out['vote1_instant'] = vote1_instant dictionary_out['vote12_instant'] = vote12_instant dictionary_out['vote13_instant'] = vote13_instant dictionary_out['vote5'] = vote5 dictionary_out['vote10'] = vote10 dictionary_out['vote20'] = vote20 dictionary_out['regress_forecast1'] = regress_forecast1 dictionary_out['regress_forecast2'] = regress_forecast2 dictionary_out['regress_forecast3'] = regress_forecast3 dictionary_out['svr_forecast1'] = svr_forecast1 dictionary_out['svr_forecast2'] = svr_forecast2 dictionary_out['norm_pnl1'] = test_data['change1Normalized'].iloc[0] dictionary_out['norm_pnl1Instant'] = test_data[ 'change1_InstantNormalized'].iloc[0] dictionary_out['long_tight_stop_pnl1Instant'] = long_tight_stop_pnl1Instant dictionary_out['long_loose_stop_pnl1Instant'] = long_loose_stop_pnl1Instant dictionary_out[ 'short_tight_stop_pnl1Instant'] = short_tight_stop_pnl1Instant dictionary_out[ 'short_loose_stop_pnl1Instant'] = short_loose_stop_pnl1Instant dictionary_out['norm_pnl5'] = test_data['change5Normalized'].iloc[0] dictionary_out['norm_pnl10'] = test_data['change10Normalized'].iloc[0] dictionary_out['norm_pnl20'] = test_data['change20Normalized'].iloc[0] dictionary_out['rolling_data'] = rolling_data for ind in indicator_list: dictionary_out[ind] = test_data[ind].iloc[0] return dictionary_out
def get_futures_butterfly_signals(**kwargs): ticker_list = kwargs['ticker_list'] date_to = kwargs['date_to'] if 'tr_dte_list' in kwargs.keys(): tr_dte_list = kwargs['tr_dte_list'] else: tr_dte_list = [exp.get_futures_days2_expiration({'ticker': x,'date_to': date_to}) for x in ticker_list] if 'aggregation_method' in kwargs.keys() and 'contracts_back' in kwargs.keys(): aggregation_method = kwargs['aggregation_method'] contracts_back = kwargs['contracts_back'] else: amcb_output = opUtil.get_aggregation_method_contracts_back(cmi.get_contract_specs(ticker_list[0])) aggregation_method = amcb_output['aggregation_method'] contracts_back = amcb_output['contracts_back'] if 'use_last_as_current' in kwargs.keys(): use_last_as_current = kwargs['use_last_as_current'] else: use_last_as_current = False if 'futures_data_dictionary' in kwargs.keys(): futures_data_dictionary = kwargs['futures_data_dictionary'] else: futures_data_dictionary = {x: gfp.get_futures_price_preloaded(ticker_head=x) for x in [cmi.get_contract_specs(ticker_list[0])['ticker_head']]} if 'contract_multiplier' in kwargs.keys(): contract_multiplier = kwargs['contract_multiplier'] else: contract_multiplier = cmi.contract_multiplier[cmi.get_contract_specs(ticker_list[0])['ticker_head']] if 'datetime5_years_ago' in kwargs.keys(): datetime5_years_ago = kwargs['datetime5_years_ago'] else: date5_years_ago = cu.doubledate_shift(date_to,5*365) datetime5_years_ago = cu.convert_doubledate_2datetime(date5_years_ago) if 'datetime2_months_ago' in kwargs.keys(): datetime2_months_ago = kwargs['datetime2_months_ago'] else: date2_months_ago = cu.doubledate_shift(date_to,60) datetime2_months_ago = cu.convert_doubledate_2datetime(date2_months_ago) aligned_output = opUtil.get_aligned_futures_data(contract_list=ticker_list, tr_dte_list=tr_dte_list, aggregation_method=aggregation_method, contracts_back=contracts_back, date_to=date_to, futures_data_dictionary=futures_data_dictionary, use_last_as_current=use_last_as_current) current_data = aligned_output['current_data'] aligned_data = aligned_output['aligned_data'] month_diff_1 = 12*(current_data['c1']['ticker_year']-current_data['c2']['ticker_year'])+(current_data['c1']['ticker_month']-current_data['c2']['ticker_month']) month_diff_2 = 12*(current_data['c2']['ticker_year']-current_data['c3']['ticker_year'])+(current_data['c2']['ticker_month']-current_data['c3']['ticker_month']) weight_11 = 2*month_diff_2/(month_diff_1+month_diff_1) weight_12 = -2 weight_13 = 2*month_diff_1/(month_diff_1+month_diff_1) price_1 = current_data['c1']['close_price'] price_2 = current_data['c2']['close_price'] price_3 = current_data['c3']['close_price'] linear_interp_price2 = (weight_11*aligned_data['c1']['close_price']+weight_13*aligned_data['c3']['close_price'])/2 butterfly_price = aligned_data['c1']['close_price']-2*aligned_data['c2']['close_price']+aligned_data['c3']['close_price'] price_ratio = linear_interp_price2/aligned_data['c2']['close_price'] linear_interp_price2_current = (weight_11*price_1+weight_13*price_3)/2 price_ratio_current = linear_interp_price2_current/price_2 q = stats.get_quantile_from_number({'x': price_ratio_current, 'y': price_ratio.values, 'clean_num_obs': max(100, round(3*len(price_ratio.values)/4))}) qf = stats.get_quantile_from_number({'x': price_ratio_current, 'y': price_ratio.values[-40:], 'clean_num_obs': 30}) recent_quantile_list = [stats.get_quantile_from_number({'x': x, 'y': price_ratio.values[-40:], 'clean_num_obs': 30}) for x in price_ratio.values[-40:]] weight1 = weight_11 weight2 = weight_12 weight3 = weight_13 last5_years_indx = aligned_data['settle_date']>=datetime5_years_ago last2_months_indx = aligned_data['settle_date']>=datetime2_months_ago data_last5_years = aligned_data[last5_years_indx] yield1 = 100*(aligned_data['c1']['close_price']-aligned_data['c2']['close_price'])/aligned_data['c2']['close_price'] yield2 = 100*(aligned_data['c2']['close_price']-aligned_data['c3']['close_price'])/aligned_data['c3']['close_price'] yield1_last5_years = yield1[last5_years_indx] yield2_last5_years = yield2[last5_years_indx] yield1_current = 100*(current_data['c1']['close_price']-current_data['c2']['close_price'])/current_data['c2']['close_price'] yield2_current = 100*(current_data['c2']['close_price']-current_data['c3']['close_price'])/current_data['c3']['close_price'] butterfly_price_current = current_data['c1']['close_price']\ -2*current_data['c2']['close_price']\ +current_data['c3']['close_price'] yield_regress_output = stats.get_regression_results({'x':yield2, 'y':yield1,'x_current': yield2_current, 'y_current': yield1_current, 'clean_num_obs': max(100, round(3*len(yield1.values)/4))}) yield_regress_output_last5_years = stats.get_regression_results({'x':yield2_last5_years, 'y':yield1_last5_years, 'x_current': yield2_current, 'y_current': yield1_current, 'clean_num_obs': max(100, round(3*len(yield1_last5_years.values)/4))}) bf_qz_frame_short = pd.DataFrame() bf_qz_frame_long = pd.DataFrame() if (len(yield1) >= 40)&(len(yield2) >= 40): recent_zscore_list = [(yield1[-40+i]-yield_regress_output['alpha']-yield_regress_output['beta']*yield2[-40+i])/yield_regress_output['residualstd'] for i in range(40)] bf_qz_frame = pd.DataFrame.from_items([('bf_price', butterfly_price.values[-40:]), ('q',recent_quantile_list), ('zscore', recent_zscore_list)]) bf_qz_frame = np.round(bf_qz_frame, 8) bf_qz_frame.drop_duplicates(['bf_price'], take_last=True, inplace=True) # return bf_qz_frame bf_qz_frame_short = bf_qz_frame[(bf_qz_frame['zscore'] >= 0.6) & (bf_qz_frame['q'] >= 85)] bf_qz_frame_long = bf_qz_frame[(bf_qz_frame['zscore'] <= -0.6) & (bf_qz_frame['q'] <= 12)] if bf_qz_frame_short.empty: short_price_limit = np.NAN else: short_price_limit = bf_qz_frame_short['bf_price'].min() if bf_qz_frame_long.empty: long_price_limit = np.NAN else: long_price_limit = bf_qz_frame_long['bf_price'].max() zscore1= yield_regress_output['zscore'] rsquared1= yield_regress_output['rsquared'] zscore2= yield_regress_output_last5_years['zscore'] rsquared2= yield_regress_output_last5_years['rsquared'] second_spread_weight_1 = yield_regress_output['beta'] second_spread_weight_2 = yield_regress_output_last5_years['beta'] butterfly_5_change = data_last5_years['c1']['change_5']\ - (1+second_spread_weight_1)*data_last5_years['c2']['change_5']\ + second_spread_weight_1*data_last5_years['c3']['change_5'] butterfly_5_change_current = current_data['c1']['change_5']\ - (1+second_spread_weight_1)*current_data['c2']['change_5']\ + second_spread_weight_1*current_data['c3']['change_5'] butterfly_1_change = data_last5_years['c1']['change_1']\ - (1+second_spread_weight_1)*data_last5_years['c2']['change_1']\ + second_spread_weight_1*data_last5_years['c3']['change_1'] percentile_vector = stats.get_number_from_quantile(y=butterfly_5_change.values, quantile_list=[1, 15, 85, 99], clean_num_obs=max(100, round(3*len(butterfly_5_change.values)/4))) downside = contract_multiplier*(percentile_vector[0]+percentile_vector[1])/2 upside = contract_multiplier*(percentile_vector[2]+percentile_vector[3])/2 recent_5day_pnl = contract_multiplier*butterfly_5_change_current residuals = yield1-yield_regress_output['alpha']-yield_regress_output['beta']*yield2 regime_change_ind = (residuals[last5_years_indx].mean()-residuals.mean())/residuals.std() contract_seasonality_ind = (residuals[aligned_data['c1']['ticker_month'] == current_data['c1']['ticker_month']].mean()-residuals.mean())/residuals.std() yield1_quantile_list = stats.get_number_from_quantile(y=yield1, quantile_list=[10, 90]) yield2_quantile_list = stats.get_number_from_quantile(y=yield2, quantile_list=[10, 90]) noise_ratio = (yield1_quantile_list[1]-yield1_quantile_list[0])/(yield2_quantile_list[1]-yield2_quantile_list[0]) daily_noise_recent = stats.get_stdev(x=butterfly_1_change.values[-20:], clean_num_obs=15) daily_noise_past = stats.get_stdev(x=butterfly_1_change.values, clean_num_obs=max(100, round(3*len(butterfly_1_change.values)/4))) recent_vol_ratio = daily_noise_recent/daily_noise_past alpha1 = yield_regress_output['alpha'] residuals_last5_years = residuals[last5_years_indx] residuals_last2_months = residuals[last2_months_indx] residual_current = yield1_current-alpha1-second_spread_weight_1*yield2_current z3 = (residual_current-residuals_last5_years.mean())/residuals.std() z4 = (residual_current-residuals_last2_months.mean())/residuals.std() yield_change = (alpha1+second_spread_weight_1*yield2_current-yield1_current)/(1+second_spread_weight_1) new_yield1 = yield1_current + yield_change new_yield2 = yield2_current - yield_change price_change1 = 100*((price_2*(new_yield1+100)/100)-price_1)/(200+new_yield1) price_change2 = 100*((price_3*(new_yield2+100)/100)-price_2)/(200+new_yield2) theo_pnl = contract_multiplier*(2*price_change1-2*second_spread_weight_1*price_change2) aligned_data['residuals'] = residuals aligned_output['aligned_data'] = aligned_data grouped = aligned_data.groupby(aligned_data['c1']['cont_indx']) aligned_data['shifted_residuals'] = grouped['residuals'].shift(-5) aligned_data['residual_change'] = aligned_data['shifted_residuals']-aligned_data['residuals'] mean_reversion = stats.get_regression_results({'x':aligned_data['residuals'].values, 'y':aligned_data['residual_change'].values, 'clean_num_obs': max(100, round(3*len(yield1.values)/4))}) theo_spread_move_output = su.calc_theo_spread_move_from_ratio_normalization(ratio_time_series=price_ratio.values[-40:], starting_quantile=qf, num_price=linear_interp_price2_current, den_price=current_data['c2']['close_price'], favorable_quantile_move_list=[5, 10, 15, 20, 25]) theo_pnl_list = [x*contract_multiplier*2 for x in theo_spread_move_output['theo_spread_move_list']] return {'aligned_output': aligned_output, 'q': q, 'qf': qf, 'theo_pnl_list': theo_pnl_list, 'ratio_target_list': theo_spread_move_output['ratio_target_list'], 'weight1': weight1, 'weight2': weight2, 'weight3': weight3, 'zscore1': zscore1, 'rsquared1': rsquared1, 'zscore2': zscore2, 'rsquared2': rsquared2, 'zscore3': z3, 'zscore4': z4, 'zscore5': zscore1-regime_change_ind, 'zscore6': zscore1-contract_seasonality_ind, 'zscore7': zscore1-regime_change_ind-contract_seasonality_ind, 'theo_pnl': theo_pnl, 'regime_change_ind' : regime_change_ind,'contract_seasonality_ind': contract_seasonality_ind, 'second_spread_weight_1': second_spread_weight_1, 'second_spread_weight_2': second_spread_weight_2, 'downside': downside, 'upside': upside, 'yield1': yield1, 'yield2': yield2, 'yield1_current': yield1_current, 'yield2_current': yield2_current, 'bf_price': butterfly_price_current, 'short_price_limit': short_price_limit,'long_price_limit':long_price_limit, 'noise_ratio': noise_ratio, 'alpha1': alpha1, 'alpha2': yield_regress_output_last5_years['alpha'], 'residual_std1': yield_regress_output['residualstd'], 'residual_std2': yield_regress_output_last5_years['residualstd'], 'recent_vol_ratio': recent_vol_ratio, 'recent_5day_pnl': recent_5day_pnl, 'price_1': price_1, 'price_2': price_2, 'price_3': price_3, 'last5_years_indx': last5_years_indx, 'price_ratio': price_ratio, 'mean_reversion_rsquared': mean_reversion['rsquared'], 'mean_reversion_signif' : (mean_reversion['conf_int'][1, :] < 0).all()}
def get_futures_spread_carry_signals(**kwargs): ticker_list = kwargs['ticker_list'] date_to = kwargs['date_to'] if 'tr_dte_list' in kwargs.keys(): tr_dte_list = kwargs['tr_dte_list'] else: tr_dte_list = [exp.get_futures_days2_expiration({'ticker': x,'date_to': date_to}) for x in ticker_list] if 'aggregation_method' in kwargs.keys() and 'contracts_back' in kwargs.keys(): aggregation_method = kwargs['aggregation_method'] contracts_back = kwargs['contracts_back'] else: amcb_output = opUtil.get_aggregation_method_contracts_back(cmi.get_contract_specs(ticker_list[0])) aggregation_method = amcb_output['aggregation_method'] contracts_back = amcb_output['contracts_back'] if 'use_last_as_current' in kwargs.keys(): use_last_as_current = kwargs['use_last_as_current'] else: use_last_as_current = False if 'futures_data_dictionary' in kwargs.keys(): futures_data_dictionary = kwargs['futures_data_dictionary'] else: futures_data_dictionary = {x: gfp.get_futures_price_preloaded(ticker_head=x) for x in [cmi.get_contract_specs(ticker_list[0])['ticker_head']]} if 'contract_multiplier' in kwargs.keys(): contract_multiplier = kwargs['contract_multiplier'] else: contract_multiplier = cmi.contract_multiplier[cmi.get_contract_specs(ticker_list[0])['ticker_head']] if 'datetime5_years_ago' in kwargs.keys(): datetime5_years_ago = kwargs['datetime5_years_ago'] else: date5_years_ago = cu.doubledate_shift(date_to,5*365) datetime5_years_ago = cu.convert_doubledate_2datetime(date5_years_ago) if 'datetime2_months_ago' in kwargs.keys(): datetime2_months_ago = kwargs['datetime2_months_ago'] else: date2_months_ago = cu.doubledate_shift(date_to,60) datetime2_months_ago = cu.convert_doubledate_2datetime(date2_months_ago) aligned_output = opUtil.get_aligned_futures_data(contract_list=ticker_list, tr_dte_list=tr_dte_list, aggregation_method=aggregation_method, contracts_back=contracts_back, date_to=date_to, futures_data_dictionary=futures_data_dictionary, use_last_as_current=use_last_as_current) aligned_data = aligned_output['aligned_data'] current_data = aligned_output['current_data'] last5_years_indx = aligned_data['settle_date']>=datetime5_years_ago data_last5_years = aligned_data[last5_years_indx] ticker1_list = [current_data['c' + str(x+1)]['ticker'] for x in range(len(ticker_list)-1)] ticker2_list = [current_data['c' + str(x+2)]['ticker'] for x in range(len(ticker_list)-1)] yield_current_list = [100*(current_data['c' + str(x+1)]['close_price']- current_data['c' + str(x+2)]['close_price'])/ current_data['c' + str(x+2)]['close_price'] for x in range(len(ticker_list)-1)] price_current_list = [current_data['c' + str(x+1)]['close_price']-current_data['c' + str(x+2)]['close_price'] for x in range(len(ticker_list)-1)] yield_history = [100*(aligned_data['c' + str(x+1)]['close_price']- aligned_data['c' + str(x+2)]['close_price'])/ aligned_data['c' + str(x+2)]['close_price'] for x in range(len(ticker_list)-1)] change_5_history = [data_last5_years['c' + str(x+1)]['change_5']- data_last5_years['c' + str(x+2)]['change_5'] for x in range(len(ticker_list)-1)] change5 = [contract_multiplier*(current_data['c' + str(x+1)]['change5']- current_data['c' + str(x+2)]['change5']) for x in range(len(ticker_list)-1)] change10 = [contract_multiplier*(current_data['c' + str(x+1)]['change10']- current_data['c' + str(x+2)]['change10']) for x in range(len(ticker_list)-1)] change20 = [contract_multiplier*(current_data['c' + str(x+1)]['change20']- current_data['c' + str(x+2)]['change20']) for x in range(len(ticker_list)-1)] front_tr_dte = [current_data['c' + str(x+1)]['tr_dte'] for x in range(len(ticker_list)-1)] q_list = [stats.get_quantile_from_number({'x': yield_current_list[x], 'y': yield_history[x].values, 'clean_num_obs': max(100, round(3*len(yield_history[x].values)/4))}) for x in range(len(ticker_list)-1)] percentile_vector = [stats.get_number_from_quantile(y=change_5_history[x].values, quantile_list=[1, 15, 85, 99], clean_num_obs=max(100, round(3*len(change_5_history[x].values)/4))) for x in range(len(ticker_list)-1)] q1 = [x[0] for x in percentile_vector] q15 = [x[1] for x in percentile_vector] q85 = [x[2] for x in percentile_vector] q99 = [x[3] for x in percentile_vector] downside = [contract_multiplier*(q1[x]+q15[x])/2 for x in range(len(q1))] upside = [contract_multiplier*(q85[x]+q99[x])/2 for x in range(len(q1))] carry = [contract_multiplier*(price_current_list[x]-price_current_list[x+1]) for x in range(len(q_list)-1)] q_carry = [q_list[x]-q_list[x+1] for x in range(len(q_list)-1)] reward_risk = [5*carry[x]/((front_tr_dte[x+1]-front_tr_dte[x])*abs(downside[x+1])) if carry[x]>0 else 5*carry[x]/((front_tr_dte[x+1]-front_tr_dte[x])*upside[x+1]) for x in range(len(carry))] return pd.DataFrame.from_items([('ticker1',ticker1_list), ('ticker2',ticker2_list), ('ticker_head',cmi.get_contract_specs(ticker_list[0])['ticker_head']), ('front_tr_dte',front_tr_dte), ('carry',[np.NAN]+carry), ('q_carry',[np.NAN]+q_carry), ('reward_risk',[np.NAN]+reward_risk), ('price',price_current_list), ('q',q_list), ('upside',upside), ('downside',downside), ('change5',change5), ('change10',change10), ('change20',change20)])
def get_futures_spread_carry_signals(**kwargs): ticker_list = kwargs['ticker_list'] date_to = kwargs['date_to'] if 'tr_dte_list' in kwargs.keys(): tr_dte_list = kwargs['tr_dte_list'] else: tr_dte_list = [ exp.get_futures_days2_expiration({ 'ticker': x, 'date_to': date_to }) for x in ticker_list ] if 'aggregation_method' in kwargs.keys( ) and 'contracts_back' in kwargs.keys(): aggregation_method = kwargs['aggregation_method'] contracts_back = kwargs['contracts_back'] else: amcb_output = opUtil.get_aggregation_method_contracts_back( cmi.get_contract_specs(ticker_list[0])) aggregation_method = amcb_output['aggregation_method'] contracts_back = amcb_output['contracts_back'] if 'use_last_as_current' in kwargs.keys(): use_last_as_current = kwargs['use_last_as_current'] else: use_last_as_current = False if 'futures_data_dictionary' in kwargs.keys(): futures_data_dictionary = kwargs['futures_data_dictionary'] else: futures_data_dictionary = { x: gfp.get_futures_price_preloaded(ticker_head=x) for x in [cmi.get_contract_specs(ticker_list[0])['ticker_head']] } if 'contract_multiplier' in kwargs.keys(): contract_multiplier = kwargs['contract_multiplier'] else: contract_multiplier = cmi.contract_multiplier[cmi.get_contract_specs( ticker_list[0])['ticker_head']] if 'datetime5_years_ago' in kwargs.keys(): datetime5_years_ago = kwargs['datetime5_years_ago'] else: date5_years_ago = cu.doubledate_shift(date_to, 5 * 365) datetime5_years_ago = cu.convert_doubledate_2datetime(date5_years_ago) aligned_output = opUtil.get_aligned_futures_data( contract_list=ticker_list, tr_dte_list=tr_dte_list, aggregation_method=aggregation_method, contracts_back=contracts_back, date_to=date_to, futures_data_dictionary=futures_data_dictionary, use_last_as_current=use_last_as_current) aligned_data = aligned_output['aligned_data'] current_data = aligned_output['current_data'] last5_years_indx = aligned_data['settle_date'] >= datetime5_years_ago data_last5_years = aligned_data[last5_years_indx] ticker1_list = [ current_data['c' + str(x + 1)]['ticker'] for x in range(len(ticker_list) - 1) ] ticker2_list = [ current_data['c' + str(x + 2)]['ticker'] for x in range(len(ticker_list) - 1) ] yield_current_list = [ 100 * (current_data['c' + str(x + 1)]['close_price'] - current_data['c' + str(x + 2)]['close_price']) / current_data['c' + str(x + 2)]['close_price'] for x in range(len(ticker_list) - 1) ] butterfly_current_list = [ 100 * (current_data['c' + str(x + 1)]['close_price'] - 2 * current_data['c' + str(x + 2)]['close_price'] + current_data['c' + str(x + 3)]['close_price']) / current_data['c' + str(x + 2)]['close_price'] for x in range(len(ticker_list) - 2) ] price_current_list = [ current_data['c' + str(x + 1)]['close_price'] - current_data['c' + str(x + 2)]['close_price'] for x in range(len(ticker_list) - 1) ] yield_history = [ 100 * (aligned_data['c' + str(x + 1)]['close_price'] - aligned_data['c' + str(x + 2)]['close_price']) / aligned_data['c' + str(x + 2)]['close_price'] for x in range(len(ticker_list) - 1) ] butterfly_history = [ 100 * (aligned_data['c' + str(x + 1)]['close_price'] - 2 * aligned_data['c' + str(x + 2)]['close_price'] + aligned_data['c' + str(x + 3)]['close_price']) / aligned_data['c' + str(x + 2)]['close_price'] for x in range(len(ticker_list) - 2) ] change_5_history = [ data_last5_years['c' + str(x + 1)]['change_5'] - data_last5_years['c' + str(x + 2)]['change_5'] for x in range(len(ticker_list) - 1) ] change5 = [ contract_multiplier * (current_data['c' + str(x + 1)]['change5'] - current_data['c' + str(x + 2)]['change5']) for x in range(len(ticker_list) - 1) ] change10 = [ contract_multiplier * (current_data['c' + str(x + 1)]['change10'] - current_data['c' + str(x + 2)]['change10']) for x in range(len(ticker_list) - 1) ] change20 = [ contract_multiplier * (current_data['c' + str(x + 1)]['change20'] - current_data['c' + str(x + 2)]['change20']) for x in range(len(ticker_list) - 1) ] front_tr_dte = [ current_data['c' + str(x + 1)]['tr_dte'] for x in range(len(ticker_list) - 1) ] q_list = [ stats.get_quantile_from_number({ 'x': yield_current_list[x], 'y': yield_history[x].values, 'clean_num_obs': max(100, round(3 * len(yield_history[x].values) / 4)) }) for x in range(len(ticker_list) - 1) ] butterfly_q_list = [ stats.get_quantile_from_number({ 'x': butterfly_current_list[x], 'y': butterfly_history[x].values[-40:], 'clean_num_obs': round(3 * len(butterfly_history[x].values[-40:]) / 4) }) for x in range(len(ticker_list) - 2) ] extreme_quantiles_list = [ stats.get_number_from_quantile( y=x.values[:-40], quantile_list=[10, 25, 35, 50, 65, 75, 90]) for x in butterfly_history ] butterfly_q10 = [x[0] for x in extreme_quantiles_list] butterfly_q25 = [x[1] for x in extreme_quantiles_list] butterfly_q35 = [x[2] for x in extreme_quantiles_list] butterfly_q50 = [x[3] for x in extreme_quantiles_list] butterfly_q65 = [x[4] for x in extreme_quantiles_list] butterfly_q75 = [x[5] for x in extreme_quantiles_list] butterfly_q90 = [x[6] for x in extreme_quantiles_list] butterfly_noise_list = [ stats.get_stdev(x=butterfly_history[i].values[-20:]) for i in range(len(ticker_list) - 2) ] butterfly_mean_list = [ stats.get_mean(x=butterfly_history[i].values[-10:]) for i in range(len(ticker_list) - 2) ] butterfly_z_list = [(butterfly_current_list[i] - butterfly_mean_list[i]) / butterfly_noise_list[i] for i in range(len(ticker_list) - 2)] percentile_vector = [ stats.get_number_from_quantile( y=change_5_history[x].values, quantile_list=[1, 15, 85, 99], clean_num_obs=max(100, round(3 * len(change_5_history[x].values) / 4))) for x in range(len(ticker_list) - 1) ] q1 = [x[0] for x in percentile_vector] q15 = [x[1] for x in percentile_vector] q85 = [x[2] for x in percentile_vector] q99 = [x[3] for x in percentile_vector] downside = [ contract_multiplier * (q1[x] + q15[x]) / 2 for x in range(len(q1)) ] upside = [ contract_multiplier * (q85[x] + q99[x]) / 2 for x in range(len(q1)) ] carry = [ contract_multiplier * (price_current_list[x] - price_current_list[x + 1]) for x in range(len(q_list) - 1) ] q_carry = [q_list[x] - q_list[x + 1] for x in range(len(q_list) - 1)] q_average = np.cumsum(q_list) / range(1, len(q_list) + 1) q_series = pd.Series(q_list) q_min = q_series.cummin().values q_max = q_series.cummax().values q_carry_average = [ q_average[x] - q_list[x + 1] for x in range(len(q_list) - 1) ] q_carry_max = [q_max[x] - q_list[x + 1] for x in range(len(q_list) - 1)] q_carry_min = [q_min[x] - q_list[x + 1] for x in range(len(q_list) - 1)] reward_risk = [ 5 * carry[x] / ((front_tr_dte[x + 1] - front_tr_dte[x]) * abs(downside[x + 1])) if carry[x] > 0 else 5 * carry[x] / ((front_tr_dte[x + 1] - front_tr_dte[x]) * upside[x + 1]) for x in range(len(carry)) ] return pd.DataFrame.from_dict({ 'ticker1': ticker1_list, 'ticker2': ticker2_list, 'ticker1L': [''] + ticker1_list[:-1], 'ticker2L': [''] + ticker2_list[:-1], 'ticker_head': cmi.get_contract_specs(ticker_list[0])['ticker_head'], 'front_tr_dte': front_tr_dte, 'front_tr_dteL': [np.NAN] + front_tr_dte[:-1], 'carry': [np.NAN] + carry, 'q_carry': [np.NAN] + q_carry, 'q_carry_average': [np.NAN] + q_carry_average, 'q_carry_max': [np.NAN] + q_carry_max, 'q_carry_min': [np.NAN] + q_carry_min, 'butterfly_q': [np.NAN] + butterfly_q_list, 'butterfly_z': [np.NAN] + butterfly_z_list, 'reward_risk': [np.NAN] + reward_risk, 'price': price_current_list, 'priceL': [np.NAN] + price_current_list[:-1], 'butterfly_q10': [np.NAN] + butterfly_q10, 'butterfly_q25': [np.NAN] + butterfly_q25, 'butterfly_q35': [np.NAN] + butterfly_q35, 'butterfly_q50': [np.NAN] + butterfly_q50, 'butterfly_q65': [np.NAN] + butterfly_q65, 'butterfly_q75': [np.NAN] + butterfly_q75, 'butterfly_q90': [np.NAN] + butterfly_q90, 'butterfly_mean': [np.NAN] + butterfly_mean_list, 'butterfly_noise': [np.NAN] + butterfly_noise_list, 'q': q_list, 'upside': upside, 'downside': downside, 'upsideL': [np.NAN] + upside[:-1], 'downsideL': [np.NAN] + downside[:-1], 'change5': change5, 'change10': change10, 'change20': change20 })
def get_futures_butterfly_signals(**kwargs): ticker_list = kwargs['ticker_list'] date_to = kwargs['date_to'] if 'tr_dte_list' in kwargs.keys(): tr_dte_list = kwargs['tr_dte_list'] else: tr_dte_list = [ exp.get_futures_days2_expiration({ 'ticker': x, 'date_to': date_to }) for x in ticker_list ] if 'aggregation_method' in kwargs.keys( ) and 'contracts_back' in kwargs.keys(): aggregation_method = kwargs['aggregation_method'] contracts_back = kwargs['contracts_back'] else: amcb_output = opUtil.get_aggregation_method_contracts_back( cmi.get_contract_specs(ticker_list[0])) aggregation_method = amcb_output['aggregation_method'] contracts_back = amcb_output['contracts_back'] if 'use_last_as_current' in kwargs.keys(): use_last_as_current = kwargs['use_last_as_current'] else: use_last_as_current = False if 'futures_data_dictionary' in kwargs.keys(): futures_data_dictionary = kwargs['futures_data_dictionary'] else: futures_data_dictionary = { x: gfp.get_futures_price_preloaded(ticker_head=x) for x in [cmi.get_contract_specs(ticker_list[0])['ticker_head']] } if 'contract_multiplier' in kwargs.keys(): contract_multiplier = kwargs['contract_multiplier'] else: contract_multiplier = cmi.contract_multiplier[cmi.get_contract_specs( ticker_list[0])['ticker_head']] if 'datetime5_years_ago' in kwargs.keys(): datetime5_years_ago = kwargs['datetime5_years_ago'] else: date5_years_ago = cu.doubledate_shift(date_to, 5 * 365) datetime5_years_ago = cu.convert_doubledate_2datetime(date5_years_ago) if 'datetime2_months_ago' in kwargs.keys(): datetime2_months_ago = kwargs['datetime2_months_ago'] else: date2_months_ago = cu.doubledate_shift(date_to, 60) datetime2_months_ago = cu.convert_doubledate_2datetime( date2_months_ago) aligned_output = opUtil.get_aligned_futures_data( contract_list=ticker_list, tr_dte_list=tr_dte_list, aggregation_method=aggregation_method, contracts_back=contracts_back, date_to=date_to, futures_data_dictionary=futures_data_dictionary, use_last_as_current=use_last_as_current) if not aligned_output['success']: return {'success': False} current_data = aligned_output['current_data'] aligned_data = aligned_output['aligned_data'] month_diff_1 = 12 * (current_data['c1']['ticker_year'] - current_data['c2']['ticker_year']) + ( current_data['c1']['ticker_month'] - current_data['c2']['ticker_month']) month_diff_2 = 12 * (current_data['c2']['ticker_year'] - current_data['c3']['ticker_year']) + ( current_data['c2']['ticker_month'] - current_data['c3']['ticker_month']) weight_11 = 2 * month_diff_2 / (month_diff_1 + month_diff_1) weight_12 = -2 weight_13 = 2 * month_diff_1 / (month_diff_1 + month_diff_1) price_1 = current_data['c1']['close_price'] price_2 = current_data['c2']['close_price'] price_3 = current_data['c3']['close_price'] linear_interp_price2 = (weight_11 * aligned_data['c1']['close_price'] + weight_13 * aligned_data['c3']['close_price']) / 2 butterfly_price = aligned_data['c1']['close_price'] - 2 * aligned_data[ 'c2']['close_price'] + aligned_data['c3']['close_price'] price_ratio = linear_interp_price2 / aligned_data['c2']['close_price'] linear_interp_price2_current = (weight_11 * price_1 + weight_13 * price_3) / 2 price_ratio_current = linear_interp_price2_current / price_2 q = stats.get_quantile_from_number({ 'x': price_ratio_current, 'y': price_ratio.values, 'clean_num_obs': max(100, round(3 * len(price_ratio.values) / 4)) }) qf = stats.get_quantile_from_number({ 'x': price_ratio_current, 'y': price_ratio.values[-40:], 'clean_num_obs': 30 }) recent_quantile_list = [ stats.get_quantile_from_number({ 'x': x, 'y': price_ratio.values[-40:], 'clean_num_obs': 30 }) for x in price_ratio.values[-40:] ] weight1 = weight_11 weight2 = weight_12 weight3 = weight_13 last5_years_indx = aligned_data['settle_date'] >= datetime5_years_ago last2_months_indx = aligned_data['settle_date'] >= datetime2_months_ago data_last5_years = aligned_data[last5_years_indx] yield1 = 100 * ( aligned_data['c1']['close_price'] - aligned_data['c2']['close_price']) / aligned_data['c2']['close_price'] yield2 = 100 * ( aligned_data['c2']['close_price'] - aligned_data['c3']['close_price']) / aligned_data['c3']['close_price'] yield1_last5_years = yield1[last5_years_indx] yield2_last5_years = yield2[last5_years_indx] yield1_current = 100 * ( current_data['c1']['close_price'] - current_data['c2']['close_price']) / current_data['c2']['close_price'] yield2_current = 100 * ( current_data['c2']['close_price'] - current_data['c3']['close_price']) / current_data['c3']['close_price'] butterfly_price_current = current_data['c1']['close_price']\ -2*current_data['c2']['close_price']\ +current_data['c3']['close_price'] #return {'yield1': yield1, 'yield2': yield2, 'yield1_current':yield1_current, 'yield2_current': yield2_current} yield_regress_output = stats.get_regression_results({ 'x': yield2, 'y': yield1, 'x_current': yield2_current, 'y_current': yield1_current, 'clean_num_obs': max(100, round(3 * len(yield1.values) / 4)) }) yield_regress_output_last5_years = stats.get_regression_results({ 'x': yield2_last5_years, 'y': yield1_last5_years, 'x_current': yield2_current, 'y_current': yield1_current, 'clean_num_obs': max(100, round(3 * len(yield1_last5_years.values) / 4)) }) bf_qz_frame_short = pd.DataFrame() bf_qz_frame_long = pd.DataFrame() if (len(yield1) >= 40) & (len(yield2) >= 40): recent_zscore_list = [ (yield1[-40 + i] - yield_regress_output['alpha'] - yield_regress_output['beta'] * yield2[-40 + i]) / yield_regress_output['residualstd'] for i in range(40) ] bf_qz_frame = pd.DataFrame.from_dict({ 'bf_price': butterfly_price.values[-40:], 'q': recent_quantile_list, 'zscore': recent_zscore_list }) bf_qz_frame = np.round(bf_qz_frame, 8) bf_qz_frame.drop_duplicates(['bf_price'], keep='last', inplace=True) # return bf_qz_frame bf_qz_frame_short = bf_qz_frame[(bf_qz_frame['zscore'] >= 0.6) & (bf_qz_frame['q'] >= 85)] bf_qz_frame_long = bf_qz_frame[(bf_qz_frame['zscore'] <= -0.6) & (bf_qz_frame['q'] <= 12)] if bf_qz_frame_short.empty: short_price_limit = np.NAN else: short_price_limit = bf_qz_frame_short['bf_price'].min() if bf_qz_frame_long.empty: long_price_limit = np.NAN else: long_price_limit = bf_qz_frame_long['bf_price'].max() zscore1 = yield_regress_output['zscore'] rsquared1 = yield_regress_output['rsquared'] zscore2 = yield_regress_output_last5_years['zscore'] rsquared2 = yield_regress_output_last5_years['rsquared'] second_spread_weight_1 = yield_regress_output['beta'] second_spread_weight_2 = yield_regress_output_last5_years['beta'] butterfly_5_change = data_last5_years['c1']['change_5']\ - (1+second_spread_weight_1)*data_last5_years['c2']['change_5']\ + second_spread_weight_1*data_last5_years['c3']['change_5'] butterfly_5_change_current = current_data['c1']['change_5']\ - (1+second_spread_weight_1)*current_data['c2']['change_5']\ + second_spread_weight_1*current_data['c3']['change_5'] butterfly_1_change = data_last5_years['c1']['change_1']\ - (1+second_spread_weight_1)*data_last5_years['c2']['change_1']\ + second_spread_weight_1*data_last5_years['c3']['change_1'] percentile_vector = stats.get_number_from_quantile( y=butterfly_5_change.values, quantile_list=[1, 15, 85, 99], clean_num_obs=max(100, round(3 * len(butterfly_5_change.values) / 4))) downside = contract_multiplier * (percentile_vector[0] + percentile_vector[1]) / 2 upside = contract_multiplier * (percentile_vector[2] + percentile_vector[3]) / 2 recent_5day_pnl = contract_multiplier * butterfly_5_change_current residuals = yield1 - yield_regress_output[ 'alpha'] - yield_regress_output['beta'] * yield2 regime_change_ind = (residuals[last5_years_indx].mean() - residuals.mean()) / residuals.std() seasonal_residuals = residuals[aligned_data['c1']['ticker_month'] == current_data['c1']['ticker_month']] seasonal_clean_residuals = seasonal_residuals[np.isfinite( seasonal_residuals)] clean_residuals = residuals[np.isfinite(residuals)] contract_seasonality_ind = ( seasonal_clean_residuals.mean() - clean_residuals.mean()) / clean_residuals.std() yield1_quantile_list = stats.get_number_from_quantile( y=yield1, quantile_list=[10, 90]) yield2_quantile_list = stats.get_number_from_quantile( y=yield2, quantile_list=[10, 90]) noise_ratio = (yield1_quantile_list[1] - yield1_quantile_list[0]) / ( yield2_quantile_list[1] - yield2_quantile_list[0]) daily_noise_recent = stats.get_stdev(x=butterfly_1_change.values[-20:], clean_num_obs=15) daily_noise_past = stats.get_stdev( x=butterfly_1_change.values, clean_num_obs=max(100, round(3 * len(butterfly_1_change.values) / 4))) recent_vol_ratio = daily_noise_recent / daily_noise_past alpha1 = yield_regress_output['alpha'] residuals_last5_years = residuals[last5_years_indx] residuals_last2_months = residuals[last2_months_indx] residual_current = yield1_current - alpha1 - second_spread_weight_1 * yield2_current z3 = (residual_current - residuals_last5_years.mean()) / residuals.std() z4 = (residual_current - residuals_last2_months.mean()) / residuals.std() yield_change = (alpha1 + second_spread_weight_1 * yield2_current - yield1_current) / (1 + second_spread_weight_1) new_yield1 = yield1_current + yield_change new_yield2 = yield2_current - yield_change price_change1 = 100 * ( (price_2 * (new_yield1 + 100) / 100) - price_1) / (200 + new_yield1) price_change2 = 100 * ( (price_3 * (new_yield2 + 100) / 100) - price_2) / (200 + new_yield2) theo_pnl = contract_multiplier * ( 2 * price_change1 - 2 * second_spread_weight_1 * price_change2) aligned_data['residuals'] = residuals aligned_output['aligned_data'] = aligned_data grouped = aligned_data.groupby(aligned_data['c1']['cont_indx']) aligned_data['shifted_residuals'] = grouped['residuals'].shift(-5) aligned_data['residual_change'] = aligned_data[ 'shifted_residuals'] - aligned_data['residuals'] mean_reversion = stats.get_regression_results({ 'x': aligned_data['residuals'].values, 'y': aligned_data['residual_change'].values, 'clean_num_obs': max(100, round(3 * len(yield1.values) / 4)) }) theo_spread_move_output = su.calc_theo_spread_move_from_ratio_normalization( ratio_time_series=price_ratio.values[-40:], starting_quantile=qf, num_price=linear_interp_price2_current, den_price=current_data['c2']['close_price'], favorable_quantile_move_list=[5, 10, 15, 20, 25]) theo_pnl_list = [ x * contract_multiplier * 2 for x in theo_spread_move_output['theo_spread_move_list'] ] return { 'success': True, 'aligned_output': aligned_output, 'q': q, 'qf': qf, 'theo_pnl_list': theo_pnl_list, 'ratio_target_list': theo_spread_move_output['ratio_target_list'], 'weight1': weight1, 'weight2': weight2, 'weight3': weight3, 'zscore1': zscore1, 'rsquared1': rsquared1, 'zscore2': zscore2, 'rsquared2': rsquared2, 'zscore3': z3, 'zscore4': z4, 'zscore5': zscore1 - regime_change_ind, 'zscore6': zscore1 - contract_seasonality_ind, 'zscore7': zscore1 - regime_change_ind - contract_seasonality_ind, 'theo_pnl': theo_pnl, 'regime_change_ind': regime_change_ind, 'contract_seasonality_ind': contract_seasonality_ind, 'second_spread_weight_1': second_spread_weight_1, 'second_spread_weight_2': second_spread_weight_2, 'downside': downside, 'upside': upside, 'yield1': yield1, 'yield2': yield2, 'yield1_current': yield1_current, 'yield2_current': yield2_current, 'bf_price': butterfly_price_current, 'short_price_limit': short_price_limit, 'long_price_limit': long_price_limit, 'noise_ratio': noise_ratio, 'alpha1': alpha1, 'alpha2': yield_regress_output_last5_years['alpha'], 'residual_std1': yield_regress_output['residualstd'], 'residual_std2': yield_regress_output_last5_years['residualstd'], 'recent_vol_ratio': recent_vol_ratio, 'recent_5day_pnl': recent_5day_pnl, 'price_1': price_1, 'price_2': price_2, 'price_3': price_3, 'last5_years_indx': last5_years_indx, 'price_ratio': price_ratio, 'mean_reversion_rsquared': mean_reversion['rsquared'], 'mean_reversion_signif': (mean_reversion['conf_int'][1, :] < 0).all() }
def get_historical_risk_4strategy(**kwargs): con = msu.get_my_sql_connection(**kwargs) alias = kwargs['alias'] #print(alias) if 'as_of_date' in kwargs.keys(): as_of_date = kwargs['as_of_date'] else: as_of_date = exp.doubledate_shift_bus_days() if 'datetime5_years_ago' in kwargs.keys(): datetime5_years_ago = kwargs['datetime5_years_ago'] else: date5_years_ago = cu.doubledate_shift(as_of_date,5*365) datetime5_years_ago = cu.convert_doubledate_2datetime(date5_years_ago) net_position = ts.get_net_position_4strategy_alias(alias=alias,con=con) net_position = net_position[net_position['instrument'] != 'O'] if 'con' not in kwargs.keys(): con.close() if net_position.empty: return {'downside': 0, 'pnl_5_change': []} amcb_output = [opUtil.get_aggregation_method_contracts_back(cmi.get_contract_specs(x)) for x in net_position['ticker']] aggregation_method = pd.DataFrame(amcb_output)['aggregation_method'].max() if aggregation_method == 12: contracts_back = const.annualContractsBack elif aggregation_method == 3: contracts_back = const.quarterlyContractsBack elif aggregation_method == 1: contracts_back = const.monthlyContractsBack aligned_output = opUtil.get_aligned_futures_data(contract_list=net_position['ticker'].values, aggregation_method=aggregation_method, contracts_back=contracts_back,date_to=as_of_date,**kwargs) aligned_data = aligned_output['aligned_data'] last5_years_indx = aligned_data['settle_date'] >= datetime5_years_ago data_last5_years = aligned_data[last5_years_indx] ticker_head_list = [cmi.get_contract_specs(x)['ticker_head'] for x in net_position['ticker']] contract_multiplier_list = [cmi.contract_multiplier[x] for x in ticker_head_list] pnl_5_change_list = [contract_multiplier_list[x]* net_position['qty'].iloc[x]* data_last5_years['c' + str(x+1)]['change_5'] for x in range(len(net_position.index))] pnl_5_change = sum(pnl_5_change_list) percentile_vector = stats.get_number_from_quantile(y=pnl_5_change.values, quantile_list=[1, 15], clean_num_obs=max(100, round(3*len(pnl_5_change.values)/4))) downside = (percentile_vector[0]+percentile_vector[1])/2 unique_ticker_head_list = list(set(ticker_head_list)) ticker_head_based_pnl_5_change = {x: sum([pnl_5_change_list[y] for y in range(len(ticker_head_list)) if ticker_head_list[y] == x]) for x in unique_ticker_head_list} return {'downside': downside, 'pnl_5_change': pnl_5_change,'ticker_head_based_pnl_5_change':ticker_head_based_pnl_5_change}
def get_vcs_signals(**kwargs): aligned_indicators_output = get_aligned_option_indicators(**kwargs) if not aligned_indicators_output['success']: return { 'hist': [], 'current': [], 'atm_vol_ratio': np.NaN, 'fwd_vol': np.NaN, 'downside': np.NaN, 'upside': np.NaN, 'real_vol_ratio': np.NaN, 'atm_real_vol_ratio': np.NaN, 'theta': np.NaN, 'q': np.NaN, 'q1': np.NaN, 'fwd_vol_q': np.NaN } hist = aligned_indicators_output['hist'] current = aligned_indicators_output['current'] settle_datetime = cu.convert_doubledate_2datetime(kwargs['settle_date']) settle_datetime_1year_back = settle_datetime - dt.timedelta(360) hist['atm_vol_ratio'] = hist['c1']['imp_vol'] / hist['c2']['imp_vol'] if 'atm_vol_ratio' in kwargs.keys(): atm_vol_ratio = kwargs['atm_vol_ratio'] else: atm_vol_ratio = current['imp_vol'][0] / current['imp_vol'][1] hist_1year = hist[hist.index >= settle_datetime_1year_back] q = stats.get_quantile_from_number({ 'x': atm_vol_ratio, 'y': hist['atm_vol_ratio'].to_numpy(), 'clean_num_obs': max(100, round(3 * len(hist.index) / 4)) }) q1 = stats.get_quantile_from_number({ 'x': atm_vol_ratio, 'y': hist_1year['atm_vol_ratio'].to_numpy(), 'clean_num_obs': max(50, round(3 * len(hist_1year.index) / 4)) }) fwd_var = hist['c2']['cal_dte'] * (hist['c2']['imp_vol']** 2) - hist['c1']['cal_dte'] * ( hist['c1']['imp_vol']**2) fwd_vol_sq = fwd_var / (hist['c2']['cal_dte'] - hist['c1']['cal_dte']) fwd_vol_adj = np.sign(fwd_vol_sq) * ((abs(fwd_vol_sq)).apply(np.sqrt)) hist['fwd_vol_adj'] = fwd_vol_adj fwd_var = current['cal_dte'][1] * (current['imp_vol'][1]** 2) - current['cal_dte'][0] * ( current['imp_vol'][0]**2) fwd_vol_sq = fwd_var / (current['cal_dte'][1] - current['cal_dte'][0]) fwd_vol_adj = np.sign(fwd_vol_sq) * (np.sqrt(abs(fwd_vol_sq))) fwd_vol_q = stats.get_quantile_from_number({ 'x': fwd_vol_adj, 'y': hist['fwd_vol_adj'].to_numpy(), 'clean_num_obs': max(100, round(3 * len(hist.index) / 4)) }) clean_indx = hist['c1']['profit5'].notnull() clean_data = hist[clean_indx] if clean_data.empty: downside = np.NaN upside = np.NaN else: last_available_align_date = clean_data.index[-1] clean_data = clean_data[clean_data.index >= last_available_align_date - dt.timedelta(5 * 365)] profit5 = clean_data['c1']['profit5'] - clean_data['c2']['profit5'] percentile_vector = stats.get_number_from_quantile( y=profit5.to_numpy(), quantile_list=[1, 15, 85, 99], clean_num_obs=max(100, round(3 * len(profit5.to_numpy()) / 4))) downside = (percentile_vector[0] + percentile_vector[1]) / 2 upside = (percentile_vector[2] + percentile_vector[3]) / 2 return { 'hist': hist, 'current': current, 'atm_vol_ratio': atm_vol_ratio, 'fwd_vol': fwd_vol_adj, 'downside': downside, 'upside': upside, 'real_vol_ratio': current['close2close_vol20'][0] / current['close2close_vol20'][1], 'atm_real_vol_ratio': current['imp_vol'][0] / current['close2close_vol20'][0], 'theta': current['theta'][1] - current['theta'][0], 'q': q, 'q1': q1, 'fwd_vol_q': fwd_vol_q }
def get_scv_signals(**kwargs): ticker = kwargs['ticker'] date_to = kwargs['date_to'] con = msu.get_my_sql_connection(**kwargs) if 'futures_data_dictionary' in kwargs.keys(): futures_data_dictionary = kwargs['futures_data_dictionary'] else: futures_data_dictionary = { x: gfp.get_futures_price_preloaded(ticker_head=x) for x in [cmi.get_contract_specs(ticker)['ticker_head']] } aligned_indicators_output = ops.get_aligned_option_indicators( ticker_list=[ticker], settle_date=date_to, con=con) if not aligned_indicators_output['success']: return { 'downside': np.NaN, 'upside': np.NaN, 'theta': np.NaN, 'realized_vol_forecast': np.NaN, 'real_vol20_current': np.NaN, 'imp_vol': np.NaN, 'imp_vol_premium': np.NaN, 'q': np.NaN } hist = aligned_indicators_output['hist'] current = aligned_indicators_output['current'] vcs_output = vcs.generate_vcs_sheet_4date(date_to=date_to, con=con) if 'con' not in kwargs.keys(): con.close() clean_indx = hist['c1']['profit5'].notnull() clean_data = hist[clean_indx] if clean_data.empty: downside = np.NaN upside = np.NaN else: last_available_align_date = clean_data.index[-1] clean_data = clean_data[clean_data.index >= last_available_align_date - dt.timedelta(5 * 365)] profit5 = clean_data['c1']['profit5'] percentile_vector = stats.get_number_from_quantile( y=profit5.values, quantile_list=[1, 15, 85, 99], clean_num_obs=max(100, round(3 * len(profit5.values) / 4))) downside = (percentile_vector[0] + percentile_vector[1]) / 2 upside = (percentile_vector[2] + percentile_vector[3]) / 2 realized_vol_output = rvue.forecast_realized_vol_until_expiration( ticker=ticker, futures_data_dictionary=futures_data_dictionary, date_to=date_to) realized_vol_forecast = realized_vol_output['realized_vol_forecast'] real_vol20_current = realized_vol_output['real_vol20_current'] imp_vol = current['imp_vol'][0] imp_vol_premium = 100 * (imp_vol - realized_vol_forecast) / imp_vol q = np.NaN if vcs_output['success']: vcs_pairs = vcs_output['vcs_pairs'] selected_pairs = vcs_pairs[vcs_pairs['ticker2'] == ticker] if not selected_pairs.empty: q = 100 - selected_pairs['Q'].mean() return { 'downside': downside, 'upside': upside, 'theta': current['theta'][0], 'realized_vol_forecast': realized_vol_forecast, 'real_vol20_current': real_vol20_current, 'imp_vol': imp_vol, 'imp_vol_premium': imp_vol_premium, 'q': q }
def get_intraday_spread_signals(**kwargs): ticker_list = kwargs['ticker_list'] date_to = kwargs['date_to'] ticker_list = [x for x in ticker_list if x is not None] ticker_head_list = [cmi.get_contract_specs(x)['ticker_head'] for x in ticker_list] ticker_class_list = [cmi.ticker_class[x] for x in ticker_head_list] print('-'.join(ticker_list)) if 'tr_dte_list' in kwargs.keys(): tr_dte_list = kwargs['tr_dte_list'] else: tr_dte_list = [exp.get_days2_expiration(ticker=x,date_to=date_to, instrument='futures')['tr_dte'] for x in ticker_list] weights_output = sutil.get_spread_weights_4contract_list(ticker_head_list=ticker_head_list) if 'aggregation_method' in kwargs.keys() and 'contracts_back' in kwargs.keys(): aggregation_method = kwargs['aggregation_method'] contracts_back = kwargs['contracts_back'] else: amcb_output = [opUtil.get_aggregation_method_contracts_back(cmi.get_contract_specs(x)) for x in ticker_list] aggregation_method = max([x['aggregation_method'] for x in amcb_output]) contracts_back = min([x['contracts_back'] for x in amcb_output]) if 'futures_data_dictionary' in kwargs.keys(): futures_data_dictionary = kwargs['futures_data_dictionary'] else: futures_data_dictionary = {x: gfp.get_futures_price_preloaded(ticker_head=x) for x in list(set(ticker_head_list))} if 'use_last_as_current' in kwargs.keys(): use_last_as_current = kwargs['use_last_as_current'] else: use_last_as_current = True if 'datetime5_years_ago' in kwargs.keys(): datetime5_years_ago = kwargs['datetime5_years_ago'] else: date5_years_ago = cu.doubledate_shift(date_to,5*365) datetime5_years_ago = cu.convert_doubledate_2datetime(date5_years_ago) if 'num_days_back_4intraday' in kwargs.keys(): num_days_back_4intraday = kwargs['num_days_back_4intraday'] else: num_days_back_4intraday = 5 contract_multiplier_list = [cmi.contract_multiplier[x] for x in ticker_head_list] aligned_output = opUtil.get_aligned_futures_data(contract_list=ticker_list, tr_dte_list=tr_dte_list, aggregation_method=aggregation_method, contracts_back=contracts_back, date_to=date_to, futures_data_dictionary=futures_data_dictionary, use_last_as_current=use_last_as_current) aligned_data = aligned_output['aligned_data'] current_data = aligned_output['current_data'] spread_weights = weights_output['spread_weights'] portfolio_weights = weights_output['portfolio_weights'] aligned_data['spread'] = 0 aligned_data['spread_pnl_1'] = 0 aligned_data['spread_pnl1'] = 0 spread_settle = 0 last5_years_indx = aligned_data['settle_date']>=datetime5_years_ago num_contracts = len(ticker_list) for i in range(num_contracts): aligned_data['spread'] = aligned_data['spread']+aligned_data['c' + str(i+1)]['close_price']*spread_weights[i] spread_settle = spread_settle + current_data['c' + str(i+1)]['close_price']*spread_weights[i] aligned_data['spread_pnl_1'] = aligned_data['spread_pnl_1']+aligned_data['c' + str(i+1)]['change_1']*portfolio_weights[i]*contract_multiplier_list[i] aligned_data['spread_pnl1'] = aligned_data['spread_pnl1']+aligned_data['c' + str(i+1)]['change1_instant']*portfolio_weights[i]*contract_multiplier_list[i] aligned_data['spread_normalized'] = aligned_data['spread']/aligned_data['c1']['close_price'] data_last5_years = aligned_data[last5_years_indx] percentile_vector = stats.get_number_from_quantile(y=data_last5_years['spread_pnl_1'].values, quantile_list=[1, 15, 85, 99], clean_num_obs=max(100, round(3*len(data_last5_years.index)/4))) downside = (percentile_vector[0]+percentile_vector[1])/2 upside = (percentile_vector[2]+percentile_vector[3])/2 date_list = [exp.doubledate_shift_bus_days(double_date=date_to,shift_in_days=x) for x in reversed(range(1,num_days_back_4intraday))] date_list.append(date_to) intraday_data = opUtil.get_aligned_futures_data_intraday(contract_list=ticker_list, date_list=date_list) intraday_data['time_stamp'] = [x.to_datetime() for x in intraday_data.index] intraday_data['settle_date'] = intraday_data['time_stamp'].apply(lambda x: x.date()) end_hour = min([cmi.last_trade_hour_minute[x] for x in ticker_head_list]) start_hour = max([cmi.first_trade_hour_minute[x] for x in ticker_head_list]) trade_start_hour = dt.time(9, 30, 0, 0) if 'Ag' in ticker_class_list: start_hour1 = dt.time(0, 45, 0, 0) end_hour1 = dt.time(7, 45, 0, 0) selection_indx = [x for x in range(len(intraday_data.index)) if ((intraday_data['time_stamp'].iloc[x].time() < end_hour1) and(intraday_data['time_stamp'].iloc[x].time() >= start_hour1)) or ((intraday_data['time_stamp'].iloc[x].time() < end_hour) and(intraday_data['time_stamp'].iloc[x].time() >= start_hour))] else: selection_indx = [x for x in range(len(intraday_data.index)) if (intraday_data.index[x].to_datetime().time() < end_hour) and(intraday_data.index[x].to_datetime().time() >= start_hour)] intraday_data = intraday_data.iloc[selection_indx] intraday_data['spread'] = 0 for i in range(num_contracts): intraday_data['c' + str(i+1), 'mid_p'] = (intraday_data['c' + str(i+1)]['best_bid_p'] + intraday_data['c' + str(i+1)]['best_ask_p'])/2 intraday_data['spread'] = intraday_data['spread']+intraday_data['c' + str(i+1)]['mid_p']*spread_weights[i] unique_settle_dates = intraday_data['settle_date'].unique() intraday_data['spread1'] = np.nan for i in range(len(unique_settle_dates)-1): if (intraday_data['settle_date'] == unique_settle_dates[i]).sum() == \ (intraday_data['settle_date'] == unique_settle_dates[i+1]).sum(): intraday_data.loc[intraday_data['settle_date'] == unique_settle_dates[i],'spread1'] = \ intraday_data['spread'][intraday_data['settle_date'] == unique_settle_dates[i+1]].values intraday_data = intraday_data[intraday_data['settle_date'].notnull()] intraday_mean = intraday_data['spread'].mean() intraday_std = intraday_data['spread'].std() intraday_data_last2days = intraday_data[intraday_data['settle_date'] >= cu.convert_doubledate_2datetime(date_list[-2]).date()] intraday_data_yesterday = intraday_data[intraday_data['settle_date'] == cu.convert_doubledate_2datetime(date_list[-1]).date()] intraday_mean2 = intraday_data_last2days['spread'].mean() intraday_std2 = intraday_data_last2days['spread'].std() intraday_mean1 = intraday_data_yesterday['spread'].mean() intraday_std1 = intraday_data_yesterday['spread'].std() intraday_z = (spread_settle-intraday_mean)/intraday_std num_obs_intraday = len(intraday_data.index) num_obs_intraday_half = round(num_obs_intraday/2) intraday_tail = intraday_data.tail(num_obs_intraday_half) num_positives = sum(intraday_tail['spread'] > intraday_data['spread'].mean()) num_negatives = sum(intraday_tail['spread'] < intraday_data['spread'].mean()) recent_trend = 100*(num_positives-num_negatives)/(num_positives+num_negatives) pnl_frame = ifs.get_pnl_4_date_range(date_to=date_to, num_bus_days_back=20, ticker_list=ticker_list) if (len(pnl_frame.index)>15)&(pnl_frame['total_pnl'].std() != 0): historical_sharp = (250**(0.5))*pnl_frame['total_pnl'].mean()/pnl_frame['total_pnl'].std() else: historical_sharp = np.nan return {'downside': downside, 'upside': upside,'intraday_data': intraday_data, 'z': intraday_z,'recent_trend': recent_trend, 'intraday_mean': intraday_mean, 'intraday_std': intraday_std, 'intraday_mean2': intraday_mean2, 'intraday_std2': intraday_std2, 'intraday_mean1': intraday_mean1, 'intraday_std1': intraday_std1, 'aligned_output': aligned_output, 'spread_settle': spread_settle, 'data_last5_years': data_last5_years,'historical_sharp':historical_sharp}
def get_coin_stats(**kwargs): ticker = kwargs['ticker'] date_to = kwargs['date'] data_out = gd.get_daily_price_data4ticker(ticker=ticker, date_to=date_to) data_out['quoteAssetVolume'] = pd.to_numeric(data_out['quoteAssetVolume']) data_out['close'] = pd.to_numeric(data_out['close']) data_out['pChange_1'] = 100 * data_out['close'].pct_change() if len(data_out.index) >= 30: average_volume = data_out['quoteAssetVolume'].iloc[-30:].mean() else: average_volume = np.nan if len(data_out.index) >= 7: std7 = np.std(data_out['pChange_1'].iloc[-7:]) else: std7 = np.nan if len(data_out.index) >= 30: std30 = np.std(data_out['pChange_1'].iloc[-30:]) else: std30 = np.nan if len(data_out.index) >= 8: pChange_7 = 100 * ( data_out['close'].iloc[-1] - data_out['close'].iloc[-8]) / data_out['close'].iloc[-8] else: pChange_7 = np.nan if len(data_out.index) >= 31: pChange_30 = 100 * ( data_out['close'].iloc[-1] - data_out['close'].iloc[-31]) / data_out['close'].iloc[-31] else: pChange_30 = np.nan if len(data_out.index) >= 61: pChange_60 = 100 * ( data_out['close'].iloc[-1] - data_out['close'].iloc[-61]) / data_out['close'].iloc[-61] else: pChange_60 = np.nan if len(data_out.index) >= 91: pChange_90 = 100 * ( data_out['close'].iloc[-1] - data_out['close'].iloc[-91]) / data_out['close'].iloc[-91] else: pChange_90 = np.nan if len(data_out.index) >= 200: data_out['ma150'] = data_out['close'].rolling(window=150, center=False).mean() data_out['ma150diff'] = data_out['close'] - data_out['ma150'] data_out['zscore'] = data_out['ma150diff'] / np.std( data_out['ma150diff']) quantile_list = stats.get_number_from_quantile( y=data_out['zscore'].values, quantile_list=[20, 80]) zscore_stop = quantile_list[0] zscore_target = quantile_list[1] zscore = data_out['zscore'].iloc[-1] if data_out['ma150'].iloc[-1] > data_out['ma150'].iloc[-40]: trend_direction1 = 1 else: trend_direction1 = -1 if max(data_out['high'].iloc[-60:]) == max( data_out['high'].iloc[-200:]): trend_direction2 = 1 elif min(data_out['low'].iloc[-60:]) == min( data_out['low'].iloc[-200:]): trend_direction2 = -1 else: trend_direction2 = 0 else: trend_direction1 = 0 trend_direction2 = 0 zscore = np.nan zscore_stop = np.nan zscore_target = np.nan if len(data_out.index) >= 60: entry_price = 1.005 * max(data_out['high'].iloc[-7:]) stop_price = 0.995 * min(data_out['low'].iloc[-7:]) recent_range = 100 * (max(data_out['high'].iloc[-7:]) - min( data_out['low'].iloc[-7:])) / min(data_out['low'].iloc[-7:]) risk = recent_range + 1 target_price = 0.8 * (max(data_out['high'].iloc[-90:]) - max( data_out['high'].iloc[-7:])) + max(data_out['high'].iloc[-7:]) reward = 100 * (target_price - entry_price) / entry_price rr = reward / risk else: entry_price = np.nan target_price = np.nan stop_price = np.nan risk = np.nan reward = np.nan rr = np.nan return { 'average_volume': average_volume, 'std7': std7, 'std30': std30, 'pChange_7': pChange_7, 'pChange_30': pChange_30, 'pChange_60': pChange_60, 'pChange_90': pChange_90, 'trend_direction1': trend_direction1, 'trend_direction2': trend_direction2, 'zscore': zscore, 'zscore_stop': zscore_stop, 'zscore_target': zscore_target, 'entry_price': entry_price, 'target_price': target_price, 'stop_price': stop_price, 'risk': risk, 'reward': reward, 'rr': rr }
def get_historical_risk_4open_strategies(**kwargs): if 'as_of_date' in kwargs.keys(): as_of_date = kwargs['as_of_date'] else: as_of_date = exp.doubledate_shift_bus_days() kwargs['as_of_date'] = as_of_date ta_output_dir = dn.get_dated_directory_extension(folder_date=as_of_date, ext='ta') if os.path.isfile(ta_output_dir + '/portfolio_risk.pkl'): with open(ta_output_dir + '/portfolio_risk.pkl','rb') as handle: portfolio_risk_output = pickle.load(handle) return portfolio_risk_output con = msu.get_my_sql_connection(**kwargs) strategy_frame = ts.get_open_strategies(**kwargs) futures_data_dictionary = {x: gfp.get_futures_price_preloaded(ticker_head=x) for x in cmi.ticker_class.keys()} strategy_risk_frame = pd.DataFrame() historical_risk_output = [get_historical_risk_4strategy(alias=x, as_of_date=as_of_date, con=con, futures_data_dictionary=futures_data_dictionary) for x in strategy_frame['alias']] if 'con' not in kwargs.keys(): con.close() strategy_risk_frame['alias'] = strategy_frame['alias'] strategy_risk_frame['downside'] = [x['downside'] for x in historical_risk_output] strategy_risk_frame.sort('downside', ascending=True, inplace=True) ticker_head_list = su.flatten_list([list(x['ticker_head_based_pnl_5_change'].keys()) for x in historical_risk_output if x['downside'] != 0]) unique_ticker_head_list = list(set(ticker_head_list)) ticker_head_aggregated_pnl_5_change = {ticker_head: sum([x['ticker_head_based_pnl_5_change'][ticker_head] for x in historical_risk_output if x['downside'] != 0 and ticker_head in x['ticker_head_based_pnl_5_change'].keys()]) for ticker_head in unique_ticker_head_list} percentile_vector = [stats.get_number_from_quantile(y=ticker_head_aggregated_pnl_5_change[ticker_head], quantile_list=[1, 15], clean_num_obs=max(100, round(3*len(ticker_head_aggregated_pnl_5_change[ticker_head].values)/4))) for ticker_head in unique_ticker_head_list] ticker_head_risk_frame = pd.DataFrame() ticker_head_risk_frame['tickerHead'] = unique_ticker_head_list ticker_head_risk_frame['downside'] = [(x[0]+x[1])/2 for x in percentile_vector] ticker_head_risk_frame.sort('downside', ascending=True, inplace=True) strategy_risk_frame['downside'] = strategy_risk_frame['downside'].round() ticker_head_risk_frame['downside'] = ticker_head_risk_frame['downside'].round() portfolio_risk_output = {'strategy_risk_frame': strategy_risk_frame, 'ticker_head_aggregated_pnl_5_change': ticker_head_aggregated_pnl_5_change, 'ticker_head_risk_frame':ticker_head_risk_frame} with open(ta_output_dir + '/portfolio_risk.pkl', 'wb') as handle: pickle.dump(portfolio_risk_output, handle) return portfolio_risk_output
def get_ics_signals(**kwargs): ticker = kwargs['ticker'] #print(ticker) date_to = kwargs['date_to'] con = msu.get_my_sql_connection(**kwargs) ticker_list = ticker.split('-') #print(ticker_list) ticker_head_list = [ cmi.get_contract_specs(x)['ticker_head'] for x in ticker_list ] ticker_class = cmi.ticker_class[ticker_head_list[0]] if 'futures_data_dictionary' in kwargs.keys(): futures_data_dictionary = kwargs['futures_data_dictionary'] else: futures_data_dictionary = { x: gfp.get_futures_price_preloaded(ticker_head=x) for x in list(set(ticker_head_list)) } if 'datetime5_years_ago' in kwargs.keys(): datetime5_years_ago = kwargs['datetime5_years_ago'] else: date5_years_ago = cu.doubledate_shift(date_to, 5 * 365) datetime5_years_ago = cu.convert_doubledate_2datetime(date5_years_ago) if 'num_days_back_4intraday' in kwargs.keys(): num_days_back_4intraday = kwargs['num_days_back_4intraday'] else: num_days_back_4intraday = 5 tr_dte_list = [ exp.get_days2_expiration(ticker=x, date_to=date_to, instrument='futures', con=con)['tr_dte'] for x in ticker_list ] amcb_output = [ opUtil.get_aggregation_method_contracts_back(cmi.get_contract_specs(x)) for x in ticker_list ] aggregation_method = max([x['aggregation_method'] for x in amcb_output]) contracts_back = min([x['contracts_back'] for x in amcb_output]) contract_multiplier = cmi.contract_multiplier[ticker_head_list[0]] aligned_output = opUtil.get_aligned_futures_data( contract_list=ticker_list, tr_dte_list=tr_dte_list, aggregation_method=aggregation_method, contracts_back=contracts_back, date_to=date_to, futures_data_dictionary=futures_data_dictionary, use_last_as_current=True) aligned_data = aligned_output['aligned_data'] last5_years_indx = aligned_data['settle_date'] >= datetime5_years_ago data_last5_years = aligned_data[last5_years_indx] data_last5_years['spread_pnl_1'] = aligned_data['c1'][ 'change_1'] - aligned_data['c2']['change_1'] percentile_vector = stats.get_number_from_quantile( y=data_last5_years['spread_pnl_1'].values, quantile_list=[1, 15, 85, 99], clean_num_obs=max(100, round(3 * len(data_last5_years.index) / 4))) downside = contract_multiplier * (percentile_vector[0] + percentile_vector[1]) / 2 upside = contract_multiplier * (percentile_vector[2] + percentile_vector[3]) / 2 date_list = [ exp.doubledate_shift_bus_days(double_date=date_to, shift_in_days=x) for x in reversed(range(1, num_days_back_4intraday)) ] date_list.append(date_to) intraday_data = opUtil.get_aligned_futures_data_intraday( contract_list=[ticker], date_list=date_list) intraday_data['time_stamp'] = [ x.to_datetime() for x in intraday_data.index ] intraday_data['settle_date'] = intraday_data['time_stamp'].apply( lambda x: x.date()) end_hour = cmi.last_trade_hour_minute[ticker_head_list[0]] start_hour = cmi.first_trade_hour_minute[ticker_head_list[0]] if ticker_class == 'Ag': start_hour1 = dt.time(0, 45, 0, 0) end_hour1 = dt.time(7, 45, 0, 0) selection_indx = [ x for x in range(len(intraday_data.index)) if ((intraday_data['time_stamp'].iloc[x].time() < end_hour1) and (intraday_data['time_stamp'].iloc[x].time() >= start_hour1)) or ((intraday_data['time_stamp'].iloc[x].time() < end_hour) and (intraday_data['time_stamp'].iloc[x].time() >= start_hour)) ] else: selection_indx = [ x for x in range(len(intraday_data.index)) if (intraday_data.index[x].to_datetime().time() < end_hour) and ( intraday_data.index[x].to_datetime().time() >= start_hour) ] intraday_data = intraday_data.iloc[selection_indx] intraday_mean5 = np.nan intraday_std5 = np.nan intraday_mean2 = np.nan intraday_std2 = np.nan intraday_mean1 = np.nan intraday_std1 = np.nan if len(intraday_data.index) > 0: intraday_data['mid_p'] = (intraday_data['c1']['best_bid_p'] + intraday_data['c1']['best_ask_p']) / 2 intraday_mean5 = intraday_data['mid_p'].mean() intraday_std5 = intraday_data['mid_p'].std() intraday_data_last2days = intraday_data[ intraday_data['settle_date'] >= cu.convert_doubledate_2datetime( date_list[-2]).date()] intraday_data_yesterday = intraday_data[ intraday_data['settle_date'] == cu.convert_doubledate_2datetime( date_list[-1]).date()] intraday_mean2 = intraday_data_last2days['mid_p'].mean() intraday_std2 = intraday_data_last2days['mid_p'].std() intraday_mean1 = intraday_data_yesterday['mid_p'].mean() intraday_std1 = intraday_data_yesterday['mid_p'].std() if 'con' not in kwargs.keys(): con.close() return { 'downside': downside, 'upside': upside, 'front_tr_dte': tr_dte_list[0], 'intraday_mean5': intraday_mean5, 'intraday_std5': intraday_std5, 'intraday_mean2': intraday_mean2, 'intraday_std2': intraday_std2, 'intraday_mean1': intraday_mean1, 'intraday_std1': intraday_std1 }
def get_vcs_signals_legacy(**kwargs): aligned_indicators_output = get_aligned_option_indicators_legacy(**kwargs) if not aligned_indicators_output['success']: return {'atm_vol_ratio': np.NaN, 'q': np.NaN, 'q2': np.NaN, 'q1': np.NaN, 'q5': np.NaN, 'fwd_vol_q': np.NaN, 'fwd_vol_q2': np.NaN, 'fwd_vol_q1': np.NaN, 'fwd_vol_q5': np.NaN, 'atm_real_vol_ratio': np.NaN, 'q_atm_real_vol_ratio': np.NaN, 'atm_real_vol_ratio_ratio': np.NaN, 'q_atm_real_vol_ratio_ratio': np.NaN, 'tr_dte_diff_percent': np.NaN,'downside': np.NaN, 'upside': np.NaN, 'theta1': np.NaN, 'theta2': np.NaN, 'hist': []} hist = aligned_indicators_output['hist'] current = aligned_indicators_output['current'] settle_datetime = cu.convert_doubledate_2datetime(kwargs['settle_date']) settle_datetime_1year_back = settle_datetime-dt.timedelta(360) settle_datetime_5year_back = settle_datetime-dt.timedelta(5*360) hist['atm_vol_ratio'] = hist['c1']['imp_vol']/hist['c2']['imp_vol'] fwd_var = hist['c2']['cal_dte']*(hist['c2']['imp_vol']**2)-hist['c1']['cal_dte']*(hist['c1']['imp_vol']**2) fwd_vol_sq = fwd_var/(hist['c2']['cal_dte']-hist['c1']['cal_dte']) fwd_vol_adj = np.sign(fwd_vol_sq)*((abs(fwd_vol_sq)).apply(np.sqrt)) hist['fwd_vol_adj'] = fwd_vol_adj fwd_var = current['cal_dte'][1]*(current['imp_vol'][1]**2)-current['cal_dte'][0]*(current['imp_vol'][0]**2) fwd_vol_sq = fwd_var/(current['cal_dte'][1]-current['cal_dte'][0]) fwd_vol_adj = np.sign(fwd_vol_sq)*(np.sqrt(abs(fwd_vol_sq))) atm_vol_ratio = current['imp_vol'][0]/current['imp_vol'][1] hist['atm_real_vol_ratio'] = hist['c1']['imp_vol']/hist['c1']['close2close_vol20'] atm_real_vol_ratio = current['imp_vol'][0]/current['close2close_vol20'][0] hist['atm_real_vol_ratio_ratio'] = (hist['c1']['imp_vol']/hist['c1']['close2close_vol20'])/(hist['c2']['imp_vol']/hist['c2']['close2close_vol20']) atm_real_vol_ratio_ratio = (current['imp_vol'][0]/current['close2close_vol20'][0])/(current['imp_vol'][0]/current['close2close_vol20'][0]) hist_1year = hist[hist.index >= settle_datetime_1year_back] hist_5year = hist[hist.index >= settle_datetime_5year_back] q = stats.get_quantile_from_number({'x': atm_vol_ratio, 'y': hist['atm_vol_ratio'].values, 'clean_num_obs': max(100, round(3*len(hist.index)/4))}) q2 = stats.get_quantile_from_number({'x': atm_vol_ratio, 'y': hist['atm_vol_ratio'].values[-40:], 'clean_num_obs': 30}) q1 = stats.get_quantile_from_number({'x': atm_vol_ratio, 'y': hist_1year['atm_vol_ratio'].values, 'clean_num_obs': max(50, round(3*len(hist_1year.index)/4))}) q5 = stats.get_quantile_from_number({'x': atm_vol_ratio, 'y': hist_5year['atm_vol_ratio'].values, 'clean_num_obs': max(100, round(3*len(hist_5year.index)/4))}) fwd_vol_q = stats.get_quantile_from_number({'x': fwd_vol_adj, 'y': hist['fwd_vol_adj'].values, 'clean_num_obs': max(100, round(3*len(hist.index)/4))}) fwd_vol_q2 = stats.get_quantile_from_number({'x': fwd_vol_adj, 'y': hist['fwd_vol_adj'].values[-40:], 'clean_num_obs': 30}) fwd_vol_q1 = stats.get_quantile_from_number({'x': fwd_vol_adj, 'y': hist_1year['fwd_vol_adj'].values, 'clean_num_obs': max(50, round(3*len(hist_1year.index)/4))}) fwd_vol_q5 = stats.get_quantile_from_number({'x': fwd_vol_adj, 'y': hist_5year['fwd_vol_adj'].values, 'clean_num_obs': max(100, round(3*len(hist_5year.index)/4))}) q_atm_real_vol_ratio = stats.get_quantile_from_number({'x': atm_real_vol_ratio, 'y': hist['atm_real_vol_ratio'].values, 'clean_num_obs': max(100, round(3*len(hist.index)/4))}) q_atm_real_vol_ratio_ratio = stats.get_quantile_from_number({'x': atm_real_vol_ratio_ratio, 'y': hist['atm_real_vol_ratio_ratio'].values, 'clean_num_obs': max(100, round(3*len(hist.index)/4))}) tr_dte_diff_percent = round(100*(current['tr_dte'][1]-current['tr_dte'][0])/current['tr_dte'][0]) profit5 = hist['c1']['profit5']-hist['c2']['profit5'] clean_indx = profit5.notnull() clean_data = hist[clean_indx] if clean_data.empty: downside = np.NaN upside = np.NaN else: last_available_align_date = clean_data.index[-1] clean_data = clean_data[clean_data.index >= last_available_align_date-dt.timedelta(5*365)] profit5 = clean_data['c1']['profit5']-clean_data['c2']['profit5'] percentile_vector = stats.get_number_from_quantile(y=profit5.values, quantile_list=[1, 15, 85, 99], clean_num_obs=max(100, round(3*len(profit5.values)/4))) downside = (percentile_vector[0]+percentile_vector[1])/2 upside = (percentile_vector[2]+percentile_vector[3])/2 return {'atm_vol_ratio': atm_vol_ratio, 'q': q, 'q2': q2, 'q1': q1, 'q5': q5, 'fwd_vol_q': fwd_vol_q, 'fwd_vol_q2': fwd_vol_q2, 'fwd_vol_q1': fwd_vol_q1, 'fwd_vol_q5': fwd_vol_q5, 'atm_real_vol_ratio': atm_real_vol_ratio, 'q_atm_real_vol_ratio': q_atm_real_vol_ratio, 'atm_real_vol_ratio_ratio': atm_real_vol_ratio_ratio, 'q_atm_real_vol_ratio_ratio': q_atm_real_vol_ratio_ratio, 'tr_dte_diff_percent': tr_dte_diff_percent, 'downside': downside, 'upside': upside, 'theta1': current['theta'][0], 'theta2': current['theta'][1], 'hist': hist}
def get_historical_risk_4open_strategies(**kwargs): if 'as_of_date' in kwargs.keys(): as_of_date = kwargs['as_of_date'] else: as_of_date = exp.doubledate_shift_bus_days() kwargs['as_of_date'] = as_of_date ta_output_dir = dn.get_dated_directory_extension(folder_date=as_of_date, ext='ta') if os.path.isfile(ta_output_dir + '/portfolio_risk.pkl'): with open(ta_output_dir + '/portfolio_risk.pkl','rb') as handle: portfolio_risk_output = pickle.load(handle) return portfolio_risk_output con = msu.get_my_sql_connection(**kwargs) strategy_frame = ts.get_open_strategies(**kwargs) futures_data_dictionary = {x: gfp.get_futures_price_preloaded(ticker_head=x) for x in cmi.ticker_class.keys()} strategy_risk_frame = pd.DataFrame() historical_risk_output = [get_historical_risk_4strategy(alias=x, as_of_date=as_of_date, con=con, futures_data_dictionary=futures_data_dictionary) for x in strategy_frame['alias']] if 'con' not in kwargs.keys(): con.close() strategy_risk_frame['alias'] = strategy_frame['alias'] strategy_risk_frame['downside'] = [x['downside'] for x in historical_risk_output] strategy_risk_frame.sort_values('downside', ascending=True, inplace=True) ticker_head_list = su.flatten_list([list(x['ticker_head_based_pnl_5_change'].keys()) for x in historical_risk_output if x['downside'] != 0]) unique_ticker_head_list = list(set(ticker_head_list)) ticker_head_aggregated_pnl_5_change = {ticker_head: sum([x['ticker_head_based_pnl_5_change'][ticker_head] for x in historical_risk_output if x['downside'] != 0 and ticker_head in x['ticker_head_based_pnl_5_change'].keys()]) for ticker_head in unique_ticker_head_list} percentile_vector = [stats.get_number_from_quantile(y=ticker_head_aggregated_pnl_5_change[ticker_head], quantile_list=[1, 15], clean_num_obs=max(100, round(3*len(ticker_head_aggregated_pnl_5_change[ticker_head].values)/4))) for ticker_head in unique_ticker_head_list] ticker_head_risk_frame = pd.DataFrame() ticker_head_risk_frame['tickerHead'] = unique_ticker_head_list ticker_head_risk_frame['downside'] = [(x[0]+x[1])/2 for x in percentile_vector] ticker_head_risk_frame.sort_values('downside', ascending=True, inplace=True) strategy_risk_frame['downside'] = strategy_risk_frame['downside'].round() ticker_head_risk_frame['downside'] = ticker_head_risk_frame['downside'].round() portfolio_risk_output = {'strategy_risk_frame': strategy_risk_frame, 'ticker_head_aggregated_pnl_5_change': ticker_head_aggregated_pnl_5_change, 'ticker_head_risk_frame':ticker_head_risk_frame} with open(ta_output_dir + '/portfolio_risk.pkl', 'wb') as handle: pickle.dump(portfolio_risk_output, handle) return portfolio_risk_output
def get_intraday_spread_signals(**kwargs): ticker_list = kwargs['ticker_list'] date_to = kwargs['date_to'] #print(ticker_list) ticker_list = [x for x in ticker_list if x is not None] ticker_head_list = [ cmi.get_contract_specs(x)['ticker_head'] for x in ticker_list ] ticker_class_list = [cmi.ticker_class[x] for x in ticker_head_list] #print('-'.join(ticker_list)) if 'tr_dte_list' in kwargs.keys(): tr_dte_list = kwargs['tr_dte_list'] else: tr_dte_list = [ exp.get_days2_expiration(ticker=x, date_to=date_to, instrument='futures')['tr_dte'] for x in ticker_list ] if 'aggregation_method' in kwargs.keys( ) and 'contracts_back' in kwargs.keys(): aggregation_method = kwargs['aggregation_method'] contracts_back = kwargs['contracts_back'] else: amcb_output = [ opUtil.get_aggregation_method_contracts_back( cmi.get_contract_specs(x)) for x in ticker_list ] aggregation_method = max( [x['aggregation_method'] for x in amcb_output]) contracts_back = min([x['contracts_back'] for x in amcb_output]) if 'futures_data_dictionary' in kwargs.keys(): futures_data_dictionary = kwargs['futures_data_dictionary'] else: futures_data_dictionary = { x: gfp.get_futures_price_preloaded(ticker_head=x) for x in list(set(ticker_head_list)) } if 'use_last_as_current' in kwargs.keys(): use_last_as_current = kwargs['use_last_as_current'] else: use_last_as_current = True if 'datetime5_years_ago' in kwargs.keys(): datetime5_years_ago = kwargs['datetime5_years_ago'] else: date5_years_ago = cu.doubledate_shift(date_to, 5 * 365) datetime5_years_ago = cu.convert_doubledate_2datetime(date5_years_ago) if 'num_days_back_4intraday' in kwargs.keys(): num_days_back_4intraday = kwargs['num_days_back_4intraday'] else: num_days_back_4intraday = 10 contract_multiplier_list = [ cmi.contract_multiplier[x] for x in ticker_head_list ] aligned_output = opUtil.get_aligned_futures_data( contract_list=ticker_list, tr_dte_list=tr_dte_list, aggregation_method=aggregation_method, contracts_back=contracts_back, date_to=date_to, futures_data_dictionary=futures_data_dictionary, use_last_as_current=use_last_as_current) aligned_data = aligned_output['aligned_data'] current_data = aligned_output['current_data'] if ticker_head_list in fixed_weight_future_spread_list: weights_output = sutil.get_spread_weights_4contract_list( ticker_head_list=ticker_head_list) spread_weights = weights_output['spread_weights'] portfolio_weights = weights_output['portfolio_weights'] else: regress_output = stats.get_regression_results({ 'x': aligned_data['c2']['change_1'][-60:], 'y': aligned_data['c1']['change_1'][-60:] }) spread_weights = [1, -regress_output['beta']] portfolio_weights = [ 1, -regress_output['beta'] * contract_multiplier_list[0] / contract_multiplier_list[1] ] aligned_data['spread'] = 0 aligned_data['spread_pnl_1'] = 0 aligned_data['spread_pnl1'] = 0 spread_settle = 0 last5_years_indx = aligned_data['settle_date'] >= datetime5_years_ago num_contracts = len(ticker_list) for i in range(num_contracts): aligned_data['spread'] = aligned_data['spread'] + aligned_data[ 'c' + str(i + 1)]['close_price'] * spread_weights[i] spread_settle = spread_settle + current_data[ 'c' + str(i + 1)]['close_price'] * spread_weights[i] aligned_data[ 'spread_pnl_1'] = aligned_data['spread_pnl_1'] + aligned_data[ 'c' + str(i + 1)]['change_1'] * portfolio_weights[ i] * contract_multiplier_list[i] aligned_data[ 'spread_pnl1'] = aligned_data['spread_pnl1'] + aligned_data[ 'c' + str(i + 1)]['change1_instant'] * portfolio_weights[ i] * contract_multiplier_list[i] aligned_data['spread_normalized'] = aligned_data['spread'] / aligned_data[ 'c1']['close_price'] data_last5_years = aligned_data[last5_years_indx] percentile_vector = stats.get_number_from_quantile( y=data_last5_years['spread_pnl_1'].values, quantile_list=[1, 15, 85, 99], clean_num_obs=max(100, round(3 * len(data_last5_years.index) / 4))) downside = (percentile_vector[0] + percentile_vector[1]) / 2 upside = (percentile_vector[2] + percentile_vector[3]) / 2 date_list = [ exp.doubledate_shift_bus_days(double_date=date_to, shift_in_days=x) for x in reversed(range(1, num_days_back_4intraday)) ] date_list.append(date_to) intraday_data = opUtil.get_aligned_futures_data_intraday( contract_list=ticker_list, date_list=date_list) if len(intraday_data.index) == 0: return { 'downside': downside, 'upside': upside, 'intraday_data': intraday_data, 'trading_data': intraday_data, 'spread_weight': spread_weights[1], 'portfolio_weight': portfolio_weights[1], 'z': np.nan, 'recent_trend': np.nan, 'intraday_mean10': np.nan, 'intraday_std10': np.nan, 'intraday_mean5': np.nan, 'intraday_std5': np.nan, 'intraday_mean2': np.nan, 'intraday_std2': np.nan, 'intraday_mean1': np.nan, 'intraday_std1': np.nan, 'aligned_output': aligned_output, 'spread_settle': spread_settle, 'data_last5_years': data_last5_years, 'ma_spread_lowL': np.nan, 'ma_spread_highL': np.nan, 'ma_spread_low': np.nan, 'ma_spread_high': np.nan, 'intraday_sharp': np.nan } intraday_data['time_stamp'] = [ x.to_datetime() for x in intraday_data.index ] intraday_data['settle_date'] = intraday_data['time_stamp'].apply( lambda x: x.date()) end_hour = min([cmi.last_trade_hour_minute[x] for x in ticker_head_list]) start_hour = max( [cmi.first_trade_hour_minute[x] for x in ticker_head_list]) trade_start_hour = dt.time(9, 30, 0, 0) if 'Ag' in ticker_class_list: start_hour1 = dt.time(0, 45, 0, 0) end_hour1 = dt.time(7, 45, 0, 0) selection_indx = [ x for x in range(len(intraday_data.index)) if ((intraday_data['time_stamp'].iloc[x].time() < end_hour1) and (intraday_data['time_stamp'].iloc[x].time() >= start_hour1)) or ((intraday_data['time_stamp'].iloc[x].time() < end_hour) and (intraday_data['time_stamp'].iloc[x].time() >= start_hour)) ] else: selection_indx = [ x for x in range(len(intraday_data.index)) if (intraday_data.index[x].to_datetime().time() < end_hour) and ( intraday_data.index[x].to_datetime().time() >= start_hour) ] intraday_data = intraday_data.iloc[selection_indx] intraday_data['spread'] = 0 for i in range(num_contracts): intraday_data[ 'c' + str(i + 1), 'mid_p'] = (intraday_data['c' + str(i + 1)]['best_bid_p'] + intraday_data['c' + str(i + 1)]['best_ask_p']) / 2 intraday_data['spread'] = intraday_data['spread'] + intraday_data[ 'c' + str(i + 1)]['mid_p'] * spread_weights[i] unique_settle_dates = intraday_data['settle_date'].unique() intraday_data['spread1'] = np.nan for i in range(len(unique_settle_dates) - 1): if (intraday_data['settle_date'] == unique_settle_dates[i]).sum() == \ (intraday_data['settle_date'] == unique_settle_dates[i+1]).sum(): intraday_data.loc[intraday_data['settle_date'] == unique_settle_dates[i],'spread1'] = \ intraday_data['spread'][intraday_data['settle_date'] == unique_settle_dates[i+1]].values intraday_data = intraday_data[intraday_data['settle_date'].notnull()] intraday_mean10 = intraday_data['spread'].mean() intraday_std10 = intraday_data['spread'].std() intraday_data_last5days = intraday_data[ intraday_data['settle_date'] >= cu.convert_doubledate_2datetime( date_list[-5]).date()] intraday_data_last2days = intraday_data[ intraday_data['settle_date'] >= cu.convert_doubledate_2datetime( date_list[-2]).date()] intraday_data_yesterday = intraday_data[intraday_data['settle_date'] == cu.convert_doubledate_2datetime( date_list[-1]).date()] intraday_mean5 = intraday_data_last5days['spread'].mean() intraday_std5 = intraday_data_last5days['spread'].std() intraday_mean2 = intraday_data_last2days['spread'].mean() intraday_std2 = intraday_data_last2days['spread'].std() intraday_mean1 = intraday_data_yesterday['spread'].mean() intraday_std1 = intraday_data_yesterday['spread'].std() intraday_z = (spread_settle - intraday_mean5) / intraday_std5 num_obs_intraday = len(intraday_data.index) num_obs_intraday_half = round(num_obs_intraday / 2) intraday_tail = intraday_data.tail(num_obs_intraday_half) num_positives = sum( intraday_tail['spread'] > intraday_data['spread'].mean()) num_negatives = sum( intraday_tail['spread'] < intraday_data['spread'].mean()) if num_positives + num_negatives != 0: recent_trend = 100 * (num_positives - num_negatives) / (num_positives + num_negatives) else: recent_trend = np.nan intraday_data_shifted = intraday_data.groupby('settle_date').shift(-60) intraday_data['spread_shifted'] = intraday_data_shifted['spread'] intraday_data[ 'delta60'] = intraday_data['spread_shifted'] - intraday_data['spread'] intraday_data['ewma10'] = pd.ewma(intraday_data['spread'], span=10) intraday_data['ewma50'] = pd.ewma(intraday_data['spread'], span=50) intraday_data['ewma200'] = pd.ewma(intraday_data['spread'], span=200) intraday_data['ma40'] = pd.rolling_mean(intraday_data['spread'], 40) intraday_data[ 'ewma50_spread'] = intraday_data['spread'] - intraday_data['ewma50'] intraday_data[ 'ma40_spread'] = intraday_data['spread'] - intraday_data['ma40'] selection_indx = [ x for x in range(len(intraday_data.index)) if (intraday_data['time_stamp'].iloc[x].time() > trade_start_hour) ] selected_data = intraday_data.iloc[selection_indx] selected_data['delta60Net'] = (contract_multiplier_list[0] * selected_data['delta60'] / spread_weights[0]) selected_data.reset_index(drop=True, inplace=True) selected_data['proxy_pnl'] = 0 t_cost = cmi.t_cost[ticker_head_list[0]] ma_spread_low = np.nan ma_spread_high = np.nan ma_spread_lowL = np.nan ma_spread_highL = np.nan intraday_sharp = np.nan if sum(selected_data['ma40_spread'].notnull()) > 30: quantile_list = selected_data['ma40_spread'].quantile([0.1, 0.9]) down_indx = selected_data['ma40_spread'] < quantile_list[0.1] up_indx = selected_data['ma40_spread'] > quantile_list[0.9] up_data = selected_data[up_indx] down_data = selected_data[down_indx] ma_spread_lowL = quantile_list[0.1] ma_spread_highL = quantile_list[0.9] #return {'selected_data':selected_data,'up_data':up_data,'up_indx':up_indx} selected_data.loc[up_indx, 'proxy_pnl'] = (-up_data['delta60Net'] - 2 * num_contracts * t_cost).values selected_data.loc[down_indx, 'proxy_pnl'] = (down_data['delta60Net'] - 2 * num_contracts * t_cost).values short_term_data = selected_data[ selected_data['settle_date'] >= cu.convert_doubledate_2datetime( date_list[-5]).date()] if sum(short_term_data['ma40_spread'].notnull()) > 30: quantile_list = short_term_data['ma40_spread'].quantile([0.1, 0.9]) ma_spread_low = quantile_list[0.1] ma_spread_high = quantile_list[0.9] if selected_data['proxy_pnl'].std() != 0: intraday_sharp = selected_data['proxy_pnl'].mean( ) / selected_data['proxy_pnl'].std() return { 'downside': downside, 'upside': upside, 'intraday_data': intraday_data, 'trading_data': selected_data, 'spread_weight': spread_weights[1], 'portfolio_weight': portfolio_weights[1], 'z': intraday_z, 'recent_trend': recent_trend, 'intraday_mean10': intraday_mean10, 'intraday_std10': intraday_std10, 'intraday_mean5': intraday_mean5, 'intraday_std5': intraday_std5, 'intraday_mean2': intraday_mean2, 'intraday_std2': intraday_std2, 'intraday_mean1': intraday_mean1, 'intraday_std1': intraday_std1, 'aligned_output': aligned_output, 'spread_settle': spread_settle, 'data_last5_years': data_last5_years, 'ma_spread_lowL': ma_spread_lowL, 'ma_spread_highL': ma_spread_highL, 'ma_spread_low': ma_spread_low, 'ma_spread_high': ma_spread_high, 'intraday_sharp': intraday_sharp }
def get_scv_signals(**kwargs): ticker = kwargs['ticker'] date_to = kwargs['date_to'] con = msu.get_my_sql_connection(**kwargs) if 'futures_data_dictionary' in kwargs.keys(): futures_data_dictionary = kwargs['futures_data_dictionary'] else: futures_data_dictionary = {x: gfp.get_futures_price_preloaded(ticker_head=x) for x in [cmi.get_contract_specs(ticker)['ticker_head']]} aligned_indicators_output = ops.get_aligned_option_indicators(ticker_list=[ticker], settle_date=date_to, con=con) if not aligned_indicators_output['success']: return {'downside': np.NaN, 'upside': np.NaN, 'theta': np.NaN, 'realized_vol_forecast': np.NaN, 'real_vol20_current': np.NaN, 'imp_vol': np.NaN, 'imp_vol_premium': np.NaN, 'q': np.NaN} hist = aligned_indicators_output['hist'] current = aligned_indicators_output['current'] vcs_output = vcs.generate_vcs_sheet_4date(date_to=date_to,con=con) if 'con' not in kwargs.keys(): con.close() clean_indx = hist['c1']['profit5'].notnull() clean_data = hist[clean_indx] if clean_data.empty: downside = np.NaN upside = np.NaN else: last_available_align_date = clean_data.index[-1] clean_data = clean_data[clean_data.index >= last_available_align_date-dt.timedelta(5*365)] profit5 = clean_data['c1']['profit5'] percentile_vector = stats.get_number_from_quantile(y=profit5.values, quantile_list=[1, 15, 85, 99], clean_num_obs=max(100, round(3*len(profit5.values)/4))) downside = (percentile_vector[0]+percentile_vector[1])/2 upside = (percentile_vector[2]+percentile_vector[3])/2 realized_vol_output = rvue.forecast_realized_vol_until_expiration(ticker=ticker, futures_data_dictionary=futures_data_dictionary, date_to=date_to) realized_vol_forecast = realized_vol_output['realized_vol_forecast'] real_vol20_current = realized_vol_output['real_vol20_current'] imp_vol = current['imp_vol'][0] imp_vol_premium = 100*(imp_vol-realized_vol_forecast)/imp_vol q = np.NaN if vcs_output['success']: vcs_pairs = vcs_output['vcs_pairs'] selected_pairs = vcs_pairs[vcs_pairs['ticker2'] == ticker] if not selected_pairs.empty: q = 100-selected_pairs['Q'].mean() return {'downside': downside, 'upside': upside, 'theta': current['theta'][0], 'realized_vol_forecast': realized_vol_forecast, 'real_vol20_current': real_vol20_current, 'imp_vol': imp_vol, 'imp_vol_premium': imp_vol_premium, 'q': q}