def get_butterfly_panel_plot(**kwargs): report_date = kwargs['report_date'] id = kwargs['id'] bf_output = fb.generate_futures_butterfly_sheet_4date(date_to=report_date) butterflies = bf_output['butterflies'] contract_list = [butterflies['ticker1'][id], butterflies['ticker2'][id], butterflies['ticker3'][id]] tr_dte_list = [butterflies['trDte1'][id], butterflies['trDte2'][id], butterflies['trDte3'][id]] if 'aggregation_method' in kwargs.keys(): aggregation_method = kwargs['aggregation_method'] else: aggregation_method = butterflies['agg'][id] if 'contracts_back' in kwargs.keys(): contracts_back = kwargs['contracts_back'] else: contracts_back = butterflies['cBack'][id] post_report_date = exp.doubledate_shift_bus_days(double_date=report_date,shift_in_days=-20) bf_signals_output = fs.get_futures_butterfly_signals(ticker_list=contract_list, tr_dte_list=tr_dte_list, aggregation_method=aggregation_method, contracts_back=contracts_back, date_to=post_report_date, contract_multiplier=butterflies['multiplier'][id], use_last_as_current=True) aligned_data = bf_signals_output['aligned_output']['aligned_data'] new_index = list(range(len(aligned_data.index))) contract_change_indx = (aligned_data['c1']['ticker_year']-aligned_data['c1']['ticker_year'].shift(1)!=0).values front_contract_year = aligned_data['c1']['ticker_year'] % 10 contract_change_indx[0] = False report_datetime = cu.convert_doubledate_2datetime(report_date) x_index = [x for x in new_index if aligned_data['settle_date'][x] == report_datetime][0] x_tick_locations = [x for x in new_index if contract_change_indx[x]] x_tick_locations.append(x_index) x_tick_values = [cmi.letter_month_string[aligned_data['c1']['ticker_month'].values[x]-1]+ str(front_contract_year.values[x]) for x in new_index if contract_change_indx[x]] x_tick_values.append('X') plt.figure(figsize=(16, 7)) plt.plot(aligned_data['residuals']) plt.xticks(x_tick_locations,x_tick_values) plt.grid() plt.title('Contracts: ' + str(contract_list) + ', weight2: ' + str(bf_signals_output['second_spread_weight_1'].round(2))) plt.show() return bf_signals_output
def get_butterfly_scatter_plot(**kwargs): report_date = kwargs['report_date'] id = kwargs['id'] bf_output = fb.generate_futures_butterfly_sheet_4date(date_to=report_date) butterflies = bf_output['butterflies'] contract_list = [butterflies['ticker1'][id],butterflies['ticker2'][id],butterflies['ticker3'][id]] tr_dte_list = [butterflies['trDte1'][id],butterflies['trDte2'][id],butterflies['trDte3'][id]] if 'aggregation_method' in kwargs.keys(): aggregation_method = kwargs['aggregation_method'] else: aggregation_method = butterflies['agg'][id] if 'contracts_back' in kwargs.keys(): contracts_back = kwargs['contracts_back'] else: contracts_back = butterflies['cBack'][id] bf_signals_output = fs.get_futures_butterfly_signals(ticker_list=contract_list, tr_dte_list=tr_dte_list, aggregation_method=aggregation_method, contracts_back=contracts_back, date_to=report_date, contract_multiplier=butterflies['multiplier'][id]) last5_years_indx = bf_signals_output['last5_years_indx'] yield1 = bf_signals_output['yield1'] yield2 = bf_signals_output['yield2'] yield1_current = bf_signals_output['yield1_current'] yield2_current = bf_signals_output['yield2_current'] yield1_last5_years = yield1[last5_years_indx] yield2_last5_years = yield2[last5_years_indx] plt.figure(figsize=(16,7)) plt.scatter(yield2, yield1, color='b') plt.scatter(yield2_last5_years,yield1_last5_years, color='k') plt.scatter(yield2_current, yield1_current, color='r') plt.legend(['old', 'recent', 'last'], frameon=False) plt.grid() plt.show() return bf_signals_output
def generate_futures_butterfly_sheet_4date(**kwargs): date_to = kwargs['date_to'] output_dir = ts.create_strategy_output_dir( strategy_class='futures_butterfly', report_date=date_to) if os.path.isfile(output_dir + '/summary.pkl'): butterflies = pd.read_pickle(output_dir + '/summary.pkl') return {'butterflies': butterflies, 'success': True} if 'volume_filter' not in kwargs.keys(): kwargs['volume_filter'] = 100 butterflies = get_futures_butterflies_4date(**kwargs) butterflies = butterflies[butterflies['trDte1'] >= 35] butterflies.reset_index(drop=True, inplace=True) num_butterflies = len(butterflies) q_list = [None] * num_butterflies qf_list = [None] * num_butterflies zscore1_list = [None] * num_butterflies zscore2_list = [None] * num_butterflies zscore3_list = [None] * num_butterflies zscore4_list = [None] * num_butterflies zscore5_list = [None] * num_butterflies zscore6_list = [None] * num_butterflies zscore7_list = [None] * num_butterflies rsquared1_list = [None] * num_butterflies rsquared2_list = [None] * num_butterflies regime_change_list = [None] * num_butterflies contract_seasonality_list = [None] * num_butterflies yield1_list = [None] * num_butterflies yield2_list = [None] * num_butterflies bf_price_list = [None] * num_butterflies bf_price_sell_limit_list = [None] * num_butterflies bf_price_buy_limit_list = [None] * num_butterflies noise_ratio_list = [None] * num_butterflies alpha1_list = [None] * num_butterflies alpha2_list = [None] * num_butterflies residual_std1_list = [None] * num_butterflies residual_std2_list = [None] * num_butterflies second_spread_weight_1_list = [None] * num_butterflies second_spread_weight_2_list = [None] * num_butterflies weight1_list = [None] * num_butterflies weight2_list = [None] * num_butterflies weight3_list = [None] * num_butterflies downside_list = [None] * num_butterflies upside_list = [None] * num_butterflies recent_5day_pnl_list = [None] * num_butterflies recent_vol_ratio_list = [None] * num_butterflies theo_pnl_list = [None] * num_butterflies theo_pnl5_list = [None] * num_butterflies theo_pnl10_list = [None] * num_butterflies theo_pnl15_list = [None] * num_butterflies theo_pnl20_list = [None] * num_butterflies theo_pnl25_list = [None] * num_butterflies ratio_target5_list = [None] * num_butterflies ratio_target10_list = [None] * num_butterflies ratio_target15_list = [None] * num_butterflies ratio_target20_list = [None] * num_butterflies ratio_target25_list = [None] * num_butterflies price_1_list = [None] * num_butterflies price_2_list = [None] * num_butterflies price_3_list = [None] * num_butterflies mean_reversion_rsquared_list = [None] * num_butterflies mean_reversion_signif_list = [None] * num_butterflies futures_data_dictionary = { x: gfp.get_futures_price_preloaded(ticker_head=x) for x in cmi.futures_butterfly_strategy_tickerhead_list } date5_years_ago = cu.doubledate_shift(date_to, 5 * 365) datetime5_years_ago = cu.convert_doubledate_2datetime(date5_years_ago) for i in range(num_butterflies): bf_signals_output = fs.get_futures_butterfly_signals( ticker_list=[ butterflies['ticker1'][i], butterflies['ticker2'][i], butterflies['ticker3'][i] ], tr_dte_list=[ butterflies['trDte1'][i], butterflies['trDte2'][i], butterflies['trDte3'][i] ], aggregation_method=butterflies['agg'][i], contracts_back=butterflies['cBack'][i], date_to=date_to, futures_data_dictionary=futures_data_dictionary, contract_multiplier=butterflies['multiplier'][i], datetime5_years_ago=datetime5_years_ago) if not bf_signals_output['success']: continue q_list[i] = bf_signals_output['q'] qf_list[i] = bf_signals_output['qf'] zscore1_list[i] = bf_signals_output['zscore1'] zscore2_list[i] = bf_signals_output['zscore2'] zscore3_list[i] = bf_signals_output['zscore3'] zscore4_list[i] = bf_signals_output['zscore4'] zscore5_list[i] = bf_signals_output['zscore5'] zscore6_list[i] = bf_signals_output['zscore6'] zscore7_list[i] = bf_signals_output['zscore7'] rsquared1_list[i] = bf_signals_output['rsquared1'] rsquared2_list[i] = bf_signals_output['rsquared2'] regime_change_list[i] = bf_signals_output['regime_change_ind'] contract_seasonality_list[i] = bf_signals_output[ 'contract_seasonality_ind'] yield1_list[i] = bf_signals_output['yield1_current'] yield2_list[i] = bf_signals_output['yield2_current'] bf_price_list[i] = bf_signals_output['bf_price'] bf_price_sell_limit_list[i] = bf_signals_output['short_price_limit'] bf_price_buy_limit_list[i] = bf_signals_output['long_price_limit'] noise_ratio_list[i] = bf_signals_output['noise_ratio'] alpha1_list[i] = bf_signals_output['alpha1'] alpha2_list[i] = bf_signals_output['alpha2'] residual_std1_list = bf_signals_output['residual_std1'] residual_std2_list = bf_signals_output['residual_std2'] second_spread_weight_1_list[i] = bf_signals_output[ 'second_spread_weight_1'] second_spread_weight_2_list[i] = bf_signals_output[ 'second_spread_weight_2'] weight1_list[i] = bf_signals_output['weight1'] weight2_list[i] = bf_signals_output['weight2'] weight3_list[i] = bf_signals_output['weight3'] downside_list[i] = bf_signals_output['downside'] upside_list[i] = bf_signals_output['upside'] recent_5day_pnl_list[i] = bf_signals_output['recent_5day_pnl'] recent_vol_ratio_list[i] = bf_signals_output['recent_vol_ratio'] theo_pnl_list[i] = bf_signals_output['theo_pnl'] theo_pnl5_list[i] = bf_signals_output['theo_pnl_list'][0] theo_pnl10_list[i] = bf_signals_output['theo_pnl_list'][1] theo_pnl15_list[i] = bf_signals_output['theo_pnl_list'][2] theo_pnl20_list[i] = bf_signals_output['theo_pnl_list'][3] theo_pnl25_list[i] = bf_signals_output['theo_pnl_list'][4] ratio_target5_list[i] = bf_signals_output['ratio_target_list'][0] ratio_target10_list[i] = bf_signals_output['ratio_target_list'][1] ratio_target15_list[i] = bf_signals_output['ratio_target_list'][2] ratio_target20_list[i] = bf_signals_output['ratio_target_list'][3] ratio_target25_list[i] = bf_signals_output['ratio_target_list'][4] price_1_list[i] = bf_signals_output['price_1'] price_2_list[i] = bf_signals_output['price_2'] price_3_list[i] = bf_signals_output['price_3'] mean_reversion_rsquared_list[i] = bf_signals_output[ 'mean_reversion_rsquared'] mean_reversion_signif_list[i] = bf_signals_output[ 'mean_reversion_signif'] butterflies['Q'] = q_list butterflies['QF'] = qf_list butterflies['z1'] = zscore1_list butterflies['z2'] = zscore2_list butterflies['z3'] = zscore3_list butterflies['z4'] = zscore4_list butterflies['z5'] = zscore5_list butterflies['z6'] = zscore6_list butterflies['z7'] = zscore7_list butterflies['r1'] = rsquared1_list butterflies['r2'] = rsquared2_list butterflies['RC'] = regime_change_list butterflies['seasonality'] = contract_seasonality_list butterflies['yield1'] = yield1_list butterflies['yield2'] = yield2_list butterflies['bf_price'] = bf_price_list butterflies['bf_sell_limit'] = bf_price_sell_limit_list butterflies['bf_buy_limit'] = bf_price_buy_limit_list butterflies['noise_ratio'] = noise_ratio_list butterflies['alpha1'] = alpha1_list butterflies['alpha2'] = alpha2_list butterflies['residual_std1'] = residual_std1_list butterflies['residual_std2'] = residual_std2_list butterflies['second_spread_weight_1'] = second_spread_weight_1_list butterflies['second_spread_weight_2'] = second_spread_weight_2_list butterflies['weight1'] = weight1_list butterflies['weight2'] = weight2_list butterflies['weight3'] = weight3_list butterflies['downside'] = downside_list butterflies['upside'] = upside_list butterflies['recent_5day_pnl'] = recent_5day_pnl_list butterflies['recent_vol_ratio'] = recent_vol_ratio_list butterflies['theo_pnl'] = theo_pnl_list butterflies['theo_pnl5'] = theo_pnl5_list butterflies['theo_pnl10'] = theo_pnl10_list butterflies['theo_pnl15'] = theo_pnl15_list butterflies['theo_pnl20'] = theo_pnl20_list butterflies['theo_pnl25'] = theo_pnl25_list butterflies['ratio_target5'] = ratio_target5_list butterflies['ratio_target10'] = ratio_target10_list butterflies['ratio_target15'] = ratio_target15_list butterflies['ratio_target20'] = ratio_target20_list butterflies['ratio_target25'] = ratio_target25_list butterflies['price1'] = price_1_list butterflies['price2'] = price_2_list butterflies['price3'] = price_3_list butterflies['mean_reversion_rsquared'] = mean_reversion_rsquared_list butterflies['mean_reversion_signif'] = mean_reversion_signif_list butterflies['z1'] = butterflies['z1'].round(2) butterflies['z2'] = butterflies['z2'].round(2) butterflies['z3'] = butterflies['z3'].round(2) butterflies['z4'] = butterflies['z4'].round(2) butterflies['z5'] = butterflies['z5'].round(2) butterflies['z6'] = butterflies['z6'].round(2) butterflies['z7'] = butterflies['z7'].round(2) butterflies['r1'] = butterflies['r1'].round(2) butterflies['r2'] = butterflies['r2'].round(2) butterflies['RC'] = butterflies['RC'].round(2) butterflies['seasonality'] = butterflies['seasonality'].round(2) butterflies['second_spread_weight_1'] = butterflies[ 'second_spread_weight_1'].round(2) butterflies['second_spread_weight_2'] = butterflies[ 'second_spread_weight_1'].round(2) butterflies['yield1'] = butterflies['yield1'].round(3) butterflies['yield2'] = butterflies['yield2'].round(3) butterflies['noise_ratio'] = butterflies['noise_ratio'].round(3) butterflies['alpha1'] = butterflies['alpha1'].round(3) butterflies['alpha2'] = butterflies['alpha2'].round(3) butterflies['residual_std1'] = butterflies['residual_std1'].round(3) butterflies['residual_std2'] = butterflies['residual_std2'].round(3) butterflies['downside'] = butterflies['downside'].round(3) butterflies['upside'] = butterflies['upside'].round(3) butterflies['recent_5day_pnl'] = butterflies['recent_5day_pnl'].round(3) butterflies['recent_vol_ratio'] = butterflies['recent_vol_ratio'].round(2) butterflies['theo_pnl'] = butterflies['theo_pnl'].round(3) butterflies['price1'] = butterflies['price1'].round(4) butterflies['price2'] = butterflies['price2'].round(4) butterflies['price3'] = butterflies['price3'].round(4) butterflies['mean_reversion_rsquared'] = butterflies[ 'mean_reversion_rsquared'].round(2) butterflies.to_pickle(output_dir + '/summary.pkl') return {'butterflies': butterflies, 'success': True}
def get_results_4strategy(**kwargs): signal_input = dict() if 'futures_data_dictionary' in kwargs.keys(): signal_input['futures_data_dictionary'] = kwargs[ 'futures_data_dictionary'] if 'date_to' in kwargs.keys(): date_to = kwargs['date_to'] else: date_to = exp.doubledate_shift_bus_days() if 'datetime5_years_ago' in kwargs.keys(): signal_input['datetime5_years_ago'] = kwargs['datetime5_years_ago'] if 'strategy_info_output' in kwargs.keys(): strategy_info_output = kwargs['strategy_info_output'] else: strategy_info_output = ts.get_strategy_info_from_alias(**kwargs) if 'broker' in kwargs.keys(): broker = kwargs['broker'] else: broker = 'abn' con = msu.get_my_sql_connection(**kwargs) strategy_info_dict = sc.convert_from_string_to_dictionary( string_input=strategy_info_output['description_string']) strategy_class = strategy_info_dict['strategy_class'] pnl_frame = tpm.get_daily_pnl_snapshot(as_of_date=date_to, broker=broker) pnl_frame = pnl_frame[pnl_frame['alias'] == kwargs['alias']] strategy_position = ts.get_net_position_4strategy_alias( alias=kwargs['alias'], as_of_date=date_to) if strategy_class == 'futures_butterfly': ticker_head = cmi.get_contract_specs( strategy_info_dict['ticker1'])['ticker_head'] if not strategy_position.empty: total_contracts2trade = strategy_position['qty'].abs().sum() t_cost = cmi.t_cost[ticker_head] QF_initial = float(strategy_info_dict['QF']) z1_initial = float(strategy_info_dict['z1']) bf_signals_output = fs.get_futures_butterfly_signals( ticker_list=[ strategy_info_dict['ticker1'], strategy_info_dict['ticker2'], strategy_info_dict['ticker3'] ], aggregation_method=int(strategy_info_dict['agg']), contracts_back=int(strategy_info_dict['cBack']), date_to=date_to, **signal_input) if bf_signals_output['success']: aligned_output = bf_signals_output['aligned_output'] current_data = aligned_output['current_data'] holding_tr_dte = int( strategy_info_dict['trDte1']) - current_data['c1']['tr_dte'] success_status = True QF = bf_signals_output['qf'] z1 = bf_signals_output['zscore1'] short_tr_dte = current_data['c1']['tr_dte'] second_spread_weight = bf_signals_output['second_spread_weight_1'] if strategy_position.empty: recommendation = 'CLOSE' elif (z1_initial>0)&(holding_tr_dte > 5) &\ (bf_signals_output['qf']<QF_initial-20)&\ (pnl_frame['total_pnl'].iloc[0] > 3*t_cost*total_contracts2trade): recommendation = 'STOP' elif (z1_initial<0)&(holding_tr_dte > 5) &\ (bf_signals_output['qf']>QF_initial+20)&\ (pnl_frame['total_pnl'].iloc[0] > 3*t_cost*total_contracts2trade): recommendation = 'STOP' elif (current_data['c1']['tr_dte'] < 35)&\ (pnl_frame['total_pnl'].iloc[0] > 3*t_cost*total_contracts2trade): recommendation = 'STOP' elif (current_data['c1']['tr_dte'] < 35)&\ (pnl_frame['total_pnl'].iloc[0] < 3*t_cost*total_contracts2trade): recommendation = 'WINDDOWN' else: recommendation = 'HOLD' else: success_status = False QF = np.nan z1 = np.nan short_tr_dte = np.nan holding_tr_dte = np.nan second_spread_weight = np.nan recommendation = 'MISSING DATA' result_output = { 'success': success_status, 'ticker_head': ticker_head, 'QF_initial': QF_initial, 'z1_initial': z1_initial, 'QF': QF, 'z1': z1, 'short_tr_dte': short_tr_dte, 'holding_tr_dte': holding_tr_dte, 'second_spread_weight': second_spread_weight, 'recommendation': recommendation } elif strategy_class == 'spread_carry': trades4_strategy = ts.get_trades_4strategy_alias(**kwargs) grouped = trades4_strategy.groupby('ticker') net_position = pd.DataFrame() net_position['ticker'] = (grouped['ticker'].first()).values net_position['qty'] = (grouped['trade_quantity'].sum()).values net_position = net_position[net_position['qty'] != 0] net_position['ticker_head'] = [ cmi.get_contract_specs(x)['ticker_head'] for x in net_position['ticker'] ] price_output = [ gfp.get_futures_price_preloaded(ticker=x, settle_date=date_to) for x in net_position['ticker'] ] net_position['tr_dte'] = [ np.nan if x.empty else x['tr_dte'].values[0] for x in price_output ] results_frame = pd.DataFrame() unique_tickerhead_list = net_position['ticker_head'].unique() results_frame['tickerHead'] = unique_tickerhead_list results_frame['ticker1'] = [None] * len(unique_tickerhead_list) results_frame['ticker2'] = [None] * len(unique_tickerhead_list) results_frame['qty'] = [None] * len(unique_tickerhead_list) results_frame['pnl'] = [None] * len(unique_tickerhead_list) results_frame['downside'] = [None] * len(unique_tickerhead_list) results_frame['indicator'] = [None] * len(unique_tickerhead_list) results_frame['timeHeld'] = [None] * len(unique_tickerhead_list) results_frame['recommendation'] = [None] * len(unique_tickerhead_list) spread_carry_output = osc.generate_spread_carry_sheet_4date( report_date=date_to) spread_report = spread_carry_output['spread_report'] pnl_output = tpnl.get_strategy_pnl(**kwargs) pnl_per_tickerhead = pnl_output['pnl_per_tickerhead'] for i in range(len(unique_tickerhead_list)): net_position_per_tickerhead = net_position[ net_position['ticker_head'] == unique_tickerhead_list[i]] net_position_per_tickerhead.sort_values('tr_dte', ascending=True, inplace=True) selected_spread = spread_report[ (spread_report['ticker1'] == net_position_per_tickerhead['ticker'].values[0]) & (spread_report['ticker2'] == net_position_per_tickerhead['ticker'].values[1])] results_frame['qty'][i] = net_position_per_tickerhead[ 'qty'].values[0] if selected_spread.empty: results_frame['ticker1'][i] = net_position_per_tickerhead[ 'ticker'].values[0] results_frame['ticker2'][i] = net_position_per_tickerhead[ 'ticker'].values[1] else: results_frame['ticker1'][i] = selected_spread[ 'ticker1'].values[0] results_frame['ticker2'][i] = selected_spread[ 'ticker2'].values[0] selected_trades = trades4_strategy[ trades4_strategy['ticker'] == results_frame['ticker1'].values[i]] price_output = gfp.get_futures_price_preloaded( ticker=results_frame['ticker1'].values[i], settle_date=pd.to_datetime( selected_trades['trade_date'].values[0])) results_frame['timeHeld'][i] = price_output['tr_dte'].values[ 0] - net_position_per_tickerhead['tr_dte'].values[0] results_frame['pnl'][i] = pnl_per_tickerhead[ unique_tickerhead_list[i]].sum() if unique_tickerhead_list[i] in ['CL', 'B', 'ED']: results_frame['indicator'][i] = selected_spread[ 'reward_risk'].values[0] if results_frame['qty'][i] > 0: results_frame['recommendation'][i] = 'STOP' elif results_frame['qty'][i] < 0: if results_frame['indicator'][i] > -0.06: results_frame['recommendation'][i] = 'STOP' else: results_frame['recommendation'][i] = 'HOLD' else: results_frame['indicator'][i] = selected_spread[ 'q_carry'].values[0] if results_frame['qty'][i] > 0: if results_frame['indicator'][i] < 19: results_frame['recommendation'][i] = 'STOP' else: results_frame['recommendation'][i] = 'HOLD' elif results_frame['qty'][i] < 0: if results_frame['indicator'][i] > -9: results_frame['recommendation'][i] = 'STOP' else: results_frame['recommendation'][i] = 'HOLD' if results_frame['qty'][i] > 0: results_frame['downside'][i] = selected_spread[ 'downside'].values[0] * results_frame['qty'][i] else: results_frame['downside'][i] = selected_spread[ 'upside'].values[0] * results_frame['qty'][i] return {'success': True, 'results_frame': results_frame} elif strategy_class == 'vcs': greeks_out = sg.get_greeks_4strategy_4date(alias=kwargs['alias'], as_of_date=date_to) ticker_portfolio = greeks_out['ticker_portfolio'] options_position = greeks_out['options_position'] if ticker_portfolio.empty and not options_position.empty: result_output = { 'success': False, 'net_oev': np.NaN, 'net_theta': np.NaN, 'long_short_ratio': np.NaN, 'recommendation': 'MISSING DATA', 'last_adjustment_days_ago': np.NaN, 'min_tr_dte': np.NaN, 'long_oev': np.NaN, 'short_oev': np.NaN, 'favQMove': np.NaN } elif ticker_portfolio.empty and options_position.empty: result_output = { 'success': False, 'net_oev': np.NaN, 'net_theta': np.NaN, 'long_short_ratio': np.NaN, 'recommendation': 'EMPTY', 'last_adjustment_days_ago': np.NaN, 'min_tr_dte': np.NaN, 'long_oev': np.NaN, 'short_oev': np.NaN, 'favQMove': np.NaN } else: min_tr_dte = min([ exp.get_days2_expiration(ticker=x, date_to=date_to, instrument='options', con=con)['tr_dte'] for x in ticker_portfolio['ticker'] ]) net_oev = ticker_portfolio['total_oev'].sum() net_theta = ticker_portfolio['theta'].sum() long_portfolio = ticker_portfolio[ ticker_portfolio['total_oev'] > 0] short_portfolio = ticker_portfolio[ ticker_portfolio['total_oev'] < 0] short_portfolio['total_oev'] = abs(short_portfolio['total_oev']) long_oev = long_portfolio['total_oev'].sum() short_oev = short_portfolio['total_oev'].sum() if (not short_portfolio.empty) & (not long_portfolio.empty): long_short_ratio = 100 * long_oev / short_oev long_portfolio.sort_values('total_oev', ascending=False, inplace=True) short_portfolio.sort_values('total_oev', ascending=False, inplace=True) long_ticker = long_portfolio['ticker'].iloc[0] short_ticker = short_portfolio['ticker'].iloc[0] long_contract_specs = cmi.get_contract_specs(long_ticker) short_contract_specs = cmi.get_contract_specs(short_ticker) if 12*long_contract_specs['ticker_year']+long_contract_specs['ticker_month_num'] < \ 12*short_contract_specs['ticker_year']+short_contract_specs['ticker_month_num']: front_ticker = long_ticker back_ticker = short_ticker direction = 'long' else: front_ticker = short_ticker back_ticker = long_ticker direction = 'short' if 'vcs_output' in kwargs.keys(): vcs_output = kwargs['vcs_output'] else: vcs_output = ovcs.generate_vcs_sheet_4date(date_to=date_to) vcs_pairs = vcs_output['vcs_pairs'] selected_result = vcs_pairs[ (vcs_pairs['ticker1'] == front_ticker) & (vcs_pairs['ticker2'] == back_ticker)] if selected_result.empty: favQMove = np.NaN else: current_Q = selected_result['Q'].iloc[0] q_limit = of.get_vcs_filter_values( product_group=long_contract_specs['ticker_head'], filter_type='tickerHead', direction=direction, indicator='Q') if direction == 'long': favQMove = current_Q - q_limit elif direction == 'short': favQMove = q_limit - current_Q else: long_short_ratio = np.NaN favQMove = np.NaN trades_frame = ts.get_trades_4strategy_alias(**kwargs) trades_frame_options = trades_frame[trades_frame['instrument'] == 'O'] last_adjustment_days_ago = len( exp.get_bus_day_list( date_to=date_to, datetime_from=max( trades_frame_options['trade_date']).to_pydatetime())) if favQMove >= 10 and last_adjustment_days_ago > 10: recommendation = 'STOP-ratio normalized' elif min_tr_dte < 25: recommendation = 'STOP-close to expiration' elif np.isnan(long_short_ratio): recommendation = 'STOP-not a proper calendar' else: if long_short_ratio < 80: if favQMove < 0: recommendation = 'buy_options_to_grow' else: recommendation = 'buy_options_to_shrink' elif long_short_ratio > 120: if favQMove < 0: recommendation = 'sell_options_to_grow' else: recommendation = 'sell_options_to_shrink' else: recommendation = 'HOLD' result_output = { 'success': True, 'net_oev': net_oev, 'net_theta': net_theta, 'long_short_ratio': long_short_ratio, 'recommendation': recommendation, 'last_adjustment_days_ago': last_adjustment_days_ago, 'min_tr_dte': min_tr_dte, 'long_oev': long_oev, 'short_oev': short_oev, 'favQMove': favQMove } elif strategy_class == 'ocs': datetime_to = cu.convert_doubledate_2datetime(date_to) time_held = (datetime_to.date() - strategy_info_output['created_date'].date()).days notes = '' strategy_position = ts.get_net_position_4strategy_alias( alias=kwargs['alias'], as_of_date=date_to, con=con) if len(strategy_position.index) == 0: tpnl.close_strategy(alias=kwargs['alias'], close_date=date_to, broker=broker, con=con) result_output = { 'success': True, 'time_held': time_held, 'dollar_noise': np.nan, 'notes': 'closed' } elif strategy_position['qty'].sum() != 0: result_output = { 'success': True, 'time_held': time_held, 'dollar_noise': np.nan, 'notes': 'check position' } else: strategy_position['cont_indx'] = [ cmi.get_contract_specs(x)['cont_indx'] for x in strategy_position['ticker'] ] strategy_position.sort_values('cont_indx', ascending=True, inplace=True) ocs_output = ocs.generate_overnight_spreads_sheet_4date( date_to=date_to) overnight_calendars = ocs_output['overnight_calendars'] selection_indx = (overnight_calendars['ticker1'] == strategy_position['ticker'].iloc[0])&\ (overnight_calendars['ticker2'] == strategy_position['ticker'].iloc[1]) if sum(selection_indx) > 0: dollar_noise = (overnight_calendars.loc[ selection_indx, 'dollarNoise100'].values[0]) * abs( strategy_position['qty'].iloc[0]) else: dollar_noise = np.nan result_output = { 'success': True, 'time_held': time_held, 'dollar_noise': dollar_noise, 'notes': 'hold' } elif strategy_class == 'skpt': long_ticker = strategy_position.loc[strategy_position['qty'] > 0, 'ticker'].iloc[0] short_ticker = strategy_position.loc[strategy_position['qty'] < 0, 'ticker'].iloc[0] long_data = gsp.get_stock_price_preloaded(ticker=long_ticker, data_source='iex', settle_date_to=date_to) short_data = gsp.get_stock_price_preloaded(ticker=short_ticker, data_source='iex', settle_date_to=date_to) merged_data = pd.merge(long_data[['close', 'settle_datetime']], short_data[['close', 'settle_datetime']], how='inner', on='settle_datetime') merged_data.set_index('settle_datetime', drop=True, inplace=True) intaday_output_long = pweb.DataReader(long_ticker, 'iex-tops') intaday_output_short = pweb.DataReader(short_ticker, 'iex-tops') merged_data = merged_data.append( pd.DataFrame( { 'close_x': intaday_output_long.iloc[4].values[0], 'close_y': intaday_output_short.iloc[4].values[0] }, index=[dt.datetime.now()])) signal_output = spt.backtest(merged_data, 'close_x', 'close_y') return { 'long_ticker': long_ticker, 'short_ticker': short_ticker, 'zScoreC': signal_output['data_frame']['zScore'].iloc[-1], 'zScore': signal_output['data_frame']['zScore'].iloc[-2] } else: result_output = {'success': False} if 'con' not in kwargs.keys(): con.close() return result_output
def generate_futures_butterfly_sheet_4date(**kwargs): date_to = kwargs['date_to'] output_dir = ts.create_strategy_output_dir(strategy_class='futures_butterfly', report_date=date_to) if os.path.isfile(output_dir + '/summary.pkl'): butterflies = pd.read_pickle(output_dir + '/summary.pkl') return {'butterflies': butterflies,'success': True} if 'volume_filter' not in kwargs.keys(): kwargs['volume_filter'] = 100 butterflies = get_futures_butterflies_4date(**kwargs) butterflies = butterflies[butterflies['trDte1'] >= 35] butterflies.reset_index(drop=True,inplace=True) num_butterflies = len(butterflies) q_list = [None]*num_butterflies qf_list = [None]*num_butterflies zscore1_list = [None]*num_butterflies zscore2_list = [None]*num_butterflies zscore3_list = [None]*num_butterflies zscore4_list = [None]*num_butterflies zscore5_list = [None]*num_butterflies zscore6_list = [None]*num_butterflies zscore7_list = [None]*num_butterflies rsquared1_list = [None]*num_butterflies rsquared2_list = [None]*num_butterflies regime_change_list = [None]*num_butterflies contract_seasonality_list = [None]*num_butterflies yield1_list = [None]*num_butterflies yield2_list = [None]*num_butterflies bf_price_list = [None]*num_butterflies bf_price_sell_limit_list = [None]*num_butterflies bf_price_buy_limit_list = [None]*num_butterflies noise_ratio_list = [None]*num_butterflies alpha1_list = [None]*num_butterflies alpha2_list = [None]*num_butterflies residual_std1_list = [None]*num_butterflies residual_std2_list = [None]*num_butterflies second_spread_weight_1_list = [None]*num_butterflies second_spread_weight_2_list = [None]*num_butterflies weight1_list = [None]*num_butterflies weight2_list = [None]*num_butterflies weight3_list = [None]*num_butterflies downside_list = [None]*num_butterflies upside_list = [None]*num_butterflies recent_5day_pnl_list = [None]*num_butterflies recent_vol_ratio_list = [None]*num_butterflies theo_pnl_list = [None]*num_butterflies theo_pnl5_list = [None]*num_butterflies theo_pnl10_list = [None]*num_butterflies theo_pnl15_list = [None]*num_butterflies theo_pnl20_list = [None]*num_butterflies theo_pnl25_list = [None]*num_butterflies ratio_target5_list = [None]*num_butterflies ratio_target10_list = [None]*num_butterflies ratio_target15_list = [None]*num_butterflies ratio_target20_list = [None]*num_butterflies ratio_target25_list = [None]*num_butterflies price_1_list = [None]*num_butterflies price_2_list = [None]*num_butterflies price_3_list = [None]*num_butterflies mean_reversion_rsquared_list = [None]*num_butterflies mean_reversion_signif_list = [None]*num_butterflies futures_data_dictionary = {x: gfp.get_futures_price_preloaded(ticker_head=x) for x in cmi.futures_butterfly_strategy_tickerhead_list} date5_years_ago = cu.doubledate_shift(date_to,5*365) datetime5_years_ago = cu.convert_doubledate_2datetime(date5_years_ago) for i in range(num_butterflies): bf_signals_output = fs.get_futures_butterfly_signals(ticker_list=[butterflies['ticker1'][i], butterflies['ticker2'][i], butterflies['ticker3'][i]], tr_dte_list=[butterflies['trDte1'][i], butterflies['trDte2'][i], butterflies['trDte3'][i]], aggregation_method=butterflies['agg'][i], contracts_back=butterflies['cBack'][i], date_to=date_to, futures_data_dictionary=futures_data_dictionary, contract_multiplier=butterflies['multiplier'][i], datetime5_years_ago=datetime5_years_ago) q_list[i] = bf_signals_output['q'] qf_list[i] = bf_signals_output['qf'] zscore1_list[i] = bf_signals_output['zscore1'] zscore2_list[i] = bf_signals_output['zscore2'] zscore3_list[i] = bf_signals_output['zscore3'] zscore4_list[i] = bf_signals_output['zscore4'] zscore5_list[i] = bf_signals_output['zscore5'] zscore6_list[i] = bf_signals_output['zscore6'] zscore7_list[i] = bf_signals_output['zscore7'] rsquared1_list[i] = bf_signals_output['rsquared1'] rsquared2_list[i] = bf_signals_output['rsquared2'] regime_change_list[i] = bf_signals_output['regime_change_ind'] contract_seasonality_list[i] = bf_signals_output['contract_seasonality_ind'] yield1_list[i] = bf_signals_output['yield1_current'] yield2_list[i] = bf_signals_output['yield2_current'] bf_price_list[i] = bf_signals_output['bf_price'] bf_price_sell_limit_list[i] = bf_signals_output['short_price_limit'] bf_price_buy_limit_list[i] = bf_signals_output['long_price_limit'] noise_ratio_list[i] = bf_signals_output['noise_ratio'] alpha1_list[i] = bf_signals_output['alpha1'] alpha2_list[i] = bf_signals_output['alpha2'] residual_std1_list = bf_signals_output['residual_std1'] residual_std2_list = bf_signals_output['residual_std2'] second_spread_weight_1_list[i] = bf_signals_output['second_spread_weight_1'] second_spread_weight_2_list[i] = bf_signals_output['second_spread_weight_2'] weight1_list[i] = bf_signals_output['weight1'] weight2_list[i] = bf_signals_output['weight2'] weight3_list[i] = bf_signals_output['weight3'] downside_list[i] = bf_signals_output['downside'] upside_list[i] = bf_signals_output['upside'] recent_5day_pnl_list[i] = bf_signals_output['recent_5day_pnl'] recent_vol_ratio_list[i] = bf_signals_output['recent_vol_ratio'] theo_pnl_list[i] = bf_signals_output['theo_pnl'] theo_pnl5_list[i] = bf_signals_output['theo_pnl_list'][0] theo_pnl10_list[i] = bf_signals_output['theo_pnl_list'][1] theo_pnl15_list[i] = bf_signals_output['theo_pnl_list'][2] theo_pnl20_list[i] = bf_signals_output['theo_pnl_list'][3] theo_pnl25_list[i] = bf_signals_output['theo_pnl_list'][4] ratio_target5_list[i] = bf_signals_output['ratio_target_list'][0] ratio_target10_list[i] = bf_signals_output['ratio_target_list'][1] ratio_target15_list[i] = bf_signals_output['ratio_target_list'][2] ratio_target20_list[i] = bf_signals_output['ratio_target_list'][3] ratio_target25_list[i] = bf_signals_output['ratio_target_list'][4] price_1_list[i] = bf_signals_output['price_1'] price_2_list[i] = bf_signals_output['price_2'] price_3_list[i] = bf_signals_output['price_3'] mean_reversion_rsquared_list[i] = bf_signals_output['mean_reversion_rsquared'] mean_reversion_signif_list[i] = bf_signals_output['mean_reversion_signif'] butterflies['Q'] = q_list butterflies['QF'] = qf_list butterflies['z1'] = zscore1_list butterflies['z2'] = zscore2_list butterflies['z3'] = zscore3_list butterflies['z4'] = zscore4_list butterflies['z5'] = zscore5_list butterflies['z6'] = zscore6_list butterflies['z7'] = zscore7_list butterflies['r1'] = rsquared1_list butterflies['r2'] = rsquared2_list butterflies['RC'] = regime_change_list butterflies['seasonality'] = contract_seasonality_list butterflies['yield1'] = yield1_list butterflies['yield2'] = yield2_list butterflies['bf_price'] = bf_price_list butterflies['bf_sell_limit'] = bf_price_sell_limit_list butterflies['bf_buy_limit'] = bf_price_buy_limit_list butterflies['noise_ratio'] = noise_ratio_list butterflies['alpha1'] = alpha1_list butterflies['alpha2'] = alpha2_list butterflies['residual_std1'] = residual_std1_list butterflies['residual_std2'] = residual_std2_list butterflies['second_spread_weight_1'] = second_spread_weight_1_list butterflies['second_spread_weight_2'] = second_spread_weight_2_list butterflies['weight1'] = weight1_list butterflies['weight2'] = weight2_list butterflies['weight3'] = weight3_list butterflies['downside'] = downside_list butterflies['upside'] = upside_list butterflies['recent_5day_pnl'] = recent_5day_pnl_list butterflies['recent_vol_ratio'] = recent_vol_ratio_list butterflies['theo_pnl'] = theo_pnl_list butterflies['theo_pnl5'] = theo_pnl5_list butterflies['theo_pnl10'] = theo_pnl10_list butterflies['theo_pnl15'] = theo_pnl15_list butterflies['theo_pnl20'] = theo_pnl20_list butterflies['theo_pnl25'] = theo_pnl25_list butterflies['ratio_target5'] = ratio_target5_list butterflies['ratio_target10'] = ratio_target10_list butterflies['ratio_target15'] = ratio_target15_list butterflies['ratio_target20'] = ratio_target20_list butterflies['ratio_target25'] = ratio_target25_list butterflies['price1'] = price_1_list butterflies['price2'] = price_2_list butterflies['price3'] = price_3_list butterflies['mean_reversion_rsquared'] = mean_reversion_rsquared_list butterflies['mean_reversion_signif'] = mean_reversion_signif_list butterflies['z1'] = butterflies['z1'].round(2) butterflies['z2'] = butterflies['z2'].round(2) butterflies['z3'] = butterflies['z3'].round(2) butterflies['z4'] = butterflies['z4'].round(2) butterflies['z5'] = butterflies['z5'].round(2) butterflies['z6'] = butterflies['z6'].round(2) butterflies['z7'] = butterflies['z7'].round(2) butterflies['r1'] = butterflies['r1'].round(2) butterflies['r2'] = butterflies['r2'].round(2) butterflies['RC'] = butterflies['RC'].round(2) butterflies['seasonality'] = butterflies['seasonality'].round(2) butterflies['second_spread_weight_1'] = butterflies['second_spread_weight_1'].round(2) butterflies['second_spread_weight_2'] = butterflies['second_spread_weight_1'].round(2) butterflies['yield1'] = butterflies['yield1'].round(3) butterflies['yield2'] = butterflies['yield2'].round(3) butterflies['noise_ratio'] = butterflies['noise_ratio'].round(3) butterflies['alpha1'] = butterflies['alpha1'].round(3) butterflies['alpha2'] = butterflies['alpha2'].round(3) butterflies['residual_std1'] = butterflies['residual_std1'].round(3) butterflies['residual_std2'] = butterflies['residual_std2'].round(3) butterflies['downside'] = butterflies['downside'].round(3) butterflies['upside'] = butterflies['upside'].round(3) butterflies['recent_5day_pnl'] = butterflies['recent_5day_pnl'].round(3) butterflies['recent_vol_ratio'] = butterflies['recent_vol_ratio'].round(2) butterflies['theo_pnl'] = butterflies['theo_pnl'].round(3) butterflies['price1'] = butterflies['price1'].round(4) butterflies['price2'] = butterflies['price2'].round(4) butterflies['price3'] = butterflies['price3'].round(4) butterflies['mean_reversion_rsquared'] = butterflies['mean_reversion_rsquared'].round(2) butterflies.to_pickle(output_dir + '/summary.pkl') return {'butterflies': butterflies,'success': True}
def get_results_4strategy(**kwargs): signal_input = dict() if 'futures_data_dictionary' in kwargs.keys(): signal_input['futures_data_dictionary'] = kwargs['futures_data_dictionary'] if 'date_to' in kwargs.keys(): date_to = kwargs['date_to'] else: date_to = exp.doubledate_shift_bus_days() if 'datetime5_years_ago' in kwargs.keys(): signal_input['datetime5_years_ago'] = kwargs['datetime5_years_ago'] if 'strategy_info_output' in kwargs.keys(): strategy_info_output = kwargs['strategy_info_output'] else: strategy_info_output = ts.get_strategy_info_from_alias(**kwargs) con = msu.get_my_sql_connection(**kwargs) strategy_info_dict = sc.convert_from_string_to_dictionary(string_input=strategy_info_output['description_string']) #print(kwargs['alias']) strategy_class = strategy_info_dict['strategy_class'] pnl_frame = tpm.get_daily_pnl_snapshot(as_of_date=date_to) pnl_frame = pnl_frame[pnl_frame['alias']==kwargs['alias']] strategy_position = ts.get_net_position_4strategy_alias(alias=kwargs['alias'],as_of_date=date_to) if strategy_class == 'futures_butterfly': ticker_head = cmi.get_contract_specs(strategy_info_dict['ticker1'])['ticker_head'] if not strategy_position.empty: total_contracts2trade = strategy_position['qty'].abs().sum() t_cost = cmi.t_cost[ticker_head] QF_initial = float(strategy_info_dict['QF']) z1_initial = float(strategy_info_dict['z1']) bf_signals_output = fs.get_futures_butterfly_signals(ticker_list=[strategy_info_dict['ticker1'], strategy_info_dict['ticker2'], strategy_info_dict['ticker3']], aggregation_method=int(strategy_info_dict['agg']), contracts_back=int(strategy_info_dict['cBack']), date_to=date_to,**signal_input) aligned_output = bf_signals_output['aligned_output'] current_data = aligned_output['current_data'] holding_tr_dte = int(strategy_info_dict['trDte1'])-current_data['c1']['tr_dte'] if strategy_position.empty: recommendation = 'CLOSE' elif (z1_initial>0)&(holding_tr_dte > 5) &\ (bf_signals_output['qf']<QF_initial-20)&\ (pnl_frame['total_pnl'].iloc[0] > 3*t_cost*total_contracts2trade): recommendation = 'STOP' elif (z1_initial<0)&(holding_tr_dte > 5) &\ (bf_signals_output['qf']>QF_initial+20)&\ (pnl_frame['total_pnl'].iloc[0] > 3*t_cost*total_contracts2trade): recommendation = 'STOP' elif (current_data['c1']['tr_dte'] < 35)&\ (pnl_frame['total_pnl'].iloc[0] > 3*t_cost*total_contracts2trade): recommendation = 'STOP' elif (current_data['c1']['tr_dte'] < 35)&\ (pnl_frame['total_pnl'].iloc[0] < 3*t_cost*total_contracts2trade): recommendation = 'WINDDOWN' else: recommendation = 'HOLD' result_output = {'success': True,'ticker_head': ticker_head, 'QF_initial':QF_initial,'z1_initial': z1_initial, 'QF': bf_signals_output['qf'],'z1': bf_signals_output['zscore1'], 'short_tr_dte': current_data['c1']['tr_dte'], 'holding_tr_dte': holding_tr_dte, 'second_spread_weight': bf_signals_output['second_spread_weight_1'],'recommendation': recommendation} elif strategy_class == 'spread_carry': trades4_strategy = ts.get_trades_4strategy_alias(**kwargs) grouped = trades4_strategy.groupby('ticker') net_position = pd.DataFrame() net_position['ticker'] = (grouped['ticker'].first()).values net_position['qty'] = (grouped['trade_quantity'].sum()).values net_position = net_position[net_position['qty'] != 0] net_position['ticker_head'] = [cmi.get_contract_specs(x)['ticker_head'] for x in net_position['ticker']] price_output = [gfp.get_futures_price_preloaded(ticker=x, settle_date=date_to) for x in net_position['ticker']] net_position['tr_dte'] = [x['tr_dte'].values[0] for x in price_output] results_frame = pd.DataFrame() unique_tickerhead_list = net_position['ticker_head'].unique() results_frame['tickerHead'] = unique_tickerhead_list results_frame['ticker1'] = [None]*len(unique_tickerhead_list) results_frame['ticker2'] = [None]*len(unique_tickerhead_list) results_frame['qty'] = [None]*len(unique_tickerhead_list) results_frame['pnl'] = [None]*len(unique_tickerhead_list) results_frame['downside'] = [None]*len(unique_tickerhead_list) results_frame['indicator'] = [None]*len(unique_tickerhead_list) results_frame['timeHeld'] = [None]*len(unique_tickerhead_list) results_frame['recommendation'] = [None]*len(unique_tickerhead_list) spread_carry_output = osc.generate_spread_carry_sheet_4date(report_date=date_to) spread_report = spread_carry_output['spread_report'] pnl_output = tpnl.get_strategy_pnl(**kwargs) pnl_per_tickerhead = pnl_output['pnl_per_tickerhead'] for i in range(len(unique_tickerhead_list)): net_position_per_tickerhead = net_position[net_position['ticker_head'] == unique_tickerhead_list[i]] net_position_per_tickerhead.sort('tr_dte',ascending=True,inplace=True) selected_spread = spread_report[(spread_report['ticker1'] == net_position_per_tickerhead['ticker'].values[0]) & (spread_report['ticker2'] == net_position_per_tickerhead['ticker'].values[1])] results_frame['ticker1'][i] = selected_spread['ticker1'].values[0] results_frame['ticker2'][i] = selected_spread['ticker2'].values[0] results_frame['qty'][i] = net_position_per_tickerhead['qty'].values[0] selected_trades = trades4_strategy[trades4_strategy['ticker'] == results_frame['ticker1'].values[i]] price_output = gfp.get_futures_price_preloaded(ticker=results_frame['ticker1'].values[i], settle_date=pd.to_datetime(selected_trades['trade_date'].values[0])) results_frame['timeHeld'][i] = price_output['tr_dte'].values[0]-net_position_per_tickerhead['tr_dte'].values[0] results_frame['pnl'][i] = pnl_per_tickerhead[unique_tickerhead_list[i]].sum() if unique_tickerhead_list[i] in ['CL', 'B', 'ED']: results_frame['indicator'][i] = selected_spread['reward_risk'].values[0] if results_frame['qty'][i] > 0: results_frame['recommendation'][i] = 'STOP' elif results_frame['qty'][i] < 0: if results_frame['indicator'][i] > -0.06: results_frame['recommendation'][i] = 'STOP' else: results_frame['recommendation'][i] = 'HOLD' else: results_frame['indicator'][i] = selected_spread['q_carry'].values[0] if results_frame['qty'][i] > 0: if results_frame['indicator'][i] < 19: results_frame['recommendation'][i] = 'STOP' else: results_frame['recommendation'][i] = 'HOLD' elif results_frame['qty'][i] < 0: if results_frame['indicator'][i] > -9: results_frame['recommendation'][i] = 'STOP' else: results_frame['recommendation'][i] = 'HOLD' if results_frame['qty'][i] > 0: results_frame['downside'][i] = selected_spread['downside'].values[0]*results_frame['qty'][i] else: results_frame['downside'][i] = selected_spread['upside'].values[0]*results_frame['qty'][i] return {'success': True, 'results_frame': results_frame} elif strategy_class == 'vcs': greeks_out = sg.get_greeks_4strategy_4date(alias=kwargs['alias'], as_of_date=date_to) ticker_portfolio = greeks_out['ticker_portfolio'] if ticker_portfolio.empty: min_tr_dte = np.NaN result_output = {'success': False, 'net_oev': np.NaN, 'net_theta': np.NaN, 'long_short_ratio': np.NaN, 'recommendation': 'EMPTY', 'last_adjustment_days_ago': np.NaN, 'min_tr_dte': np.NaN, 'long_oev': np.NaN, 'short_oev': np.NaN, 'favQMove': np.NaN} else: min_tr_dte = min([exp.get_days2_expiration(ticker=x,date_to=date_to,instrument='options',con=con)['tr_dte'] for x in ticker_portfolio['ticker']]) net_oev = ticker_portfolio['total_oev'].sum() net_theta = ticker_portfolio['theta'].sum() long_portfolio = ticker_portfolio[ticker_portfolio['total_oev'] > 0] short_portfolio = ticker_portfolio[ticker_portfolio['total_oev'] < 0] short_portfolio['total_oev']=abs(short_portfolio['total_oev']) long_oev = long_portfolio['total_oev'].sum() short_oev = short_portfolio['total_oev'].sum() if (not short_portfolio.empty) & (not long_portfolio.empty): long_short_ratio = 100*long_oev/short_oev long_portfolio.sort('total_oev', ascending=False, inplace=True) short_portfolio.sort('total_oev', ascending=False, inplace=True) long_ticker = long_portfolio['ticker'].iloc[0] short_ticker = short_portfolio['ticker'].iloc[0] long_contract_specs = cmi.get_contract_specs(long_ticker) short_contract_specs = cmi.get_contract_specs(short_ticker) if 12*long_contract_specs['ticker_year']+long_contract_specs['ticker_month_num'] < \ 12*short_contract_specs['ticker_year']+short_contract_specs['ticker_month_num']: front_ticker = long_ticker back_ticker = short_ticker direction = 'long' else: front_ticker = short_ticker back_ticker = long_ticker direction = 'short' if 'vcs_output' in kwargs.keys(): vcs_output = kwargs['vcs_output'] else: vcs_output = ovcs.generate_vcs_sheet_4date(date_to=date_to) vcs_pairs = vcs_output['vcs_pairs'] selected_result = vcs_pairs[(vcs_pairs['ticker1'] == front_ticker) & (vcs_pairs['ticker2'] == back_ticker)] if selected_result.empty: favQMove = np.NaN else: current_Q = selected_result['Q'].iloc[0] q_limit = of.get_vcs_filter_values(product_group=long_contract_specs['ticker_head'], filter_type='tickerHead',direction=direction,indicator='Q') if direction == 'long': favQMove = current_Q-q_limit elif direction == 'short': favQMove = q_limit-current_Q else: long_short_ratio = np.NaN favQMove = np.NaN trades_frame = ts.get_trades_4strategy_alias(**kwargs) trades_frame_options = trades_frame[trades_frame['instrument'] == 'O'] last_adjustment_days_ago = len(exp.get_bus_day_list(date_to=date_to,datetime_from=max(trades_frame_options['trade_date']).to_datetime())) if favQMove >= 10 and last_adjustment_days_ago > 10: recommendation = 'STOP-ratio normalized' elif min_tr_dte<25: recommendation = 'STOP-close to expiration' elif np.isnan(long_short_ratio): recommendation = 'STOP-not a proper calendar' else: if long_short_ratio < 80: if favQMove < 0: recommendation = 'buy_options_to_grow' else: recommendation = 'buy_options_to_shrink' elif long_short_ratio > 120: if favQMove < 0: recommendation = 'sell_options_to_grow' else: recommendation = 'sell_options_to_shrink' else: recommendation = 'HOLD' result_output = {'success': True, 'net_oev': net_oev, 'net_theta': net_theta, 'long_short_ratio': long_short_ratio, 'recommendation': recommendation, 'last_adjustment_days_ago': last_adjustment_days_ago, 'min_tr_dte': min_tr_dte, 'long_oev': long_oev, 'short_oev': short_oev, 'favQMove': favQMove} else: result_output = {'success': False} if 'con' not in kwargs.keys(): con.close() return result_output