Exemple #1
0
def main():
    app = algo.Algo()
    con = msu.get_my_sql_connection()
    date_now = cu.get_doubledate()
    datetime_now = dt.datetime.now()
    report_date = exp.doubledate_shift_bus_days()

    ticker_head_list = ['HO', 'LC', 'FC', 'NQ']  # avoid HO on wednesdays for now!!

    data_list = [gfp.get_futures_price_preloaded(ticker_head=x, settle_date=report_date) for x in ticker_head_list]
    ticker_frame = pd.concat(data_list)
    ticker_frame.sort(['ticker_head','volume'], ascending=[True, False], inplace=True)
    ticker_frame.drop_duplicates(subset=['ticker_head'], take_last=False, inplace=True)

    ticker_list = list(ticker_frame['ticker'])

    theme_name_list = set([x + '_long' for x in ticker_list]).union(set([x + '_short' for x in ticker_list]))

    alias_portfolio = aup.portfolio(ticker_list=theme_name_list)

    latest_trade_entry_datetime = dt.datetime(datetime_now.year, datetime_now.month, datetime_now.day, 12, 0, 0)
    latest_livestock_exit_datetime = dt.datetime(datetime_now.year, datetime_now.month, datetime_now.day, 13, 55, 0)
    latest_macro_exit_datetime = dt.datetime(datetime_now.year, datetime_now.month, datetime_now.day, 15, 55, 0)

    daily_sd_dictionary = {}

    for i in range(len(ticker_list)):
        daily_data_frame = gfp.get_futures_price_preloaded(ticker=ticker_list[i], settle_date_to=report_date)
        daily_data_frame['close_diff'] = daily_data_frame['close_price'].diff()
        daily_sd_dictionary[ticker_list[i]] = np.std(daily_data_frame['close_diff'].iloc[-40:])

    db_alias = 'itf_' + datetime_now.strftime('%b_%y')
    strategy_frame = ts.get_open_strategies(as_of_date=int(datetime_now.strftime('%Y%m%d')), con=con)

    if db_alias not in strategy_frame.values:
        db_strategy_output = ts.generate_db_strategy_from_alias(alias=db_alias, description_string='strategy_class=itf',con=con)
        db_alias = db_strategy_output['alias']



    app.ticker_list = ticker_list
    app.db_alias = db_alias
    app.tick_size_dictionary = {x:cmi.tick_size[cmi.get_contract_specs(x)['ticker_head']] for x in ticker_list}
    app.daily_sd_dictionary = daily_sd_dictionary
    app.contract_multiplier_dictionary = {x:cmi.contract_multiplier[cmi.get_contract_specs(x)['ticker_head']] for x in ticker_list}
    app.ticker_head_dictionary = {x:cmi.get_contract_specs(x)['ticker_head'] for x in ticker_list}
    app.latest_trade_entry_datetime = latest_trade_entry_datetime
    app.latest_trade_exit_datetime_dictionary = {'HO': latest_macro_exit_datetime, 'LC': latest_livestock_exit_datetime, 'FC': latest_livestock_exit_datetime, 'NQ': latest_macro_exit_datetime}
    app.alias_portfolio = alias_portfolio
    app.output_dir = ts.create_strategy_output_dir(strategy_class='itf', report_date=report_date)
    app.log = lg.get_logger(file_identifier='ib_itf',log_level='INFO')
    app.con = con

    app.connect(client_id=4)
    app.run()
Exemple #2
0
def get_rolling_futures_price(**kwargs):

    if 'roll_tr_dte_aim' in kwargs.keys():
        roll_tr_dte_aim = kwargs['roll_tr_dte_aim']
    else:
        roll_tr_dte_aim = 50

    futures_dataframe = gfp.get_futures_price_preloaded(**kwargs)

    futures_dataframe = futures_dataframe[futures_dataframe['cal_dte'] < 270]
    futures_dataframe.sort_values(['cont_indx', 'settle_date'],
                                  ascending=[True, True],
                                  inplace=True)

    grouped = futures_dataframe.groupby('cont_indx')
    shifted = grouped.shift(1)

    futures_dataframe['log_return'] = np.log(futures_dataframe['close_price'] /
                                             shifted['close_price'])

    futures_dataframe['tr_dte_diff'] = abs(roll_tr_dte_aim -
                                           futures_dataframe['tr_dte'])
    futures_dataframe.sort_values(['settle_date', 'tr_dte_diff'],
                                  ascending=[True, True],
                                  inplace=True)
    futures_dataframe.drop_duplicates('settle_date',
                                      inplace=True,
                                      keep='first')

    return futures_dataframe
Exemple #3
0
def get_backtest_summary(**kwargs):

    futures_data_dictionary = {
        x: gfp.get_futures_price_preloaded(ticker_head=x)
        for x in cmi.futures_butterfly_strategy_tickerhead_list
    }
    date_list = kwargs['date_list']

    if 'use_existing_filesQ' in kwargs.keys():
        use_existing_filesQ = kwargs['use_existing_filesQ']
    else:
        use_existing_filesQ = True

    backtest_output = []

    for report_date in date_list:
        backtest_output.append(
            get_backtest_summary_4_date(
                report_date=report_date,
                futures_data_dictionary=futures_data_dictionary,
                use_existing_filesQ=use_existing_filesQ))

    return {
        'big_data': pd.concat(backtest_output),
        'backtest_output': backtest_output
    }
def calc_realized_vol_4options_ticker(**kwargs):

    ticker = kwargs['ticker']
    contract_specs_output = cmi.get_contract_specs(ticker)

    if contract_specs_output['ticker_class'] in ['Index', 'FX', 'Metal']:
        use_proxy_contract = True
    else:
        use_proxy_contract = False

    if use_proxy_contract:

        if 'futures_data_dictionary' in kwargs.keys():
            futures_data_input = {
                'ticker_head': contract_specs_output['ticker_head'],
                'settle_date': kwargs['settle_date']
            }
            futures_data_input['futures_data_dictionary'] = kwargs[
                'futures_data_dictionary']
            data_out = gfp.get_futures_price_preloaded(**futures_data_input)
            data_out = data_out.reset_index()
            kwargs['ticker'] = data_out['ticker'].loc[
                data_out['volume'].idxmax()]
    else:
        kwargs['ticker'] = omu.get_option_underlying(**kwargs)

    return calc_realized_vol_4futures_ticker(**kwargs)
def generate_spread_carry_sheet_4date(**kwargs):

    report_date = kwargs['report_date']

    output_dir = ts.create_strategy_output_dir(strategy_class='spread_carry', report_date=report_date)

    if os.path.isfile(output_dir + '/summary.pkl'):
        spread_report = pd.read_pickle(output_dir + '/summary.pkl')
        return {'spread_report': spread_report,'success': True}

    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 max_tr_dte_limits.keys()}

    spread_list = [get_spread_carry_4tickerhead(ticker_head=x,report_date=report_date,futures_data_dictionary=futures_data_dictionary) for x in max_tr_dte_limits.keys()]

    success_list = [x['success'] for x in spread_list]
    carry_signals_list = [x['carry_signals'] for x in spread_list]

    spread_report = pd.concat([carry_signals_list[x] for x in range(len(spread_list)) if success_list[x]])

    spread_report['carry'] = spread_report['carry'].round(2)
    spread_report['reward_risk'] = spread_report['reward_risk'].round(2)
    spread_report['upside'] = spread_report['upside'].round(2)
    spread_report['downside'] = spread_report['downside'].round(2)

    spread_report.rename(columns={'ticker_head': 'tickerHead'}, inplace=True)

    spread_report.to_pickle(output_dir + '/summary.pkl')

    return  {'spread_report': spread_report,'success': True}
def backtest_spread_carry(**kwargs):

    date_list = kwargs['date_list']
    risk = 1000

    futures_data_dictionary = {x: gfp.get_futures_price_preloaded(ticker_head=x) for x in sc.max_tr_dte_limits.keys()}

    ticker_head_list = list(sc.max_tr_dte_limits.keys())

    total_pnl_frame = pd.DataFrame({'report_date': date_list})
    total_pnl_frame['portfolio'] = 0
    backtest_output = []

    for i in range(len(ticker_head_list)):
        total_pnl_frame[ticker_head_list[i]] = 0

    for i in range(len(date_list)):
        spread_carry_output = sc.generate_spread_carry_sheet_4date(report_date=date_list[i],futures_data_dictionary=futures_data_dictionary)

        if spread_carry_output['success']:
            daily_sheet = spread_carry_output['spread_report']
        else:
            continue

        backtest_output.append(daily_sheet)

        daily_sheet['q_carry_abs'] = abs(daily_sheet['q_carry'])
        pnl_tickerhead_frame = pd.DataFrame({'ticker_head': ticker_head_list})
        pnl_tickerhead_frame['total_pnl'] = 0

        for j in range(len(ticker_head_list)):
            ticker_head_results = daily_sheet[daily_sheet['tickerHead'] == ticker_head_list[j]]

            if len(ticker_head_results.index)<=1:
                continue

            max_q_carry_abs = ticker_head_results['q_carry_abs'].max()

            if np.isnan(max_q_carry_abs):
                continue

            selected_spread = ticker_head_results.ix[ticker_head_results['q_carry_abs'].idxmax()]

            if selected_spread['q_carry']>0:
                total_pnl_frame[ticker_head_list[j]][i] = selected_spread['change5']*risk/abs(selected_spread['downside'])
                pnl_tickerhead_frame['total_pnl'][j] = total_pnl_frame[ticker_head_list[j]][i]
            elif selected_spread['q_carry']<0:
                total_pnl_frame[ticker_head_list[j]][i] = -selected_spread['change5']*risk/abs(selected_spread['upside'])
                pnl_tickerhead_frame['total_pnl'][j] = total_pnl_frame[ticker_head_list[j]][i]

        total_pnl_frame['portfolio'][i] = pnl_tickerhead_frame['total_pnl'].sum()

    big_data = pd.concat(backtest_output)
    big_data['pnl_long5'] = big_data['change5']*risk/abs(big_data['downside'])
    big_data['pnl_short5'] = -big_data['change5']*risk/abs(big_data['upside'])
    big_data['pnl_final'] = big_data['pnl_long5']
    big_data.loc[big_data['q_carry'] < 0, 'pnl_final'] = big_data.loc[big_data['q_carry'] <0, 'pnl_short5']

    return {'total_pnl_frame': total_pnl_frame, 'big_data': big_data}
def construct_spread_portfolio(**kwargs):

    date_list = kwargs['date_list']
    risk = 1000

    futures_data_dictionary = {x: gfp.get_futures_price_preloaded(ticker_head=x) for x in sc.max_tr_dte_limits.keys()}

    ticker_head_list = list(sc.max_tr_dte_limits.keys())

    total_pnl_frame = pd.DataFrame({'report_date': date_list})
    total_pnl_frame['portfolio'] = 0

    for i in range(len(ticker_head_list)):
        total_pnl_frame[ticker_head_list[i]] = 0

    for i in range(len(date_list)):
        spread_carry_output = sc.generate_spread_carry_sheet_4date(report_date=date_list[i],futures_data_dictionary=futures_data_dictionary)

        if spread_carry_output['success']:
            daily_sheet = spread_carry_output['spread_report']
        else:
            continue

        pnl_tickerhead_frame = pd.DataFrame({'ticker_head': ticker_head_list})
        pnl_tickerhead_frame['buy_mean_pnl'] = 0
        pnl_tickerhead_frame['sell_mean_pnl'] = 0
        pnl_tickerhead_frame['total_pnl'] = 0

        daily_sheet = \
                daily_sheet[(np.isfinite(daily_sheet['change5']))&
                            (np.isfinite(daily_sheet['upside']))&
                            (np.isfinite(daily_sheet['downside']))]

        for j in range(len(ticker_head_list)):

            ticker_head_results = daily_sheet[daily_sheet['tickerHead'] == ticker_head_list[j]]

            filter_output_long = sf.get_spread_carry_filters(data_frame_input=ticker_head_results, filter_list=['long1'])
            filter_output_short = sf.get_spread_carry_filters(data_frame_input=ticker_head_results, filter_list=['short1'])

            selected_short_trades = ticker_head_results[filter_output_short['selection_indx']]
            selected_long_trades = ticker_head_results[filter_output_long['selection_indx']]

            if len(selected_short_trades.index) > 0:

                short_pnl = -selected_short_trades['change5']*risk/abs(selected_short_trades['upside'])
                pnl_tickerhead_frame['sell_mean_pnl'][j] = short_pnl.mean()

            if len(selected_long_trades.index) > 0:
                long_pnl = selected_long_trades['change5']*risk/abs(selected_long_trades['downside'])
                pnl_tickerhead_frame['buy_mean_pnl'][j] = long_pnl.mean()

            pnl_tickerhead_frame['total_pnl'][j] = pnl_tickerhead_frame['buy_mean_pnl'][j] + pnl_tickerhead_frame['sell_mean_pnl'][j]
            total_pnl_frame[ticker_head_list[j]][i] = pnl_tickerhead_frame['total_pnl'][j]

        total_pnl_frame['portfolio'][i] = pnl_tickerhead_frame['total_pnl'].sum()

    return total_pnl_frame
def get_spread_carry_4tickerhead(**kwargs):

    ticker_head = kwargs['ticker_head']
    report_date = kwargs['report_date']

    if 'min_tr_dte' in kwargs.keys():
        min_tr_dte = kwargs['min_tr_dte']
    else:
        min_tr_dte = 15

    if 'futures_data_dictionary' in kwargs.keys():
        futures_data_dictionary = kwargs['futures_data_dictionary']
    else:
        futures_data_dictionary = {
            ticker_head:
            gfp.get_futures_price_preloaded(ticker_head=ticker_head)
        }

    if 'datetime5_years_ago' in kwargs.keys():
        datetime5_years_ago = kwargs['datetime5_years_ago']
    else:
        date5_years_ago = cu.doubledate_shift(report_date, 5 * 365)
        datetime5_years_ago = cu.convert_doubledate_2datetime(date5_years_ago)

    daily_data = gfp.get_futures_price_preloaded(
        ticker_head=ticker_head,
        settle_date=report_date,
        futures_data_dictionary=futures_data_dictionary)

    daily_data = daily_data[(daily_data['tr_dte'] >= min_tr_dte) & (
        daily_data['tr_dte'] <= max_tr_dte_limits[ticker_head])]

    if len(daily_data.index) > 1:

        carry_signals = fs.get_futures_spread_carry_signals(
            ticker_list=daily_data['ticker'].values,
            tr_dte_list=daily_data['tr_dte'].values,
            futures_data_dictionary=futures_data_dictionary,
            datetime5_years_ago=datetime5_years_ago,
            date_to=report_date)

        return {'success': True, 'carry_signals': carry_signals}
    else:
        return {'success': False, 'carry_signals': pd.DataFrame()}
Exemple #9
0
def get_results_4date(**kwargs):

    date_to = kwargs['date_to']
    output_dir = ts.create_strategy_output_dir(strategy_class='ibo',
                                               report_date=date_to)

    wait4_eoc_volume_filter = kwargs['wait4_eoc_volume_filter']
    trend_filter_type = kwargs['trend_filter_type']
    stop_loss_multiplier = kwargs['stop_loss_multiplier']  # 0.3
    distance_multiplier = kwargs['distance_multiplier']  # 0.5
    time_section_no = kwargs['time_section_no']  # 1
    use_filesQ = kwargs['use_filesQ']

    file_name = output_dir + '/summary.pkl'

    if use_filesQ and os.path.isfile(file_name):
        trades_frame = pd.read_pickle(file_name)
        return {'trades_frame': trades_frame, 'success': True}

    ticker_head_list = cmi.cme_futures_tickerhead_list
    #ticker_head_list = ['CL']

    data_list = [
        gfp.get_futures_price_preloaded(ticker_head=x, settle_date=date_to)
        for x in ticker_head_list
    ]

    ticker_frame = pd.concat(data_list)
    ticker_frame = ticker_frame[~((ticker_frame['ticker_head'] == 'ED') &
                                  (ticker_frame['tr_dte'] < 250))]

    ticker_frame.sort_values(['ticker_head', 'volume'],
                             ascending=[True, False],
                             inplace=True)
    ticker_frame.drop_duplicates(subset=['ticker_head'],
                                 keep='first',
                                 inplace=True)

    result_list = [
        get_results_4ticker(ticker=x,
                            date_to=date_to,
                            wait4_eoc_volume_filter=wait4_eoc_volume_filter,
                            trend_filter_type=trend_filter_type,
                            stop_loss_multiplier=stop_loss_multiplier,
                            distance_multiplier=distance_multiplier,
                            time_section_no=time_section_no)
        for x in ticker_frame['ticker']
    ]

    trades_frame = pd.concat([x['trades_frame'] for x in result_list])

    if use_filesQ:
        trades_frame.to_pickle(file_name)

    return {'trades_frame': trades_frame, 'success': True}
def get_contract_summary_stats(**kwargs):
    ticker = kwargs['ticker']
    date_to = kwargs['date_to']
    data_out = gfp.get_futures_price_preloaded(ticker=ticker)
    datetime_to = cu.convert_doubledate_2datetime(date_to)
    data_out = data_out[data_out['settle_date'] <= datetime_to]

    data_out['close_price_daily_diff'] = data_out['close_price'] - data_out['close_price'].shift(1)
    daily_noise = np.std(data_out['close_price_daily_diff'].iloc[-60:])
    average_volume = np.mean(data_out['volume'].iloc[-20:])
    return {'daily_noise': daily_noise, 'average_volume':average_volume}
def get_arma_signals(**kwargs):

    ticker_head = kwargs['ticker_head']
    date_to = kwargs['date_to']

    date2_years_ago = cu.doubledate_shift(date_to, 2*365)

    panel_data = gfp.get_futures_price_preloaded(ticker_head=ticker_head,settle_date_from=date2_years_ago,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)
    rolling_data['percent_change'] = 100*rolling_data['change_1']/rolling_data['close_price']
    rolling_data = rolling_data[rolling_data['percent_change'].notnull()]

    data_input = np.array(rolling_data['percent_change'])

    daily_noise = np.std(data_input)

    param1_list = []
    param2_list = []
    akaike_list = []
    forecast_list = []

    for i in range(0, 3):
        for j in range(0, 3):
            try:
                model_output = sm.tsa.ARMA(data_input, (i,j)).fit()
            except:
                continue

            param1_list.append(i)
            param2_list.append(j)
            akaike_list.append(model_output.aic)
            forecast_list.append(model_output.predict(len(data_input),len(data_input))[0])

    result_frame = pd.DataFrame.from_items([('param1', param1_list),
                             ('param2', param2_list),
                             ('akaike', akaike_list),
                             ('forecast', forecast_list)])

    result_frame.sort('akaike',ascending=True,inplace=True)

    param1 = result_frame['param1'].iloc[0]
    param2 = result_frame['param2'].iloc[0]

    if (param1 == 0)&(param2 == 0):
        forecast = np.nan
    else:
        forecast = result_frame['forecast'].iloc[0]

    return {'success': True, 'forecast':forecast,'normalized_forecast': forecast/daily_noise,
            'param1':param1,'param2':param2,
            'normalized_target': 100*(rolling_data['change1_instant'].iloc[-1]/rolling_data['close_price'].iloc[-1])/daily_noise}
Exemple #12
0
def generate_underlying_proxy_report(**kwargs):

    con = msu.get_my_sql_connection(**kwargs)
    report_date = kwargs['report_date']
    futures_dataframe = cl.generate_futures_list_dataframe(date_to=report_date)
    futures_flat_curve = futures_dataframe[
        futures_dataframe['ticker_class'].isin(
            ['FX', 'Metal', 'Treasury', 'Index'])]
    futures_flat_curve.reset_index(drop=True, inplace=True)

    futures_flat_curve['tr_days_2roll'] = futures_flat_curve.apply(
        lambda x: exp.get_days2_roll(ticker=x['ticker'],
                                     instrument='Futures',
                                     date_to=report_date,
                                     con=con)['tr_days_2roll'],
        axis=1)

    futures_data_dictionary = {
        x: gfp.get_futures_price_preloaded(ticker_head=x)
        for x in futures_flat_curve['ticker_head'].unique()
    }

    proxy_output_list = [
        get_underlying_proxy_ticker(
            ticker=futures_flat_curve['ticker'].iloc[x],
            settle_date=report_date,
            con=con,
            futures_data_dictionary=futures_data_dictionary)
        for x in range(len(futures_flat_curve.index))
    ]

    futures_flat_curve['proxy_ticker'] = [
        x['ticker'] for x in proxy_output_list
    ]
    futures_flat_curve['add_2_proxy'] = [
        x['add_2_proxy'] for x in proxy_output_list
    ]

    ta_output_dir = dn.get_dated_directory_extension(folder_date=report_date,
                                                     ext='ta')
    writer = pd.ExcelWriter(ta_output_dir + '/proxy_report.xlsx',
                            engine='xlsxwriter')
    futures_flat_curve = futures_flat_curve[[
        'ticker', 'ticker_head', 'ticker_class', 'volume', 'tr_days_2roll',
        'proxy_ticker', 'add_2_proxy'
    ]]

    futures_flat_curve.to_excel(writer, sheet_name='proxy_report')
    writer.save()

    if 'con' not in kwargs.keys():
        con.close()
Exemple #13
0
def cal_greeks_4option_maturity(**kwargs):

    option_prices = gop.get_options_price_from_db(**kwargs)

    if option_prices.empty:
        return pd.DataFrame()

    option_prices = option_prices[option_prices['strike'] > 0]
    option_prices.reset_index(drop=True, inplace=True)

    contract_specs_out = cmi.get_contract_specs(kwargs['ticker'])
    exercise_type = cmi.get_option_exercise_type(**contract_specs_out)

    underlying_ticker = oput.get_option_underlying(**kwargs)

    futures_price_output = gfp.get_futures_price_preloaded(
        ticker=underlying_ticker, settle_date=kwargs['settle_date'])

    if futures_price_output.empty:
        return pd.DataFrame()

    underlying_price = futures_price_output['close_price'].iloc[0]

    expiration_datetime = exp.get_expiration_from_db(instrument='options',
                                                     **kwargs)
    expiration_date = int(expiration_datetime.strftime('%Y%m%d'))

    interest_rate = grfs.get_simple_rate(
        as_of_date=kwargs['settle_date'],
        date_to=expiration_date)['rate_output']

    option_greeks = [
        qom.get_option_greeks(underlying=underlying_price,
                              option_price=float(
                                  option_prices['close_price'].iloc[x]),
                              strike=float(option_prices['strike'].iloc[x]),
                              risk_free_rate=interest_rate,
                              expiration_date=expiration_date,
                              calculation_date=kwargs['settle_date'],
                              option_type=option_prices['option_type'].iloc[x],
                              exercise_type=exercise_type)
        for x in range(len(option_prices.index))
    ]

    greek_frame = pd.DataFrame(option_greeks)

    return pd.concat([
        greek_frame[['delta', 'gamma', 'implied_vol', 'theta', 'vega']],
        option_prices
    ],
                     axis=1)
def get_spread_carry_4tickerhead(**kwargs):

    ticker_head = kwargs['ticker_head']
    report_date = kwargs['report_date']

    if 'min_tr_dte' in kwargs.keys():
        min_tr_dte = kwargs['min_tr_dte']
    else:
        min_tr_dte = 10

    if 'futures_data_dictionary' in kwargs.keys():
        futures_data_dictionary = kwargs['futures_data_dictionary']
    else:
        futures_data_dictionary = {ticker_head: gfp.get_futures_price_preloaded(ticker_head=ticker_head)}

    if 'datetime5_years_ago' in kwargs.keys():
        datetime5_years_ago = kwargs['datetime5_years_ago']
    else:
        date5_years_ago = cu.doubledate_shift(report_date,5*365)
        datetime5_years_ago = cu.convert_doubledate_2datetime(date5_years_ago)

    daily_data = gfp.get_futures_price_preloaded(ticker_head=ticker_head,
                                           settle_date=report_date,
                                           futures_data_dictionary=futures_data_dictionary)

    daily_data = daily_data[(daily_data['tr_dte'] >= min_tr_dte) & (daily_data['tr_dte'] <= max_tr_dte_limits[ticker_head])]

    if len(daily_data.index) > 1:

        carry_signals = fs.get_futures_spread_carry_signals(ticker_list=daily_data['ticker'].values,
                                        tr_dte_list=daily_data['tr_dte'].values,
                                        futures_data_dictionary=futures_data_dictionary,
                                        datetime5_years_ago=datetime5_years_ago,
                                        date_to=report_date)

        return {'success': True, 'carry_signals': carry_signals}
    else:
        return {'success': False, 'carry_signals': pd.DataFrame()}
def calc_intrday_pnl_from_prices(**kwargs):

    if 'as_of_date' in kwargs.keys():
        as_of_date = kwargs['as_of_date']
    else:
        as_of_date = exp.doubledate_shift_bus_days()

    net_position_frame = tas.get_net_position_4strategy_alias(alias=kwargs['alias'], as_of_date=as_of_date)

    net_position_frame['ticker_head'] = [cmi.get_contract_specs(x)['ticker_head'] for x in net_position_frame['ticker']]
    net_position_frame['contract_multiplier'] = [cmi.contract_multiplier[x] for x in net_position_frame['ticker_head']]

    con = msu.get_my_sql_connection(**kwargs)

    option_frame = net_position_frame[net_position_frame['instrument'] == 'O']

    #option_frame = option_frame[(option_frame['strike_price'] == 54)|(option_frame['strike_price'] == 60)]
    #option_frame = option_frame[option_frame['strike_price'] == 112]
    #option_frame['qty'].loc[option_frame['ticker']=='LNV2016'] = -20

    option_frame['close_price'] = [gop.get_options_price_from_db(ticker=option_frame['ticker'].iloc[x],
                                  strike=option_frame['strike_price'].iloc[x],
                                  option_type=option_frame['option_type'].iloc[x],
                                   con=con,settle_date=as_of_date)['close_price'][0] for x in range(len(option_frame.index))]

    structure_quantity = abs(option_frame['qty']).unique()[0]
    structure_multiplier = option_frame['contract_multiplier'].unique()[0]

    structure_price = sum(option_frame['close_price']*option_frame['qty'])/structure_quantity

    if structure_price<0:
        structure_quantity = -structure_quantity
        structure_price = -structure_price

    structure_pnl = structure_quantity*structure_multiplier*(kwargs['structure_price']-structure_price)

    futures_frame = net_position_frame[net_position_frame['instrument'] == 'F']

    futures_frame['close_price'] = [gfp.get_futures_price_preloaded(ticker=x, settle_date=as_of_date)['close_price'].iloc[0] for x in futures_frame['ticker']]

    futures_frame['intraday_price'] = [kwargs[x] for x in futures_frame['ticker']]

    futures_frame['intraday_pnl'] = (futures_frame['intraday_price']-futures_frame['close_price'])*futures_frame['qty']*futures_frame['contract_multiplier']

    if 'con' not in kwargs.keys():
        con.close()

    return {'structure_pnl': structure_pnl, 'futures_pnl': futures_frame['intraday_pnl'].sum(),'structure_settle': structure_price}
def calc_realized_vol_4futures_ticker(**kwargs):

    settle_date = kwargs.pop('settle_date')

    num_obs = kwargs.pop('num_obs', 20)

    futures_price_output = gfp.get_futures_price_preloaded(**kwargs)

    settle_datetime = cu.convert_doubledate_2datetime(settle_date)

    futures_price_selected = futures_price_output[futures_price_output['settle_date'] <= settle_datetime]

    logreturns = np.log(futures_price_selected['close_price'][-(num_obs+1):]/
                         futures_price_selected['close_price'][-(num_obs+1):].shift(1))

    return 100*np.sqrt(252*np.mean(np.square(logreturns)))
Exemple #17
0
def calc_realized_vol_4futures_ticker(**kwargs):

    settle_date = kwargs.pop('settle_date')

    num_obs = kwargs.pop('num_obs', 20)

    futures_price_output = gfp.get_futures_price_preloaded(**kwargs)

    settle_datetime = cu.convert_doubledate_2datetime(settle_date)

    futures_price_selected = futures_price_output[futures_price_output['settle_date'] <= settle_datetime]

    logreturns = np.log(futures_price_selected['close_price'][-(num_obs+1):]/
                         futures_price_selected['close_price'][-(num_obs+1):].shift(1))

    return 100*np.sqrt(252*np.mean(np.square(logreturns)))
def calc_intraday_structure_pnl_from_prices(**kwargs):

    if 'as_of_date' in kwargs.keys():
        as_of_date = kwargs['as_of_date']
    else:
        as_of_date = exp.doubledate_shift_bus_days()

    con = msu.get_my_sql_connection(**kwargs)

    structure_type = kwargs['structure_type']
    structure_price = kwargs['structure_price']
    ticker_list = kwargs['ticker_list']
    strike_list = kwargs['strike_list']
    underlying_price_list = kwargs['underlying_price_list']
    qty = kwargs['qty']

    if structure_type == 'straddle_spread':
        option_frame = pd.DataFrame.from_items([('ticker', [ticker_list[0], ticker_list[0], ticker_list[1], ticker_list[1]]),
                                                ('option_type', ['C', 'P', 'C', 'P']),
                                                ('strike_price', [strike_list[0], strike_list[0], strike_list[1],strike_list[1]]),
                                                ('qty', [-1, -1, 1, 1])])

    option_price_output = [gop.get_options_price_from_db(ticker=option_frame['ticker'].iloc[x],
                                  strike=option_frame['strike_price'].iloc[x],
                                  option_type=option_frame['option_type'].iloc[x],
                                   con=con,settle_date=as_of_date,column_names=['close_price','delta']) for x in range(len(option_frame.index))]

    option_frame['delta'] = [option_price_output[x]['delta'][0] for x in range(len(option_frame.index))]
    option_frame['close_price'] = [option_price_output[x]['close_price'][0] for x in range(len(option_frame.index))]

    option_frame['PQ'] = option_frame['close_price']*option_frame['qty']
    option_frame['signed_delta'] = option_frame['delta']*option_frame['qty']

    delta_list = [option_frame[option_frame['ticker'] == x]['signed_delta'].sum() for x in ticker_list]

    ticker_head = cmi.get_contract_specs(ticker_list[0])['ticker_head']
    contract_multiplier = cmi.contract_multiplier[ticker_head]

    structure_price_yesterday = option_frame['PQ'].sum()
    structure_pnl = qty*(structure_price-structure_price_yesterday)*contract_multiplier

    underlying_ticker_list = [oputil.get_option_underlying(ticker=x) for x in ticker_list]
    underlying_price_list_yesterday = [gfp.get_futures_price_preloaded(ticker=x, settle_date=as_of_date)['close_price'].iloc[0] for x in underlying_ticker_list]
    delta_pnl = contract_multiplier*sum([-delta_list[x]*qty*(underlying_price_list[x]-underlying_price_list_yesterday[x]) for x in range(len(delta_list))])

    return {'total_pnl': structure_pnl+delta_pnl, 'structure_pnl': structure_pnl,
            'delta_pnl': delta_pnl, 'structure_price_yesterday': structure_price_yesterday }
def generate_spread_carry_sheet_4date(**kwargs):

    report_date = kwargs['report_date']

    output_dir = ts.create_strategy_output_dir(strategy_class='spread_carry',
                                               report_date=report_date)

    if os.path.isfile(output_dir + '/summary.pkl'):
        spread_report = pd.read_pickle(output_dir + '/summary.pkl')
        return {'spread_report': spread_report, 'success': True}

    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 max_tr_dte_limits.keys()
        }

    spread_list = [
        get_spread_carry_4tickerhead(
            ticker_head=x,
            report_date=report_date,
            futures_data_dictionary=futures_data_dictionary)
        for x in max_tr_dte_limits.keys()
    ]

    success_list = [x['success'] for x in spread_list]
    carry_signals_list = [x['carry_signals'] for x in spread_list]

    spread_report = pd.concat([
        carry_signals_list[x] for x in range(len(spread_list))
        if success_list[x]
    ])

    spread_report['carry'] = spread_report['carry'].round(2)
    spread_report['q_carry_average'] = spread_report['q_carry_average'].round()
    spread_report['reward_risk'] = spread_report['reward_risk'].round(2)
    spread_report['upside'] = spread_report['upside'].round(2)
    spread_report['downside'] = spread_report['downside'].round(2)

    spread_report.rename(columns={'ticker_head': 'tickerHead'}, inplace=True)

    spread_report.to_pickle(output_dir + '/summary.pkl')

    return {'spread_report': spread_report, 'success': True}
Exemple #20
0
def get_rolling_curve_data(**kwargs):

    ticker_head = kwargs['ticker_head']
    num_contracts = kwargs['num_contracts']
    front_tr_dte_limit = kwargs['front_tr_dte_limit']
    date_from = kwargs['date_from']
    date_to = kwargs['date_to']

    date_from_datetime = cu.convert_doubledate_2datetime(date_from)
    date_to_datetime = cu.convert_doubledate_2datetime(date_to)

    panel_data = gfp.get_futures_price_preloaded(ticker_head=ticker_head)

    panel_data = panel_data.loc[(panel_data['settle_date'] >= date_from_datetime) &
                                (panel_data['settle_date'] <= date_to_datetime) &
                                (panel_data['tr_dte'] >= front_tr_dte_limit)]

    if 'month_separation' in kwargs.keys():
        month_separation = kwargs['month_separation']
    elif ticker_head == 'ED':
        month_separation = 3
    else:
        month_separation = 1

    if month_separation != 1:
        panel_data = panel_data[panel_data['ticker_month'] % month_separation == 0]

    panel_data = panel_data[np.isfinite(panel_data['close_price'])]
    sorted_data = panel_data.sort_values(['settle_date', 'tr_dte'], ascending=[True, True])

    filtered_data = sorted_data.groupby('settle_date').filter(lambda x:len(x)>=num_contracts)

    filtered_data2 = filtered_data.groupby('settle_date').filter(lambda x:
                                                            all([cmi.get_month_seperation_from_cont_indx(x['cont_indx'].values[i],
                                                                                                         x['cont_indx'].values[i+1]) ==- month_separation for i in range(num_contracts-1)]))

    grouped = filtered_data2.groupby('settle_date')

    rolling_data_list = []

    for i in range(num_contracts):

        rolling_data_list.append(grouped.nth(i))

    return rolling_data_list
def get_rolling_curve_data(**kwargs):

    ticker_head = kwargs['ticker_head']
    num_contracts = kwargs['num_contracts']
    front_tr_dte_limit = kwargs['front_tr_dte_limit']
    date_from = kwargs['date_from']
    date_to = kwargs['date_to']

    date_from_datetime = cu.convert_doubledate_2datetime(date_from)
    date_to_datetime = cu.convert_doubledate_2datetime(date_to)

    panel_data = gfp.get_futures_price_preloaded(ticker_head=ticker_head)

    panel_data = panel_data.loc[(panel_data['settle_date'] >= date_from_datetime) &
                                (panel_data['settle_date'] <= date_to_datetime) &
                                (panel_data['tr_dte'] >= front_tr_dte_limit)]

    if 'month_separation' in kwargs.keys():
        month_separation = kwargs['month_separation']
    elif ticker_head == 'ED':
        month_separation = 3
    else:
        month_separation = 1

    if month_separation != 1:
        panel_data = panel_data[panel_data['ticker_month'] % month_separation == 0]

    panel_data = panel_data[np.isfinite(panel_data['close_price'])]
    sorted_data = panel_data.sort(['settle_date', 'tr_dte'], ascending=[True, True])

    filtered_data = sorted_data.groupby('settle_date').filter(lambda x:len(x)>=num_contracts)

    filtered_data2 = filtered_data.groupby('settle_date').filter(lambda x:
                                                            all([cmi.get_month_seperation_from_cont_indx(x['cont_indx'].values[i],
                                                                                                         x['cont_indx'].values[i+1]) ==- month_separation for i in range(num_contracts-1)]))

    grouped = filtered_data2.groupby('settle_date')

    rolling_data_list = []

    for i in range(num_contracts):

        rolling_data_list.append(grouped.nth(i))

    return rolling_data_list
Exemple #22
0
def get_results_4ticker(**kwargs):

    ticker = kwargs['ticker']
    date_to = kwargs['date_to']

    candle_frame = qd.get_continuous_bar_data(ticker=ticker, date_to=date_to, num_days_back=0)

    history_frame = gfp.get_futures_price_preloaded(ticker=ticker, settle_date_to=date_to)
    history_frame = history_frame.iloc[:-1]
    history_frame['ma9'] = history_frame['close_price'].rolling(window=9, center=False).mean()

    high_1 = history_frame['high_price'].iloc[-1]
    low_1 = history_frame['low_price'].iloc[-1]

    trend_direction = 0

    if history_frame['ma9'].iloc[-1] > history_frame['ma9'].iloc[-2]:
        trend_direction = 1
    elif history_frame['ma9'].iloc[-1] < history_frame['ma9'].iloc[-2]:
        trend_direction = -1
def get_futures_curve_chart_4date(**kwargs):

    ticker_head = kwargs['ticker_head']
    settle_date = kwargs['settle_date']

    data2_plot = gfp.get_futures_price_preloaded(ticker_head=ticker_head, settle_date=settle_date)

    if 'tr_dte_limit' in kwargs.keys():
        data2_plot = data2_plot[data2_plot['tr_dte'] <= kwargs['tr_dte_limit']]

    ticker_year_short = data2_plot['ticker_year'] % 10
    month_letters = [cmi.letter_month_string[x-1] for x in data2_plot['ticker_month'].values]

    tick_labels = [month_letters[x]+str(ticker_year_short.values[x]) for x in range(len(month_letters))]

    plt.figure(figsize=(16, 7))
    plt.plot(data2_plot['close_price'])
    plt.xticks(range(len(data2_plot.index)),tick_labels)
    plt.grid()
    plt.show()
def get_futures_curve_chart_4date(**kwargs):

    ticker_head = kwargs['ticker_head']
    settle_date = kwargs['settle_date']

    data2_plot = gfp.get_futures_price_preloaded(ticker_head=ticker_head, settle_date=settle_date)

    if 'tr_dte_limit' in kwargs.keys():
        data2_plot = data2_plot[data2_plot['tr_dte'] <= kwargs['tr_dte_limit']]

    ticker_year_short = data2_plot['ticker_year'] % 10
    month_letters = [cmi.letter_month_string[x-1] for x in data2_plot['ticker_month'].values]

    tick_labels = [month_letters[x]+str(ticker_year_short.values[x]) for x in range(len(month_letters))]

    plt.figure(figsize=(16, 7))
    plt.plot(range(len(data2_plot.index)),data2_plot['close_price'])
    plt.xticks(range(len(data2_plot.index)),tick_labels)
    plt.grid()
    plt.show()
Exemple #25
0
def save_ib_data(**kwargs):

    if 'duration_str' in kwargs.keys():
        duration_str = kwargs['duration_str']
    else:
        duration_str = '2 M'

    app = algo.Algo()
    con = msu.get_my_sql_connection()
    date_now = cu.get_doubledate()
    datetime_now = dt.datetime.now()
    report_date = exp.doubledate_shift_bus_days()

    ticker_head_list = cmi.cme_futures_tickerhead_list

    data_list = [
        gfp.get_futures_price_preloaded(ticker_head=x, settle_date=report_date)
        for x in ticker_head_list
    ]
    ticker_frame = pd.concat(data_list)
    ticker_frame = ticker_frame[~((ticker_frame['ticker_head'] == 'ED') &
                                  (ticker_frame['tr_dte'] < 250))]
    ticker_frame = ticker_frame[~((ticker_frame['ticker_head'] == 'GC') |
                                  (ticker_frame['ticker_head'] == 'SI'))]

    ticker_frame.sort_values(['ticker_head', 'volume'],
                             ascending=[True, False],
                             inplace=True)
    ticker_frame.drop_duplicates(subset=['ticker_head'],
                                 keep='first',
                                 inplace=True)

    app.ticker_list = list(ticker_frame['ticker'])
    app.output_dir = sd.get_directory_name(ext='ib_data')
    app.durationStr = duration_str
    app.con = con

    app.connect(client_id=5)

    app.run()
Exemple #26
0
def get_rolling_futures_price(**kwargs):

    if 'roll_tr_dte_aim' in kwargs.keys():
        roll_tr_dte_aim = kwargs['roll_tr_dte_aim']
    else:
        roll_tr_dte_aim = 50

    futures_dataframe = gfp.get_futures_price_preloaded(**kwargs)

    futures_dataframe = futures_dataframe[futures_dataframe['cal_dte'] < 270]
    futures_dataframe.sort(['cont_indx', 'settle_date'], ascending=[True,True], inplace=True)

    grouped = futures_dataframe.groupby('cont_indx')
    shifted = grouped.shift(1)

    futures_dataframe['log_return'] = np.log(futures_dataframe['close_price']/shifted['close_price'])

    futures_dataframe['tr_dte_diff'] = abs(roll_tr_dte_aim-futures_dataframe['tr_dte'])
    futures_dataframe.sort(['settle_date','tr_dte_diff'], ascending=[True,True], inplace=True)
    futures_dataframe.drop_duplicates('settle_date', inplace=True, take_last=False)

    return futures_dataframe
Exemple #27
0
def calculate_contract_risk(**kwargs):

    contract_frame = kwargs['contract_frame']
    current_date = kwargs['current_date']
    contract_frame['risk'] = np.nan
    contract_frame['contract_multiplier'] = np.nan

    for i in range(len(contract_frame.index)):

        ticker_raw = contract_frame['ticker'].iloc[i]
        ticker_output = ticker_raw.split('-')
        contract_multiplier = cmi.contract_multiplier[
            contract_frame['ticker_head'].iloc[i]]
        contract_frame['contract_multiplier'].iloc[i] = contract_multiplier

        if len(ticker_output) == 1:
            ticker = ticker_output[0]
            data_out = gfp.get_futures_price_preloaded(
                ticker=ticker, settle_date_to=current_date)
            recent_data = data_out.iloc[-10:]
            contract_frame['risk'].iloc[i] = contract_multiplier * (
                recent_data['close_price'].max() -
                recent_data['close_price'].min())

        if len(ticker_output) > 1:
            aligned_output = opUtil.get_aligned_futures_data(
                contract_list=ticker_output,
                contracts_back=1,
                aggregation_method=12,
                date_to=current_date)

            aligned_data = aligned_output['aligned_data']
            recent_data = aligned_data.iloc[-10:]
            spread_price = recent_data['c1']['close_price'] - recent_data[
                'c2']['close_price']
            contract_frame['risk'].iloc[i] = contract_multiplier * (
                spread_price.max() - spread_price.min())

    return contract_frame
def calc_realized_vol_4options_ticker(**kwargs):

    ticker = kwargs['ticker']
    contract_specs_output = cmi.get_contract_specs(ticker)

    if contract_specs_output['ticker_class'] in ['Index', 'FX', 'Metal']:
        use_proxy_contract = True
    else:
        use_proxy_contract = False

    if use_proxy_contract:

        if 'futures_data_dictionary' in kwargs.keys():
            futures_data_input = {'ticker_head': contract_specs_output['ticker_head'],'settle_date': kwargs['settle_date']}
            futures_data_input['futures_data_dictionary'] = kwargs['futures_data_dictionary']
            data_out = gfp.get_futures_price_preloaded(**futures_data_input)
            data_out = data_out.reset_index()
            kwargs['ticker'] = data_out['ticker'].loc[data_out['volume'].idxmax()]
    else:
        kwargs['ticker'] = omu.get_option_underlying(**kwargs)

    return calc_realized_vol_4futures_ticker(**kwargs)
def cal_greeks_4option_maturity(**kwargs):

    option_prices = gop.get_options_price_from_db(**kwargs)

    if option_prices.empty:
        return pd.DataFrame()

    contract_specs_out = cmi.get_contract_specs(kwargs['ticker'])
    exercise_type = cmi.get_option_exercise_type(**contract_specs_out)

    underlying_ticker = oput.get_option_underlying(**kwargs)

    futures_price_output = gfp.get_futures_price_preloaded(ticker=underlying_ticker, settle_date=kwargs['settle_date'])

    if futures_price_output.empty:
        return pd.DataFrame()

    underlying_price = futures_price_output['close_price'].iloc[0]

    expiration_datetime = exp.get_expiration_from_db(instrument='options', **kwargs)
    expiration_date = int(expiration_datetime.strftime('%Y%m%d'))

    interest_rate = grfs.get_simple_rate(as_of_date=kwargs['settle_date'], date_to=expiration_date)['rate_output']
    #print(kwargs['settle_date'])
    #print(expiration_date)

    option_greeks = [qom.get_option_greeks(underlying=underlying_price,
                                           option_price=float(option_prices['close_price'].iloc[x]),
                                           strike=float(option_prices['strike'].iloc[x]),
                                           risk_free_rate=interest_rate,
                                           expiration_date=expiration_date,
                                           calculation_date=kwargs['settle_date'],
                                           option_type=option_prices['option_type'].iloc[x],
                                           exercise_type=exercise_type) for x in range(len(option_prices.index))]

    greek_frame = pd.DataFrame(option_greeks)

    return pd.concat([greek_frame[['delta', 'gamma', 'implied_vol', 'theta', 'vega']], option_prices], axis=1)
def get_cot_strategy_signals(**kwargs):

    ticker_head = kwargs['ticker_head']
    date_to = kwargs['date_to']

    datetime_to = cu.convert_doubledate_2datetime(date_to)

    data_out = gfp.get_futures_price_preloaded(ticker_head=ticker_head)
    data_out = data_out[data_out['settle_date'] <= datetime_to]

    data_out_front = data_out[data_out['tr_dte'] <= 60]
    data_out_front.drop_duplicates(subset=['settle_date'], keep='last', inplace=True)

    data_out_back = data_out[data_out['tr_dte'] > 60]
    data_out_back.drop_duplicates(subset=['settle_date'], keep='last', inplace=True)

    merged_data = pd.merge(data_out_front[['settle_date','tr_dte','close_price']],data_out_back[['tr_dte','close_price','settle_date','ticker','change_1']],how='inner',on='settle_date')
    merged_data['const_mat']=((merged_data['tr_dte_y']-60)*merged_data['close_price_x']+
                              (60-merged_data['tr_dte_x'])*merged_data['close_price_y'])/\
                             (merged_data['tr_dte_y']-merged_data['tr_dte_x'])

    cot_output = cot.get_cot_data(ticker_head=ticker_head,date_to=date_to)

    cot_output['comm_net'] = cot_output['Commercial Long']-cot_output['Commercial Short']
    cot_output['spec_net'] = cot_output['Noncommercial Long'] - cot_output['Noncommercial Short']

    cot_output['comm_min'] = cot_output['comm_net'].rolling(window=156, min_periods=156, center=False).min()
    cot_output['comm_max'] = cot_output['comm_net'].rolling(window=156, min_periods=156, center=False).max()
    cot_output['cot_index_slow'] = 100 * (cot_output['comm_net'] - cot_output['comm_min']) / (
                cot_output['comm_max'] - cot_output['comm_min'])

    cot_output['settle_date'] = [x+dt.timedelta(days=3) for x in cot_output['settle_date']]

    combined_data = pd.merge(merged_data,cot_output,how='inner',on='settle_date')

    return {'ticker_head':ticker_head,
            'success': True, 'cot_index_slow': cot_output['cot_index_slow'].iloc[-1],
            'combined_data': combined_data,}
Exemple #31
0
def get_tickers_4date(**kwargs):

    ticker_head_list = cmi.cme_futures_tickerhead_list

    data_list = [
        gfp.get_futures_price_preloaded(ticker_head=x,
                                        settle_date=kwargs['date_to'])
        for x in ticker_head_list
    ]
    ticker_frame = pd.concat(data_list)

    ticker_frame = ticker_frame[~((ticker_frame['ticker_head'] == 'ED') &
                                  (ticker_frame['tr_dte'] < 250))]

    ticker_frame.sort_values(['ticker_head', 'volume'],
                             ascending=[True, False],
                             inplace=True)
    ticker_frame.drop_duplicates(subset=['ticker_head'],
                                 keep='first',
                                 inplace=True)
    ticker_frame.reset_index(drop=True, inplace=True)

    return ticker_frame[['ticker', 'ticker_head']]
Exemple #32
0
def get_results_4date(**kwargs):

    date_to = kwargs['date_to']
    output_dir = ts.create_strategy_output_dir(strategy_class='itf',
                                               report_date=date_to)

    if os.path.isfile(output_dir + '/summary.pkl'):
        trades_frame = pd.read_pickle(output_dir + '/summary.pkl')
        return {'trades_frame': trades_frame, 'success': True}

    ticker_head_list = cmi.cme_futures_tickerhead_list

    data_list = [
        gfp.get_futures_price_preloaded(ticker_head=x, settle_date=date_to)
        for x in ticker_head_list
    ]
    ticker_frame = pd.concat(data_list)
    ticker_frame = ticker_frame[~((ticker_frame['ticker_head'] == 'ED') &
                                  (ticker_frame['tr_dte'] < 250))]

    ticker_frame.sort_values(['ticker_head', 'volume'],
                             ascending=[True, False],
                             inplace=True)
    ticker_frame.drop_duplicates(subset=['ticker_head'],
                                 keep='first',
                                 inplace=True)

    result_list = [
        get_results_4ticker(ticker=x, date_to=date_to)
        for x in ticker_frame['ticker']
    ]
    trades_frame = pd.concat([x['trades_frame'] for x in result_list])

    trades_frame.to_pickle(output_dir + '/summary.pkl')

    return {'trades_frame': trades_frame, 'success': True}
def get_backtest_summary(**kwargs):

    futures_data_dictionary = {
        x: gfp.get_futures_price_preloaded(ticker_head=x) for x in cmi.futures_butterfly_strategy_tickerhead_list
    }
    date_list = kwargs["date_list"]

    if "use_existing_filesQ" in kwargs.keys():
        use_existing_filesQ = kwargs["use_existing_filesQ"]
    else:
        use_existing_filesQ = True

    backtest_output = []

    for report_date in date_list:
        backtest_output.append(
            get_backtest_summary_4_date(
                report_date=report_date,
                futures_data_dictionary=futures_data_dictionary,
                use_existing_filesQ=use_existing_filesQ,
            )
        )

    return {"big_data": pd.concat(backtest_output), "backtest_output": backtest_output}
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)])
Exemple #36
0
def get_strategy_pnl(**kwargs):

    alias = kwargs['alias']
    con = msu.get_my_sql_connection(**kwargs)

    #print(alias)

    strategy_info = ts.get_strategy_info_from_alias(alias=alias, con=con)

    if 'as_of_date' in kwargs.keys():
        as_of_date = kwargs['as_of_date']
    else:
        as_of_date = exp.doubledate_shift_bus_days()

    open_date = int(strategy_info['open_date'].strftime('%Y%m%d'))
    close_date = int(strategy_info['close_date'].strftime('%Y%m%d'))

    if close_date>as_of_date:
        close_date = as_of_date

    bus_day_list = exp.get_bus_day_list(date_from=open_date,date_to=close_date)

    trades_frame = ts.get_trades_4strategy_alias(alias=alias,con=con)
    ticker_head_list = [cmi.get_contract_specs(x)['ticker_head'] for x in trades_frame['ticker']]
    unique_ticker_head_list = list(set(ticker_head_list))

    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 unique_ticker_head_list}

    trades_frame['contract_multiplier'] = [cmi.contract_multiplier[x] for x in ticker_head_list]
    trades_frame['t_cost'] = [cmi.t_cost[x] for x in ticker_head_list]

    pnl_path = [get_strategy_pnl_4day(alias=alias,pnl_date=x,con=con,
                                      trades_frame=trades_frame,
                                      futures_data_dictionary=futures_data_dictionary) for x in bus_day_list]

    pnl_per_tickerhead_list = [x['pnl_per_tickerhead'] for x in pnl_path]
    pnl_per_tickerhead = pd.concat(pnl_per_tickerhead_list, axis=1)
    pnl_per_tickerhead = pnl_per_tickerhead[['pnl_total']]
    pnl_per_tickerhead = pnl_per_tickerhead.transpose()

    if len(unique_ticker_head_list)>1:
        zero_indx = [[x not in y.index for y in pnl_per_tickerhead_list] for x in pnl_per_tickerhead.columns]

        for i in range(len(pnl_per_tickerhead.columns)):
            pnl_per_tickerhead.iloc[:, i][zero_indx[i]] = 0

    pnl_per_tickerhead['settle_date'] = bus_day_list
    pnl_per_tickerhead.reset_index(inplace=True,drop=True)

    pnl_frame = pd.DataFrame(pnl_path)
    pnl_frame['settle_date'] = bus_day_list

    if 'con' not in kwargs.keys():
        con.close()

    return {'pnl_frame': pnl_frame[['settle_date','position_pnl','intraday_pnl','t_cost','total_pnl']],
            'pnl_per_tickerhead': pnl_per_tickerhead,
            'daily_pnl': pnl_frame['total_pnl'].values[-1],
            'total_pnl': pnl_frame['total_pnl'].sum()}
Exemple #37
0
def get_results_4ticker(**kwargs):

    ticker = kwargs['ticker']
    date_to = kwargs['date_to']

    ticker_frame = gfp.get_futures_price_preloaded(ticker=ticker,
                                                   settle_date_to=date_to)
    ticker_frame['close_diff'] = ticker_frame['close_price'].diff()
    daily_sd = np.std(ticker_frame['close_diff'].iloc[-41:-1])

    ticker_frame['ma50'] = ticker_frame['close_price'].rolling(
        window=50, center=False).mean()
    ticker_frame['ma200'] = ticker_frame['close_price'].rolling(
        window=200, center=False).mean()

    if ticker_frame['close_price'].iloc[-2] > ticker_frame['ma50'].iloc[-2]:
        trend1 = 1
    else:
        trend1 = -1

    if ticker_frame['ma50'].iloc[-2] > ticker_frame['ma200'].iloc[-2]:
        trend2 = 1
    else:
        trend2 = -1

    candle_frame = qd.get_continuous_bar_data(ticker=ticker,
                                              date_to=date_to,
                                              num_days_back=20)

    ticker_head = cmi.get_contract_specs(ticker)['ticker_head']

    candle_frame['ewma300'] = candle_frame['close'].ewm(
        span=300, min_periods=250, adjust=True, ignore_na=False).mean()
    candle_frame['ewma50'] = candle_frame['close'].ewm(span=50,
                                                       min_periods=40,
                                                       adjust=True,
                                                       ignore_na=False).mean()
    candle_frame['ma5'] = candle_frame['close'].rolling(window=5,
                                                        center=False).mean()

    candle_frame['ewma300D'] = candle_frame['ewma300'] - candle_frame[
        'ewma300'].shift(60)
    candle_frame['ewma300DN'] = candle_frame['ewma300D'] / daily_sd
    candle_frame[
        'ewma50D'] = candle_frame['ewma50'] - candle_frame['ewma50'].shift(10)

    candle_frame['min14'] = candle_frame['low'].rolling(window=14,
                                                        center=False).min()
    candle_frame['max14'] = candle_frame['high'].rolling(window=14,
                                                         center=False).max()

    candle_frame['william'] = -100 * (
        candle_frame['max14'] - candle_frame['close']) / (
            candle_frame['max14'] - candle_frame['min14'])
    candle_frame['datetime'] = [
        x.replace(hour=0, second=0, minute=0) for x in candle_frame.index
    ]

    candle_frame['obs_no'] = range(len(candle_frame.index))

    candle_frame['bullishW'] = candle_frame['william'] > -20
    candle_frame['bearishW'] = candle_frame['william'] < -80

    candle_frame['bullishW'] = candle_frame['bullishW'].astype(int)
    candle_frame['bearishW'] = candle_frame['bearishW'].astype(int)

    candle_frame = candle_frame[np.isfinite(candle_frame['ewma300D'])]
    candle_frame['ewma300DS'] = np.sign(candle_frame['ewma300D'])
    candle_frame['ewma300DSDiff'] = abs(candle_frame['ewma300DS'].diff())

    turning_points = candle_frame[candle_frame['ewma300DSDiff'] != 0]
    turning_points['turning_points'] = turning_points['obs_no']

    merged_frame = pd.concat([candle_frame, turning_points['turning_points']],
                             axis=1)
    merged_frame['turning_points'].iloc[0] = 0
    merged_frame['turning_points'] = merged_frame['turning_points'].fillna(
        method='ffill')
    merged_frame[
        'trend_age'] = merged_frame['obs_no'] - merged_frame['turning_points']

    merged_frame['bullishWCumsum'] = merged_frame.groupby(
        'turning_points')['bullishW'].transform(pd.Series.cumsum)
    merged_frame['bearishWCumsum'] = merged_frame.groupby(
        'turning_points')['bearishW'].transform(pd.Series.cumsum)
    candle_frame = merged_frame

    candle_frame = candle_frame.dropna().reset_index(drop=True, inplace=False)
    date_timeto = cu.convert_doubledate_2datetime(date_to)

    daily_frame = candle_frame[candle_frame['datetime'] == date_timeto]
    daily_frame.reset_index(drop=True, inplace=True)

    tick_size = cmi.tick_size[ticker_head]
    latest_trade_exit_hour_minute = get_latest_trade_exit_hour_minute(
        ticker_head)

    current_position = 0

    direction_list = []
    entry_price_list = []
    exit_price_list = []
    entry_index_list = []
    exit_index_list = []
    entry_hour_minute_list = []
    stop_price_list = []
    target_price_list = []

    ewma300DN_list = []
    trend_age_list = []
    bullishWCumsum_list = []
    bearishWCumsum_list = []

    stop_adjustment_possible_Q = False
    long_trade_possible_Q = False
    short_trade_possible_Q = False
    breakout_price = np.nan

    for i in range(2, len(daily_frame.index)):

        if (daily_frame['ewma300D'].iloc[i] <
                0) | (daily_frame['william'].iloc[i] <= -80):
            long_trade_possible_Q = False

        if (daily_frame['ewma300D'].iloc[i] >
                0) | (daily_frame['william'].iloc[i] >= -20):
            short_trade_possible_Q = False

        if long_trade_possible_Q and (daily_frame['high'].iloc[i] > breakout_price + tick_size) \
                and (daily_frame['hour_minute'].iloc[i] <= 1100):

            long_trade_possible_Q = False
            current_position = 1
            direction_list.append(current_position)
            ewma300DN_list.append(daily_frame['ewma300DN'].iloc[i - 1])
            trend_age_list.append(daily_frame['trend_age'].iloc[i - 1])
            bullishWCumsum_list.append(daily_frame['bullishWCumsum'].iloc[i -
                                                                          1])
            bearishWCumsum_list.append(daily_frame['bearishWCumsum'].iloc[i -
                                                                          1])
            entry_index_list.append(i)
            entry_hour_minute_list.append(daily_frame['hour_minute'].iloc[i])
            entry_price = breakout_price + 1.5 * tick_size
            entry_price_list.append(entry_price)
            stop_price_list.append(swing_low - tick_size)
            target_price_list.append(2 * entry_price - swing_low)
            breakout_price = np.nan
            continue

        if (current_position == 0) and (daily_frame['ewma300D'].iloc[i] > 0) and (daily_frame['william'].iloc[i - 1] <= -80) \
                and (daily_frame['william'].iloc[i] > -80) and (daily_frame['hour_minute'].iloc[i] <= 1100) and (daily_frame['hour_minute'].iloc[i] >= 830):
            long_trade_possible_Q = True
            breakout_price = daily_frame['high'].iloc[i]

            for j in range(len(daily_frame.index)):
                if j == 0:
                    swing_low = daily_frame['low'].iloc[i - 1]
                elif daily_frame['low'].iloc[i - 1 - j] <= swing_low:
                    swing_low = daily_frame['low'].iloc[i - 1 - j]
                elif daily_frame['low'].iloc[i - 1 - j] > swing_low:
                    break

        if short_trade_possible_Q and (daily_frame['low'].iloc[i] < breakout_price - tick_size) \
            and (daily_frame['hour_minute'].iloc[i] <= 1100):

            short_trade_possible_Q = False
            current_position = -1
            direction_list.append(current_position)
            ewma300DN_list.append(daily_frame['ewma300DN'].iloc[i - 1])
            trend_age_list.append(daily_frame['trend_age'].iloc[i - 1])
            bullishWCumsum_list.append(daily_frame['bullishWCumsum'].iloc[i -
                                                                          1])
            bearishWCumsum_list.append(daily_frame['bearishWCumsum'].iloc[i -
                                                                          1])
            entry_index_list.append(i)
            entry_hour_minute_list.append(daily_frame['hour_minute'].iloc[i])
            entry_price = breakout_price - 1.5 * tick_size
            entry_price_list.append(entry_price)
            stop_price_list.append(swing_high + tick_size)
            target_price_list.append(2 * entry_price - swing_high)
            breakout_price = np.nan
            continue


        if (current_position == 0) and (daily_frame['ewma300D'].iloc[i] < 0) and (daily_frame['william'].iloc[i - 1] >= -20) \
            and (daily_frame['william'].iloc[i] < -20) and (daily_frame['hour_minute'].iloc[i] <= 1100) and (daily_frame['hour_minute'].iloc[i] >= 830):

            short_trade_possible_Q = True
            breakout_price = daily_frame['high'].iloc[i]

            for j in range(len(daily_frame.index)):
                if j == 0:
                    swing_high = daily_frame['high'].iloc[i - 1]
                elif daily_frame['high'].iloc[i - 1 - j] >= swing_high:
                    swing_high = daily_frame['high'].iloc[i - 1 - j]
                elif daily_frame['high'].iloc[i - 1 - j] < swing_high:
                    break

        if (current_position > 0) and stop_adjustment_possible_Q and (
                daily_frame['close'].iloc[i-2] < daily_frame['ma5'].iloc[i-2]) \
                and (daily_frame['close'].iloc[i-1] < daily_frame['ma5'].iloc[i-1]):
            stop_price_list[-1] = min(daily_frame['low'].iloc[i - 2],
                                      daily_frame['low'].iloc[i - 1])

        if (current_position < 0) and stop_adjustment_possible_Q and (
            daily_frame['close'].iloc[i-2] > daily_frame['ma5'].iloc[i-2]) \
            and (daily_frame['close'].iloc[i-1] > daily_frame['ma5'].iloc[i-1]):
            stop_price_list[-1] = max(daily_frame['high'].iloc[i - 2],
                                      daily_frame['high'].iloc[i - 1])

        if (current_position > 0) and ((daily_frame['hour_minute'].iloc[i] >=
                                        latest_trade_exit_hour_minute) |
                                       (i == len(daily_frame.index) - 1)):
            current_position = 0
            exit_price_list.append(daily_frame['open'].iloc[i] -
                                   0.5 * tick_size)
            exit_index_list.append(i)
            stop_adjustment_possible_Q = False

        if (current_position < 0) and ((daily_frame['hour_minute'].iloc[i] >=
                                        latest_trade_exit_hour_minute) |
                                       (i == len(daily_frame.index) - 1)):
            current_position = 0
            exit_price_list.append(daily_frame['open'].iloc[i] +
                                   0.5 * tick_size)
            exit_index_list.append(i)
            stop_adjustment_possible_Q = False

        if (current_position > 0) and (daily_frame['low'].iloc[i] <=
                                       stop_price_list[-1]):
            current_position = 0
            exit_price_list.append(stop_price_list[-1] - 0.5 * tick_size)
            exit_index_list.append(i)
            stop_adjustment_possible_Q = False

        if (current_position < 0) and (daily_frame['high'].iloc[i] >=
                                       stop_price_list[-1]):
            current_position = 0
            exit_price_list.append(stop_price_list[-1] + 0.5 * tick_size)
            exit_index_list.append(i)
            stop_adjustment_possible_Q = False

        if (current_position > 0) and (daily_frame['high'].iloc[i] >=
                                       target_price_list[-1]):
            stop_adjustment_possible_Q = True

        if (current_position < 0) and (daily_frame['low'].iloc[i] <=
                                       target_price_list[-1]):
            stop_adjustment_possible_Q = True

    trades_frame = pd.DataFrame.from_items([
        ('direction', direction_list), ('entry_price', entry_price_list),
        ('exit_price', exit_price_list), ('entry_index', entry_index_list),
        ('exit_index', exit_index_list),
        ('entry_hour_minute', entry_hour_minute_list),
        ('target_price', target_price_list), ('ewma300DN', ewma300DN_list),
        ('trend_age', trend_age_list), ('bullishWCumsum', bullishWCumsum_list),
        ('bearishWCumsum', bearishWCumsum_list)
    ])

    trades_frame['pnl'] = (
        trades_frame['exit_price'] -
        trades_frame['entry_price']) * trades_frame['direction']

    trades_frame['pnl_dollar'] = cmi.contract_multiplier[
        ticker_head] * trades_frame['pnl']
    trades_frame['stop_loss'] = abs(trades_frame['entry_price'] -
                                    trades_frame['target_price'])
    trades_frame['daily_sd'] = daily_sd
    trades_frame['normalized_stop_loss'] = trades_frame['stop_loss'] / daily_sd
    trades_frame['pnl_normalized'] = trades_frame['pnl'] / daily_sd

    trades_frame['ticker_head'] = ticker_head
    trades_frame['ticker'] = ticker
    trades_frame['trend1'] = trend1
    trades_frame['trend2'] = trend2
    trades_frame['trade_date'] = date_to

    return {'trades_frame': trades_frame, 'daily_frame': daily_frame}
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 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_aligned_futures_data(**kwargs):

    contract_list = kwargs['contract_list']
    aggregation_method = kwargs['aggregation_method']
    contracts_back = kwargs['contracts_back']
    date_to = kwargs['date_to']

    if 'use_last_as_current' in kwargs.keys():
        use_last_as_current = kwargs['use_last_as_current']
    else:
        use_last_as_current = False

    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 contract_list]

    if 'futures_data_dictionary' in kwargs.keys():
        futures_data_dictionary = kwargs['futures_data_dictionary']
    else:
        ticker_head_list = [cmi.get_contract_specs(x)['ticker_head'] for x in contract_list]
        futures_data_dictionary = {x: gfp.get_futures_price_preloaded(ticker_head=x) for x in ticker_head_list}

    date_from = cu.doubledate_shift(date_to, 2*3650)

    date_to_datetime = cu.convert_doubledate_2datetime(date_to)
    date_from_datetime = cu.convert_doubledate_2datetime(date_from)

    tr_days_half_band_width_selected = tr_days_half_band_with[aggregation_method]

    num_contracts = len(contract_list)

    contract_specs_list = [cmi.get_contract_specs(x) for x in contract_list]

    data_frame_list = []

    for i in range(num_contracts):

        futures_data_frame = futures_data_dictionary[contract_specs_list[i]['ticker_head']]

        selection_indx = (futures_data_frame['tr_dte'] >= tr_dte_list[i]-tr_days_half_band_width_selected)& \
                             (futures_data_frame['tr_dte'] <= tr_dte_list[i]+tr_days_half_band_width_selected)& \
                             (futures_data_frame['cal_dte'] >= 0)& \
                             (futures_data_frame['settle_date'] >= date_from_datetime) & \
                             (futures_data_frame['settle_date'] <= date_to_datetime)

        futures_data_frame = futures_data_frame[selection_indx]

        data_frame_list.append(futures_data_frame)

    cont_indx_list_rolls = [get_cont_indx_list_history({'current_year': x['ticker_year'],
                                 'current_month': x['ticker_month_num'],
                                 'aggregation_method': aggregation_method,
                                  'contracts_back': contracts_back}) for x in contract_specs_list]

    merged_dataframe_list = [None]*contracts_back

    for i in range(contracts_back):
        if sum([(data_frame_list[j]['cont_indx'] == cont_indx_list_rolls[j][i]).any() for j in range(len(contract_list))])<len(contract_list):
            continue
        contract_data_list = [None]*num_contracts
        for k in range(num_contracts):
            contract_data_list[k] = data_frame_list[k][data_frame_list[k]['cont_indx']==cont_indx_list_rolls[k][i]]
            contract_data_list[k].set_index('settle_date',inplace=True)

        merged_dataframe_list[i] = pd.concat(contract_data_list, axis=1, join='inner',keys=['c'+ str(x+1) for x in range(num_contracts)])

    aligned_dataframe = pd.concat(merged_dataframe_list)
    aligned_dataframe.sort_index(inplace=True)

    aligned_dataframe['tr_dte_match'] = abs(aligned_dataframe['c1']['tr_dte']-tr_dte_list[0])
    aligned_dataframe['settle_date'] = aligned_dataframe.index

    aligned_dataframe.sort(['settle_date','tr_dte_match'],ascending=[True,True],inplace=True)
    aligned_dataframe.drop_duplicates('settle_date',inplace=True)

    if use_last_as_current:
        current_data = aligned_dataframe.iloc[-1]
    else:
        current_data = aligned_dataframe.loc[cu.convert_doubledate_2datetime(date_to)]

    return {'aligned_data': aligned_dataframe, 'current_data': current_data}
def get_intraday_trend_signals(**kwargs):

    ticker = kwargs['ticker']
    date_to = kwargs['date_to']
    datetime_to = cu.convert_doubledate_2datetime(date_to)
    breakout_method = 2

    #print(ticker)

    ticker_head = cmi.get_contract_specs(ticker)['ticker_head']
    contract_multiplier = cmi.contract_multiplier[ticker_head]
    ticker_class = cmi.ticker_class[ticker_head]

    daily_settles = gfp.get_futures_price_preloaded(ticker=ticker)
    daily_settles = daily_settles[daily_settles['settle_date'] <= datetime_to]
    daily_settles['ewma10'] = pd.ewma(daily_settles['close_price'], span=10)
    daily_settles['ewma50'] = pd.ewma(daily_settles['close_price'], span=50)

    if daily_settles['ewma10'].iloc[-1] > daily_settles['ewma50'].iloc[-1]:
        long_term_trend = 1
    else:
        long_term_trend = -1

    date_list = [exp.doubledate_shift_bus_days(double_date=date_to,shift_in_days=1)]
    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['hour_minute'] = [100*x.hour+x.minute for x in intraday_data['time_stamp']]

    end_hour = cmi.last_trade_hour_minute[ticker_head]
    start_hour = cmi.first_trade_hour_minute[ticker_head]

    if ticker_class in ['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)]

    selected_data = intraday_data.iloc[selection_indx]
    selected_data['mid_p'] = (selected_data['c1']['best_bid_p']+selected_data['c1']['best_ask_p'])/2

    selected_data['ewma100'] = pd.ewma(selected_data['mid_p'], span=100)
    selected_data['ewma25'] = pd.ewma(selected_data['mid_p'], span=25)

    selected_data.reset_index(inplace=True,drop=True)

    datetime_to = cu.convert_doubledate_2datetime(date_to)

    range_start = dt.datetime.combine(datetime_to,dt.time(8,30,0,0))
    range_end = dt.datetime.combine(datetime_to,dt.time(9,0,0,0))

    first_30_minutes = selected_data[(selected_data['time_stamp'] >= range_start)&
                                     (selected_data['time_stamp'] <= range_end)]

    trading_data = selected_data[selected_data['time_stamp'] > range_end]

    trading_data_shifted = trading_data.shift(5)

    range_min = first_30_minutes['mid_p'].min()
    range_max = first_30_minutes['mid_p'].max()

    initial_range = range_max-range_min

    if breakout_method == 1:

        bullish_breakout = trading_data[(trading_data['mid_p'] > range_max)&
                                    (trading_data['mid_p'] < range_max+0.5*initial_range)&
                                    (trading_data_shifted['mid_p']<range_max)&
                                    (trading_data['ewma25'] > range_max)&
                                    (trading_data['mid_p'] > trading_data['ewma100'])]

        bearish_breakout = trading_data[(trading_data['mid_p'] < range_min)&
                                    (trading_data['mid_p'] > range_min-0.5*initial_range)&
                                    (trading_data_shifted['mid_p']>range_min)&
                                    (trading_data['ewma25'] < range_min)&
                                    (trading_data['mid_p'] < trading_data['ewma100'])]
    elif breakout_method == 2:

        bullish_breakout = pd.DataFrame()
        bearish_breakout = pd.DataFrame()

        if long_term_trend > 0:
            bullish_breakout = trading_data[(trading_data['mid_p'] > range_max)&
                                        (trading_data_shifted['mid_p']<range_max)&
                                        (long_term_trend == 1)&
                                        (trading_data['mid_p'] > trading_data['ewma100'])]
        elif long_term_trend < 0:
            bearish_breakout = trading_data[(trading_data['mid_p'] < range_min)&
                                        (trading_data_shifted['mid_p']>range_min)&
                                        (long_term_trend == -1)&
                                        (trading_data['mid_p'] < trading_data['ewma100'])]

    bullish_cross = trading_data[trading_data['mid_p'] > trading_data['ewma100']]
    bearish_cross = trading_data[trading_data['mid_p'] < trading_data['ewma100']]

    end_of_day_price = trading_data['mid_p'].iloc[-1]
    end_of_day_time_stamp = trading_data['time_stamp'].iloc[-1]

    valid_bearish_breakoutQ = False
    valid_bullish_breakoutQ = False
    bearish_breakout_price_entry = np.NaN
    bullish_breakout_price_entry = np.NaN

    if not bearish_breakout.empty:
        if bearish_breakout.index[0]+1 < trading_data.index[-1]:
            if trading_data['mid_p'].loc[bearish_breakout.index[0]+1]>range_min-0.5*initial_range:
                valid_bearish_breakoutQ = True
                bearish_breakout_price_entry = trading_data['mid_p'].loc[bearish_breakout.index[0]+1]
                bearish_breakout_time_stamp = trading_data['time_stamp'].loc[bearish_breakout.index[0]+1]

    if not bullish_breakout.empty:
        if bullish_breakout.index[0]+1<trading_data.index[-1]:
            if trading_data['mid_p'].loc[bullish_breakout.index[0]+1]<range_max+0.5*initial_range:
                valid_bullish_breakoutQ = True
                bullish_breakout_price_entry = trading_data['mid_p'].loc[bullish_breakout.index[0]+1]
                bullish_breakout_time_stamp = trading_data['time_stamp'].loc[bullish_breakout.index[0]+1]

    stop_loss = (range_max-range_min)*contract_multiplier

    pnl_list = []
    direction_list = []
    entry_time_list = []
    exit_time_list = []
    entry_price_list = []
    exit_price_list = []
    daily_trade_no_list = []
    exit_type_list = []
    ticker_list = []

    if valid_bearish_breakoutQ:

        direction_list.append(-1)
        entry_time_list.append(bearish_breakout_time_stamp)
        entry_price_list.append(bearish_breakout_price_entry)

        daily_pnl = bearish_breakout_price_entry-end_of_day_price
        exit_price = end_of_day_price
        exit_type = 'eod'
        exit_time = end_of_day_time_stamp
        daily_trade_no = 1

        #bullish_cross_stop_frame = bullish_cross[(bullish_cross['time_stamp'] > bearish_breakout_time_stamp)]

        #if (not bullish_cross_stop_frame.empty) and (bullish_cross_stop_frame.index[0]+1<trading_data.index[-1]):
        #    daily_pnl = bearish_breakout_price_entry-trading_data['mid_p'].loc[bullish_cross_stop_frame.index[0]+1]
        #    exit_price = trading_data['mid_p'].loc[bullish_cross_stop_frame.index[0]+1]
        #    exit_type = 'oso'
        #    exit_time = trading_data['time_stamp'].loc[bullish_cross_stop_frame.index[0]+1]

        #if valid_bullish_breakoutQ:
        #    if bullish_breakout_time_stamp>bearish_breakout_time_stamp:
        #        if bullish_breakout_time_stamp<exit_time:
        #            daily_pnl = bearish_breakout_price_entry-bullish_breakout_price_entry
        #            exit_price = bullish_breakout_price_entry
        #            exit_type = 'fso'
        #            exit_time = bullish_breakout_time_stamp
        #    else:
        #        daily_trade_no = 2

        exit_time_list.append(exit_time)
        exit_type_list.append(exit_type)
        daily_trade_no_list.append(daily_trade_no)
        pnl_list.append(daily_pnl)
        exit_price_list.append(exit_price)
        ticker_list.append(ticker)

    if valid_bullish_breakoutQ:
        direction_list.append(1)
        entry_time_list.append(bullish_breakout_time_stamp)
        entry_price_list.append(bullish_breakout_price_entry)

        daily_pnl = end_of_day_price-bullish_breakout_price_entry
        exit_price = end_of_day_price
        exit_type = 'eod'
        exit_time = end_of_day_time_stamp
        daily_trade_no = 1

        bearish_cross_stop_frame = bearish_cross[(bearish_cross['time_stamp'] > bullish_breakout_time_stamp)]

        #if (not bearish_cross_stop_frame.empty) and (bearish_cross_stop_frame.index[0]+1 < trading_data.index[-1]):
        #    daily_pnl = trading_data['mid_p'].loc[bearish_cross_stop_frame.index[0]+1]-bullish_breakout_price_entry
        #    exit_price = trading_data['mid_p'].loc[bearish_cross_stop_frame.index[0]+1]
        #    exit_type = 'oso'
        #    exit_time = trading_data['time_stamp'].loc[bearish_cross_stop_frame.index[0]+1]

        #if valid_bearish_breakoutQ:
        #    if bearish_breakout_time_stamp>bullish_breakout_time_stamp:
        #        if bearish_breakout_time_stamp<exit_time:
        #            daily_pnl = bearish_breakout_price_entry-bullish_breakout_price_entry
        #            exit_price = bearish_breakout_price_entry
        #            exit_type = 'fso'
        #            exit_time = bearish_breakout_time_stamp
        #    else:
         #       daily_trade_no = 2

        exit_time_list.append(exit_time)
        exit_type_list.append(exit_type)
        daily_trade_no_list.append(daily_trade_no)
        pnl_list.append(daily_pnl)
        exit_price_list.append(exit_price)
        ticker_list.append(ticker)


    pnl_frame = pd.DataFrame.from_items([('ticker', ticker_list),
                                         ('ticker_head',ticker_head),
                                    ('direction', direction_list),
                                         ('entry_price', entry_price_list),
                                         ('exit_price', exit_price_list),
                                    ('pnl', pnl_list),
                                    ('entry_time', entry_time_list),
                                    ('exit_time', exit_time_list),
                                   ('exit_type', exit_type_list),
                                    ('daily_trade_no', daily_trade_no_list)])

    pnl_frame['pnl'] = pnl_frame['pnl']*contract_multiplier

    return {'intraday_data': selected_data, 'range_min': range_min, 'range_max':range_max,'pnl_frame':pnl_frame,'stop_loss':stop_loss}
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_simple_rate(**kwargs):

    as_of_date = kwargs["as_of_date"]
    date_to = kwargs["date_to"]

    if "date_from" in kwargs.keys():
        date_from = kwargs["date_from"]
    else:
        date_from = as_of_date

    if "ticker_head" in kwargs.keys():
        ticker_head = kwargs["ticker_head"]
    else:
        ticker_head = "ED"

    ta_output_dir = dn.get_dated_directory_extension(folder_date=as_of_date, ext="ta")

    file_name = ta_output_dir + "/" + ticker_head + "_interest_curve.pkl"

    # print('as_of_date: ' + str(as_of_date) + ', date_to: ' + str(date_to))

    if os.path.isfile(file_name):
        price_frame = pd.read_pickle(file_name)

    if (not os.path.isfile(file_name)) or price_frame.empty:
        price_frame = gfp.get_futures_price_preloaded(ticker_head=ticker_head, settle_date=as_of_date)
        price_frame = price_frame[price_frame["close_price"].notnull()]

        price_frame.sort("tr_dte", ascending=True, inplace=True)
        price_frame["exp_date"] = [exp.get_futures_expiration(x) for x in price_frame["ticker"]]
        price_frame["implied_rate"] = 100 - price_frame["close_price"]
        price_frame.to_pickle(file_name)

    if price_frame.empty:
        return {
            "rate_output": np.NaN,
            "price_frame": pd.DataFrame(columns=["ticker", "cal_dte", "exp_date", "implied_rate"]),
        }

    datetime_to = cu.convert_doubledate_2datetime(date_to)
    datetime_from = cu.convert_doubledate_2datetime(date_from)

    price_frame_first = price_frame[price_frame["exp_date"] <= datetime_from]
    price_frame_middle = price_frame[
        (price_frame["exp_date"] > datetime_from) & (price_frame["exp_date"] < datetime_to)
    ]

    if price_frame_middle.empty:
        if not price_frame_first.empty:
            rate_output = price_frame_first["implied_rate"].iloc[-1] / 100
        else:
            rate_output = price_frame["implied_rate"].iloc[0] / 100
        return {
            "rate_output": rate_output,
            "price_frame": price_frame[["ticker", "cal_dte", "exp_date", "implied_rate"]],
        }

    if price_frame_first.empty:
        first_rate = price_frame_middle["implied_rate"].iloc[0]
        first_period = (price_frame_middle["exp_date"].iloc[0].to_datetime() - datetime_from).days
    else:
        first_rate = price_frame_first["implied_rate"].iloc[-1]
        first_period = (price_frame_middle["exp_date"].iloc[0].to_datetime() - datetime_from).days

    last_rate = price_frame_middle["implied_rate"].iloc[-1]
    last_period = (datetime_to - price_frame_middle["exp_date"].iloc[-1].to_datetime()).days

    middle_discount = [
        1
        + (
            price_frame_middle["implied_rate"].iloc[x]
            * (price_frame_middle["cal_dte"].iloc[x + 1] - price_frame_middle["cal_dte"].iloc[x])
            / 36500
        )
        for x in range(len(price_frame_middle.index) - 1)
    ]

    total_discount = (
        np.prod(np.array(middle_discount))
        * (1 + (first_rate * first_period / 36500))
        * (1 + (last_rate * last_period / 36500))
    )

    total_period = (
        (price_frame_middle["cal_dte"].iloc[-1] - price_frame_middle["cal_dte"].iloc[0]) + first_period + last_period
    )

    rate_output = (total_discount - 1) * 365 / total_period

    return {"rate_output": rate_output, "price_frame": price_frame[["ticker", "cal_dte", "exp_date", "implied_rate"]]}
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}
Exemple #45
0
def get_strategy_pnl_4day(**kwargs):

    alias = kwargs['alias']
    pnl_date = kwargs['pnl_date']

    #print(pnl_date)

    pnl_datetime = cu.convert_doubledate_2datetime(pnl_date)

    con = msu.get_my_sql_connection(**kwargs)

    if 'trades_frame' in kwargs.keys():
        trades_frame = kwargs['trades_frame']
        ticker_head_list = [cmi.get_contract_specs(x)['ticker_head'] for x in trades_frame['ticker']]
    else:
        trades_frame = ts.get_trades_4strategy_alias(alias=alias,con=con)
        ticker_head_list = [cmi.get_contract_specs(x)['ticker_head'] for x in trades_frame['ticker']]
        trades_frame['contract_multiplier'] = [cmi.contract_multiplier[x] for x in ticker_head_list]
        trades_frame['t_cost'] = [cmi.t_cost[x] for x in ticker_head_list]

    trades_frame['ticker_head'] = ticker_head_list

    if 'futures_data_dictionary' in kwargs.keys():
        futures_data_dictionary = kwargs['futures_data_dictionary']
    else:
        unique_ticker_head_list = list(set(ticker_head_list))
        futures_data_dictionary = {x: gfp.get_futures_price_preloaded(ticker_head=x) for x in unique_ticker_head_list}

    pnl_date_1 = exp.doubledate_shift_bus_days(double_date=pnl_date)

    underlying_frame = trades_frame[trades_frame['instrument'] == 'F']
    option_frame = trades_frame[trades_frame['instrument'] == 'O']

    futures_price_out_1 = [gfp.get_futures_price_preloaded(ticker=x,
                                futures_data_dictionary=futures_data_dictionary,
                                settle_date=pnl_date_1) for x in underlying_frame['ticker']]

    futures_price_out = [gfp.get_futures_price_preloaded(ticker=x,
                                futures_data_dictionary=futures_data_dictionary,
                                settle_date=pnl_date) for x in underlying_frame['ticker']]

    underlying_frame['price_1'] = [np.NaN if x.empty else x['close_price'].values[0] for x in futures_price_out_1]

    underlying_frame['price'] = [np.NaN if x.empty else x['close_price'].values[0] for x in futures_price_out]

    #underlying_frame['price_1'] = [gfp.get_futures_price_preloaded(ticker=x,
    #                            futures_data_dictionary=futures_data_dictionary,
    #                            settle_date=pnl_date_1)['close_price'].values[0] for x in underlying_frame['ticker']]

    #underlying_frame['price'] = [gfp.get_futures_price_preloaded(ticker=x,
    #                            futures_data_dictionary=futures_data_dictionary,
    #                            settle_date=pnl_date)['close_price'].values[0] for x in underlying_frame['ticker']]

    option_frame['price_1'] = [gop.get_options_price_from_db(ticker=option_frame['ticker'].iloc[x],
                                                             strike=option_frame['strike_price'].iloc[x],
                                                             option_type=option_frame['option_type'].iloc[x],
                                                             con=con,settle_date=pnl_date_1,
                                                             return_nan_if_emptyQ = True)['close_price'].values[0] for x in range(len(option_frame.index))]

    option_frame['price'] = [gop.get_options_price_from_db(ticker=option_frame['ticker'].iloc[x],
                                                             strike=option_frame['strike_price'].iloc[x],
                                                             option_type=option_frame['option_type'].iloc[x],
                                                             con=con,settle_date=pnl_date,
                                                             return_nan_if_emptyQ = True)['close_price'].values[0] for x in range(len(option_frame.index))]

    trades_frame = pd.concat([option_frame, underlying_frame])

    position_frame = trades_frame[trades_frame['trade_date'] < pnl_datetime]
    intraday_frame = trades_frame[trades_frame['trade_date'] == pnl_datetime]

    position_pnl_per_ticker = pd.DataFrame(columns=['ticker','pnl_position'])
    intraday_pnl_per_ticker = pd.DataFrame(columns=['ticker','pnl_intraday'])

    position_pnl_per_tickerhead = pd.DataFrame(columns=['ticker_head','pnl_position'])
    intraday_pnl_per_tickerhead = pd.DataFrame(columns=['ticker_head','pnl_intraday'])

    if len(position_frame) == 0:
        position_pnl = 0
    else:
        position_frame['pnl'] = position_frame['contract_multiplier']*\
                                position_frame['trade_quantity']*\
                                (position_frame['price']-position_frame['price_1'])
        position_pnl = position_frame['pnl'].sum()

        position_grouped_per_ticker = position_frame.groupby('ticker')
        position_grouped_per_tickerhead = position_frame.groupby('ticker_head')
        position_pnl_per_ticker['pnl_position'] = (position_grouped_per_ticker['pnl'].sum()).values
        position_pnl_per_ticker['ticker'] = (position_grouped_per_ticker['ticker'].first()).values

        position_pnl_per_tickerhead['pnl_position'] = (position_grouped_per_tickerhead['pnl'].sum()).values
        position_pnl_per_tickerhead['ticker_head'] = (position_grouped_per_tickerhead['ticker_head'].first()).values

    if len(intraday_frame) == 0:
        intraday_pnl = 0
        t_cost = 0
    else:
        intraday_frame['pnl'] = intraday_frame['contract_multiplier']*\
                                intraday_frame['trade_quantity']*\
                                (intraday_frame['price']-intraday_frame['trade_price'])
        intraday_frame['pnl_wtcost'] = intraday_frame['pnl']-abs(intraday_frame['trade_quantity']*intraday_frame['t_cost'])
        intraday_pnl = intraday_frame['pnl'].sum()
        t_cost = (abs(intraday_frame['trade_quantity']*intraday_frame['t_cost'])).sum()

        intraday_grouped_per_ticker = intraday_frame.groupby('ticker')
        intraday_grouped_per_tickerhead = intraday_frame.groupby('ticker_head')
        intraday_pnl_per_ticker['pnl_intraday'] = (intraday_grouped_per_ticker['pnl_wtcost'].sum()).values
        intraday_pnl_per_ticker['ticker'] = (intraday_grouped_per_ticker['ticker'].first()).values

        intraday_pnl_per_tickerhead['pnl_intraday'] = (intraday_grouped_per_tickerhead['pnl_wtcost'].sum()).values
        intraday_pnl_per_tickerhead['ticker_head'] = (intraday_grouped_per_tickerhead['ticker_head'].first()).values

    pnl_per_ticker = pd.merge(position_pnl_per_ticker,intraday_pnl_per_ticker,how='outer',on='ticker')
    intraday_zero_indx = [x not in intraday_pnl_per_ticker['ticker'].values for x in pnl_per_ticker['ticker']]
    position_zero_indx = [x not in position_pnl_per_ticker['ticker'].values for x in pnl_per_ticker['ticker']]
    pnl_per_ticker['pnl_position'][position_zero_indx] = 0
    pnl_per_ticker['pnl_intraday'][intraday_zero_indx] = 0
    pnl_per_ticker['pnl_total'] = pnl_per_ticker['pnl_position']+pnl_per_ticker['pnl_intraday']
    pnl_per_ticker.set_index('ticker', drop=True, inplace=True)

    pnl_per_tickerhead = pd.merge(position_pnl_per_tickerhead,intraday_pnl_per_tickerhead,how='outer',on='ticker_head')
    intraday_zero_indx = [x not in intraday_pnl_per_tickerhead['ticker_head'].values for x in pnl_per_tickerhead['ticker_head']]
    position_zero_indx = [x not in position_pnl_per_tickerhead['ticker_head'].values for x in pnl_per_tickerhead['ticker_head']]
    pnl_per_tickerhead['pnl_position'][position_zero_indx] = 0
    pnl_per_tickerhead['pnl_intraday'][intraday_zero_indx] = 0
    pnl_per_tickerhead['pnl_total'] = pnl_per_tickerhead['pnl_position']+pnl_per_tickerhead['pnl_intraday']
    pnl_per_tickerhead.set_index('ticker_head', drop=True, inplace=True)

    if 'con' not in kwargs.keys():
        con.close()

    return {'total_pnl': int(position_pnl+intraday_pnl - t_cost),
            'position_pnl': int(position_pnl),
            'intraday_pnl': int(intraday_pnl),
            't_cost': int(t_cost),
            'pnl_per_ticker': pnl_per_ticker,
            'pnl_per_tickerhead':pnl_per_tickerhead}
Exemple #46
0
def get_strategy_pnl_4day(**kwargs):

    alias = kwargs['alias']
    pnl_date = kwargs['pnl_date']

    if 'shift_in_days' in kwargs.keys():
        shift_in_days = kwargs['shift_in_days']
    else:
        shift_in_days = 1

    if 'broker' in kwargs.keys():
        broker = kwargs['broker']
    else:
        broker = 'abn'

    #print(pnl_date)

    pnl_datetime = cu.convert_doubledate_2datetime(pnl_date)

    con = msu.get_my_sql_connection(**kwargs)

    if 'trades_frame' in kwargs.keys():
        trades_frame = kwargs['trades_frame']
        ticker_head_list = [
            cmi.get_contract_specs(x)['ticker_head']
            for x in trades_frame['ticker']
        ]
    else:
        trades_frame = ts.get_trades_4strategy_alias(alias=alias, con=con)
        ticker_head_list = [
            cmi.get_contract_specs(x)['ticker_head']
            for x in trades_frame['ticker']
        ]
        trades_frame['contract_multiplier'] = [
            cmi.contract_multiplier[x] for x in ticker_head_list
        ]
        trades_frame['t_cost'] = [
            cmi.get_t_cost(ticker_head=x, broker=broker)
            for x in ticker_head_list
        ]

    trades_frame['ticker_head'] = ticker_head_list

    option_indx = trades_frame['instrument'] == 'O'
    trades_frame['generalized_ticker'] = trades_frame['ticker']
    trades_frame['generalized_ticker'][option_indx] = trades_frame['ticker'][option_indx] + '-' + \
                                                         trades_frame['option_type'][option_indx] + '-' + \
                                                         trades_frame['strike_price'][option_indx].astype(str)

    position_frame_aux = trades_frame[
        trades_frame['trade_date'] < pnl_datetime]
    intraday_frame_aux = trades_frame[trades_frame['trade_date'] ==
                                      pnl_datetime]

    grouped = position_frame_aux.groupby(['generalized_ticker'])
    net_position = pd.DataFrame()
    net_position['qty'] = grouped['trade_quantity'].sum()
    net_position['generalized_ticker'] = grouped['generalized_ticker'].first()
    net_position = net_position[abs(net_position['qty']) > 0.1]

    useful_generalized_ticker_list = list(
        set(net_position['generalized_ticker'].values)
        | set(intraday_frame_aux['generalized_ticker'].unique()))
    trades_frame = trades_frame[trades_frame['generalized_ticker'].isin(
        useful_generalized_ticker_list)]

    if 'futures_data_dictionary' in kwargs.keys():
        futures_data_dictionary = kwargs['futures_data_dictionary']
    else:
        unique_ticker_head_list = list(set(ticker_head_list))
        futures_data_dictionary = {
            x: gfp.get_futures_price_preloaded(ticker_head=x)
            for x in unique_ticker_head_list
        }

    pnl_date_1 = exp.doubledate_shift_bus_days(double_date=pnl_date,
                                               shift_in_days=shift_in_days)

    underlying_frame = trades_frame[trades_frame['instrument'] == 'F']
    option_frame = trades_frame[trades_frame['instrument'] == 'O']

    futures_price_out_1 = [
        gfp.get_futures_price_preloaded(
            ticker=x,
            futures_data_dictionary=futures_data_dictionary,
            settle_date=pnl_date_1) for x in underlying_frame['ticker']
    ]

    futures_price_out = [
        gfp.get_futures_price_preloaded(
            ticker=x,
            futures_data_dictionary=futures_data_dictionary,
            settle_date=pnl_date) for x in underlying_frame['ticker']
    ]

    underlying_frame['price_1'] = [
        np.NaN if x.empty else x['close_price'].values[0]
        for x in futures_price_out_1
    ]

    underlying_frame['price'] = [
        np.NaN if x.empty else x['close_price'].values[0]
        for x in futures_price_out
    ]

    #underlying_frame['price_1'] = [gfp.get_futures_price_preloaded(ticker=x,
    #                            futures_data_dictionary=futures_data_dictionary,
    #                            settle_date=pnl_date_1)['close_price'].values[0] for x in underlying_frame['ticker']]

    #underlying_frame['price'] = [gfp.get_futures_price_preloaded(ticker=x,
    #                            futures_data_dictionary=futures_data_dictionary,
    #                            settle_date=pnl_date)['close_price'].values[0] for x in underlying_frame['ticker']]

    option_frame['price_1'] = [
        gop.get_options_price_from_db(
            ticker=option_frame['ticker'].iloc[x],
            strike=option_frame['strike_price'].iloc[x],
            option_type=option_frame['option_type'].iloc[x],
            con=con,
            settle_date=pnl_date_1,
            return_nan_if_emptyQ=True)['close_price'].values[0]
        for x in range(len(option_frame.index))
    ]

    option_frame['price'] = [
        gop.get_options_price_from_db(
            ticker=option_frame['ticker'].iloc[x],
            strike=option_frame['strike_price'].iloc[x],
            option_type=option_frame['option_type'].iloc[x],
            con=con,
            settle_date=pnl_date,
            return_nan_if_emptyQ=True)['close_price'].values[0]
        for x in range(len(option_frame.index))
    ]

    trades_frame = pd.concat([option_frame, underlying_frame])

    position_frame = trades_frame[trades_frame['trade_date'] < pnl_datetime]

    nan_price_q = position_frame['price'].isnull().values.any()

    intraday_frame = trades_frame[trades_frame['trade_date'] == pnl_datetime]

    position_pnl_per_ticker = pd.DataFrame(columns=['ticker', 'pnl_position'])
    intraday_pnl_per_ticker = pd.DataFrame(columns=['ticker', 'pnl_intraday'])

    position_pnl_per_tickerhead = pd.DataFrame(
        columns=['ticker_head', 'pnl_position'])
    intraday_pnl_per_tickerhead = pd.DataFrame(
        columns=['ticker_head', 'pnl_intraday'])

    if len(position_frame) == 0:
        position_pnl = 0
    else:
        position_frame['pnl'] = position_frame['contract_multiplier']*\
                                position_frame['trade_quantity']*\
                                (position_frame['price']-position_frame['price_1'])
        position_pnl = position_frame['pnl'].sum()

        position_grouped_per_ticker = position_frame.groupby('ticker')
        position_grouped_per_tickerhead = position_frame.groupby('ticker_head')
        position_pnl_per_ticker['pnl_position'] = (
            position_grouped_per_ticker['pnl'].sum()).values
        position_pnl_per_ticker['ticker'] = (
            position_grouped_per_ticker['ticker'].first()).values

        position_pnl_per_tickerhead['pnl_position'] = (
            position_grouped_per_tickerhead['pnl'].sum()).values
        position_pnl_per_tickerhead['ticker_head'] = (
            position_grouped_per_tickerhead['ticker_head'].first()).values

    if len(intraday_frame) == 0:
        intraday_pnl = 0
        t_cost = 0
    else:
        intraday_frame['pnl'] = intraday_frame['contract_multiplier']*\
                                intraday_frame['trade_quantity']*\
                                (intraday_frame['price']-intraday_frame['trade_price'])
        intraday_frame['pnl_wtcost'] = intraday_frame['pnl'] - abs(
            intraday_frame['trade_quantity'] * intraday_frame['t_cost'])
        intraday_pnl = intraday_frame['pnl'].sum()
        t_cost = (abs(intraday_frame['trade_quantity'] *
                      intraday_frame['t_cost'])).sum()

        intraday_grouped_per_ticker = intraday_frame.groupby('ticker')
        intraday_grouped_per_tickerhead = intraday_frame.groupby('ticker_head')
        intraday_pnl_per_ticker['pnl_intraday'] = (
            intraday_grouped_per_ticker['pnl_wtcost'].sum()).values
        intraday_pnl_per_ticker['ticker'] = (
            intraday_grouped_per_ticker['ticker'].first()).values

        intraday_pnl_per_tickerhead['pnl_intraday'] = (
            intraday_grouped_per_tickerhead['pnl_wtcost'].sum()).values
        intraday_pnl_per_tickerhead['ticker_head'] = (
            intraday_grouped_per_tickerhead['ticker_head'].first()).values

    pnl_per_ticker = pd.merge(position_pnl_per_ticker,
                              intraday_pnl_per_ticker,
                              how='outer',
                              on='ticker')
    intraday_zero_indx = [
        x not in intraday_pnl_per_ticker['ticker'].values
        for x in pnl_per_ticker['ticker']
    ]
    position_zero_indx = [
        x not in position_pnl_per_ticker['ticker'].values
        for x in pnl_per_ticker['ticker']
    ]
    pnl_per_ticker['pnl_position'][position_zero_indx] = 0
    pnl_per_ticker['pnl_intraday'][intraday_zero_indx] = 0
    pnl_per_ticker['pnl_total'] = pnl_per_ticker[
        'pnl_position'] + pnl_per_ticker['pnl_intraday']
    pnl_per_ticker.set_index('ticker', drop=True, inplace=True)

    pnl_per_tickerhead = pd.merge(position_pnl_per_tickerhead,
                                  intraday_pnl_per_tickerhead,
                                  how='outer',
                                  on='ticker_head')
    intraday_zero_indx = [
        x not in intraday_pnl_per_tickerhead['ticker_head'].values
        for x in pnl_per_tickerhead['ticker_head']
    ]
    position_zero_indx = [
        x not in position_pnl_per_tickerhead['ticker_head'].values
        for x in pnl_per_tickerhead['ticker_head']
    ]
    pnl_per_tickerhead['pnl_position'][position_zero_indx] = 0
    pnl_per_tickerhead['pnl_intraday'][intraday_zero_indx] = 0
    pnl_per_tickerhead['pnl_total'] = pnl_per_tickerhead[
        'pnl_position'] + pnl_per_tickerhead['pnl_intraday']
    pnl_per_tickerhead.set_index('ticker_head', drop=True, inplace=True)

    if 'con' not in kwargs.keys():
        con.close()

    return {
        'total_pnl': int(position_pnl + intraday_pnl - t_cost),
        'position_pnl': int(position_pnl),
        'intraday_pnl': int(intraday_pnl),
        't_cost': int(t_cost),
        'nan_price_q': nan_price_q,
        'pnl_per_ticker': pnl_per_ticker,
        'pnl_per_tickerhead': pnl_per_tickerhead
    }
Exemple #47
0
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
    }
Exemple #48
0
def get_strategy_pnl(**kwargs):

    alias = kwargs['alias']
    con = msu.get_my_sql_connection(**kwargs)

    strategy_info = ts.get_strategy_info_from_alias(alias=alias, con=con)

    if 'as_of_date' in kwargs.keys():
        as_of_date = kwargs['as_of_date']
    else:
        as_of_date = exp.doubledate_shift_bus_days()

    if 'broker' in kwargs.keys():
        broker = kwargs['broker']
    else:
        broker = 'abn'

    open_date = int(strategy_info['open_date'].strftime('%Y%m%d'))
    #open_date = 20160920
    close_date = int(strategy_info['close_date'].strftime('%Y%m%d'))

    if close_date > as_of_date:
        close_date = as_of_date

    bus_day_list = exp.get_bus_day_list(date_from=open_date,
                                        date_to=close_date)

    trades_frame = ts.get_trades_4strategy_alias(alias=alias, con=con)

    if sum(trades_frame['instrument'] == 'S') > 0:
        stock_strategy_Q = True
    else:
        stock_strategy_Q = False

    if stock_strategy_Q:

        return {
            'pnl_frame': pd.DataFrame(),
            'daily_pnl': np.nan,
            'total_pnl': np.nan
        }

        unique_ticker_list = trades_frame['ticker'].unique()
        stock_data_dictionary = {
            x: gsp.get_stock_price_preloaded(ticker=x)
            for x in unique_ticker_list
        }

        trades_frame['t_cost'] = [
            smi.get_ib_t_cost(price=trades_frame['trade_price'].iloc[x],
                              quantity=trades_frame['trade_quantity'].iloc[x])
            for x in range(len(trades_frame.index))
        ]
        pnl_path = [
            get_stock_strategy_pnl_4day(
                alias=alias,
                pnl_date=x,
                con=con,
                trades_frame=trades_frame,
                stock_data_dictionary=stock_data_dictionary)
            for x in bus_day_list
        ]

        nan_price_q_list = [x['nan_price_q'] for x in pnl_path]
        good_price_q_list = [not i for i in nan_price_q_list]

        bus_day_after_nan_list = [
            bus_day_list[x + 1] for x in range(len(bus_day_list) - 1)
            if nan_price_q_list[x]
        ]

        pnl_path = [
            pnl_path[x] for x in range(len(pnl_path)) if good_price_q_list[x]
        ]
        bus_day_list = [
            bus_day_list[x] for x in range(len(bus_day_list))
            if good_price_q_list[x]
        ]

        # print(bus_day_list)
        # print(bus_day_after_nan_list)

        if len(bus_day_after_nan_list) > 0:
            pnl_path_after_nan = [
                get_stock_strategy_pnl_4day(
                    alias=alias,
                    pnl_date=x,
                    con=con,
                    trades_frame=trades_frame,
                    broker=broker,
                    shift_in_days=2,
                    stock_data_dictionary=stock_data_dictionary)
                for x in bus_day_after_nan_list
            ]
            for i in range(len(bus_day_after_nan_list)):

                if bus_day_after_nan_list[i] in bus_day_list:
                    index_val = bus_day_list.index(bus_day_after_nan_list[i])
                    pnl_path[index_val] = pnl_path_after_nan[i]

        pnl_frame = pd.DataFrame(pnl_path)
        pnl_frame['settle_date'] = bus_day_list

        output_dictionary = {
            'pnl_frame':
            pnl_frame[[
                'settle_date', 'position_pnl', 'intraday_pnl', 't_cost',
                'total_pnl'
            ]],
            'daily_pnl':
            pnl_frame['total_pnl'].values[-1],
            'total_pnl':
            pnl_frame['total_pnl'].sum()
        }

    else:

        ticker_head_list = [
            cmi.get_contract_specs(x)['ticker_head']
            for x in trades_frame['ticker']
        ]
        unique_ticker_head_list = list(set(ticker_head_list))

        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 unique_ticker_head_list
            }

        trades_frame['contract_multiplier'] = [
            cmi.contract_multiplier[x] for x in ticker_head_list
        ]
        trades_frame['t_cost'] = [
            cmi.get_t_cost(ticker_head=x, broker=broker)
            for x in ticker_head_list
        ]

        pnl_path = [
            get_strategy_pnl_4day(
                alias=alias,
                pnl_date=x,
                con=con,
                trades_frame=trades_frame,
                broker=broker,
                futures_data_dictionary=futures_data_dictionary)
            for x in bus_day_list
        ]

        nan_price_q_list = [x['nan_price_q'] for x in pnl_path]
        good_price_q_list = [not i for i in nan_price_q_list]

        bus_day_after_nan_list = [
            bus_day_list[x + 1] for x in range(len(bus_day_list) - 1)
            if nan_price_q_list[x]
        ]

        pnl_path = [
            pnl_path[x] for x in range(len(pnl_path)) if good_price_q_list[x]
        ]
        bus_day_list = [
            bus_day_list[x] for x in range(len(bus_day_list))
            if good_price_q_list[x]
        ]

        #print(bus_day_list)
        #print(bus_day_after_nan_list)

        if len(bus_day_after_nan_list) > 0:
            pnl_path_after_nan = [
                get_strategy_pnl_4day(
                    alias=alias,
                    pnl_date=x,
                    con=con,
                    trades_frame=trades_frame,
                    broker=broker,
                    shift_in_days=2,
                    futures_data_dictionary=futures_data_dictionary)
                for x in bus_day_after_nan_list
            ]
            for i in range(len(bus_day_after_nan_list)):
                index_val = bus_day_list.index(bus_day_after_nan_list[i])
                pnl_path[index_val] = pnl_path_after_nan[i]

        pnl_per_tickerhead_list = [x['pnl_per_tickerhead'] for x in pnl_path]

        pnl_per_tickerhead = pd.concat(pnl_per_tickerhead_list,
                                       axis=1,
                                       sort=True)
        pnl_per_tickerhead = pnl_per_tickerhead[['pnl_total']]
        pnl_per_tickerhead = pnl_per_tickerhead.transpose()

        if len(unique_ticker_head_list) > 1:
            zero_indx = [[x not in y.index for y in pnl_per_tickerhead_list]
                         for x in pnl_per_tickerhead.columns]

            for i in range(len(pnl_per_tickerhead.columns)):
                pnl_per_tickerhead.iloc[:, i][zero_indx[i]] = 0

        pnl_per_tickerhead['settle_date'] = bus_day_list
        pnl_per_tickerhead.reset_index(inplace=True, drop=True)

        pnl_frame = pd.DataFrame(pnl_path)
        pnl_frame['settle_date'] = bus_day_list

        daily_index = pnl_frame['settle_date'] == as_of_date

        if sum(daily_index) == 0:
            daily_pnl = np.nan
        else:
            daily_pnl = pnl_frame['total_pnl'].values[-1]

        output_dictionary = {
            'pnl_frame':
            pnl_frame[[
                'settle_date', 'position_pnl', 'intraday_pnl', 't_cost',
                'total_pnl'
            ]],
            'pnl_per_tickerhead':
            pnl_per_tickerhead,
            'daily_pnl':
            daily_pnl,
            'total_pnl':
            pnl_frame['total_pnl'].sum()
        }

    if 'con' not in kwargs.keys():
        con.close()

    return output_dictionary
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
Exemple #50
0
def generate_scv_sheet_4date(**kwargs):

    date_to = kwargs['date_to']

    output_dir = ts.create_strategy_output_dir(strategy_class='scv', report_date=date_to)

    if os.path.isfile(output_dir + '/summary.pkl'):
        scv_frame = pd.read_pickle(output_dir + '/summary.pkl')
        return {'scv_frame': scv_frame, 'success': True}

    con = msu.get_my_sql_connection(**kwargs)

    scv_frame = get_single_contracts_4date(settle_date=date_to, con=con)

    futures_data_dictionary = {x: gfp.get_futures_price_preloaded(ticker_head=x) for x in cmi.cme_futures_tickerhead_list}

    num_tickers = len(scv_frame.index)

    q_list = [None]*num_tickers
    downside_list = [None]*num_tickers
    upside_list = [None]*num_tickers
    theta_list = [None]*num_tickers
    realized_vol_forecast_list = [None]*num_tickers
    realized_vol20_list = [None]*num_tickers
    imp_vol_list = [None]*num_tickers
    imp_vol_premium_list = [None]*num_tickers

    for i in range(num_tickers):

        #print(scv_frame['ticker'].iloc[i])

        scv_output = scvs.get_scv_signals(ticker=scv_frame['ticker'].iloc[i], date_to=date_to,
                                          con=con, futures_data_dictionary=futures_data_dictionary)

        q_list[i] = scv_output['q']
        downside_list[i] = scv_output['downside']
        upside_list[i] = scv_output['upside']
        theta_list[i] = scv_output['theta']
        imp_vol_premium_list[i] = scv_output['imp_vol_premium']
        imp_vol_list[i] = scv_output['imp_vol']
        realized_vol_forecast_list[i] = scv_output['realized_vol_forecast']
        realized_vol20_list[i] = scv_output['real_vol20_current']

    scv_frame['Q'] = q_list
    scv_frame['premium'] = imp_vol_premium_list
    scv_frame['impVol'] = imp_vol_list
    scv_frame['forecast'] = realized_vol_forecast_list
    scv_frame['realVol20'] = realized_vol20_list
    scv_frame['downside'] = downside_list
    scv_frame['upside'] = upside_list
    scv_frame['theta'] = theta_list

    scv_frame['downside'] = scv_frame['downside'].round(2)
    scv_frame['upside'] = scv_frame['upside'].round(2)
    scv_frame['theta'] = scv_frame['theta'].round(2)
    scv_frame['premium'] = scv_frame['premium'].round(1)
    scv_frame['forecast'] = scv_frame['forecast'].round(2)
    scv_frame['realVol20'] = scv_frame['realVol20'].round(2)
    scv_frame['impVol'] = scv_frame['impVol'].round(2)

    scv_frame.to_pickle(output_dir + '/summary.pkl')

    return {'scv_frame': scv_frame, 'success': True}
def get_fm_signals(**kwargs):

    ticker_head = kwargs['ticker_head']
    date_to = kwargs['date_to']

    #print(ticker_head)

    ticker_class = cmi.ticker_class[ticker_head]

    datetime_to = cu.convert_doubledate_2datetime(date_to)

    date5_years_ago = cu.doubledate_shift(date_to,5*365)
    datetime5_years_ago = cu.convert_doubledate_2datetime(date5_years_ago)

    data_out = gfp.get_futures_price_preloaded(ticker_head=ticker_head,settle_date_to=datetime_to)

    data4day = data_out[data_out['settle_date']==datetime_to]
    data4day = data4day[data4day['tr_dte']>=20]

    if len(data4day.index)<2:
        return {'ticker': '', 'comm_net': np.nan, 'spec_net': np.nan,
            'comm_cot_index_slow': np.nan, 'comm_cot_index_fast': np.nan, 'trend_direction': np.nan,'curve_slope': np.nan,
            'rsi_3': np.nan, 'rsi_7': np.nan, 'rsi_14': np.nan,
            'change1': np.nan,
            'change1_instant': np.nan,
            'change5': np.nan,
            'change10': np.nan,
            'change20': np.nan,
            'change1_dollar': np.nan,
            'change1_instant_dollar': np.nan,
            'change5_dollar': np.nan,
            'change10_dollar': np.nan,
            'change20_dollar': np.nan}

    data4day.sort_values('volume', ascending=False, inplace=True)
    data4day = data4day.iloc[:2]

    data4day.sort_values('tr_dte',ascending=True,inplace=True)

    ticker1 = data4day['ticker'].iloc[0]
    ticker2 = data4day['ticker'].iloc[1]

    tr_dte_list = [data4day['tr_dte'].iloc[0], data4day['tr_dte'].iloc[1]]

    amcb_output = opUtil.get_aggregation_method_contracts_back({'ticker_head': ticker_head, 'ticker_class': cmi.ticker_class[ticker_head]})
    aggregation_method = amcb_output['aggregation_method']
    contracts_back = amcb_output['contracts_back']

    futures_data_dictionary = {ticker_head: data_out}

    aligned_output = opUtil.get_aligned_futures_data(contract_list=[ticker1,ticker2],
                                                          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=False)

    aligned_data = aligned_output['aligned_data']
    current_data = aligned_output['current_data']

    yield1_current = 100*(current_data['c1']['close_price']-current_data['c2']['close_price'])/current_data['c2']['close_price']
    yield1 = 100*(aligned_data['c1']['close_price']-aligned_data['c2']['close_price'])/aligned_data['c2']['close_price']

    last5_years_indx = aligned_data['settle_date']>=datetime5_years_ago

    yield1_last5_years = yield1[last5_years_indx]
    curve_slope = stats.get_quantile_from_number({'x':yield1_current,'y': yield1_last5_years})

    ticker_head_data = gfp.get_futures_price_preloaded(ticker_head=ticker_head)
    ticker_head_data = ticker_head_data[ticker_head_data['settle_date'] <= datetime_to]

    if ticker_class in ['Index', 'FX', 'Metal', 'Treasury', 'STIR']:

        merged_data = ticker_head_data[ticker_head_data['tr_dte'] >= 10]
        merged_data.sort_values(['settle_date', 'tr_dte'],ascending=True,inplace=True)
        merged_data.drop_duplicates(subset=['settle_date'], keep='first', inplace=True)

        merged_data['ma200'] = merged_data['close_price'].rolling(200).mean()
        merged_data['ma200_10'] = merged_data['ma200']-merged_data['ma200'].shift(10)
    else:
        data_out_front = ticker_head_data[ticker_head_data['tr_dte'] <= 60]
        data_out_front.drop_duplicates(subset=['settle_date'], keep='last', inplace=True)

        data_out_back = ticker_head_data[ticker_head_data['tr_dte'] > 60]
        data_out_back.drop_duplicates(subset=['settle_date'], keep='last', inplace=True)

        merged_data = pd.merge(data_out_front[['settle_date','tr_dte','close_price']],data_out_back[['tr_dte','close_price','settle_date','ticker','change_1']],how='inner',on='settle_date')
        merged_data['const_mat']=((merged_data['tr_dte_y']-60)*merged_data['close_price_x']+
                                  (60-merged_data['tr_dte_x'])*merged_data['close_price_y'])/\
                                 (merged_data['tr_dte_y']-merged_data['tr_dte_x'])

        merged_data['ma200'] = merged_data['const_mat'].rolling(200).mean()
        merged_data['ma200_10'] = merged_data['ma200']-merged_data['ma200'].shift(10)

    merged_data = merged_data[merged_data['settle_date']==datetime_to]

    if len(merged_data.index) == 0:
        trend_direction = np.nan
    elif merged_data['ma200_10'].iloc[0]>=0:
        trend_direction = 1
    else:
        trend_direction = -1

    ticker_data = gfp.get_futures_price_preloaded(ticker=ticker2,settle_date_to=datetime_to)

    ticker_data = ti.rsi(data_frame_input=ticker_data, change_field='change_1', period=3)
    ticker_data = ti.rsi(data_frame_input=ticker_data, change_field='change_1', period=7)
    ticker_data = ti.rsi(data_frame_input=ticker_data, change_field='change_1', period=14)

    cot_output = cot.get_cot_data(ticker_head=ticker_head, date_to=date_to)

    daily_noise = np.std(ticker_data['change_1'].iloc[-60:])

    if len(cot_output.index)>0:

        if ticker_class in ['FX','STIR','Index','Treasury']:

            cot_output['comm_long'] = cot_output['Asset Manager Longs']+cot_output['Dealer Longs']
            cot_output['comm_short'] = cot_output['Asset Manager Shorts']+cot_output['Dealer Shorts']
            cot_output['comm_net'] = cot_output['comm_long']-cot_output['comm_short']

            cot_output['spec_long'] = cot_output['Leveraged Funds Longs']
            cot_output['spec_short'] = cot_output['Leveraged Funds Shorts']
            cot_output['spec_net'] = cot_output['spec_long']-cot_output['spec_short']

        else:
            cot_output['comm_long'] = cot_output['Producer/Merchant/Processor/User Longs']+cot_output['Swap Dealer Longs']
            cot_output['comm_short'] = cot_output['Producer/Merchant/Processor/User Shorts']+cot_output['Swap Dealer Shorts']
            cot_output['comm_net'] = cot_output['comm_long']-cot_output['comm_short']
            cot_output['spec_long'] = cot_output['Money Manager Longs']+cot_output['Other Reportable Longs']
            cot_output['spec_short'] = cot_output['Money Manager Shorts']+cot_output['Other Reportable Shorts']
            cot_output['spec_net'] = cot_output['spec_long']-cot_output['spec_short']

        if (datetime_to-cot_output['settle_date'].iloc[-1]).days>=10:
            comm_net = np.nan
            spec_net = np.nan
        else:
            comm_net = cot_output['comm_net'].iloc[-1]
            spec_net = cot_output['spec_net'].iloc[-1]

        comm_net_min_slow = cot_output['comm_net'].iloc[-156:].min()
        comm_net_max_slow = cot_output['comm_net'].iloc[-156:].max()

        comm_cot_index_slow = 100*(comm_net-comm_net_min_slow)/(comm_net_max_slow-comm_net_min_slow)

        comm_net_min_fast = cot_output['comm_net'].iloc[-52:].min()
        comm_net_max_fast = cot_output['comm_net'].iloc[-52:].max()

        comm_cot_index_fast = 100*(comm_net-comm_net_min_fast)/(comm_net_max_fast-comm_net_min_fast)

    else:
        comm_net = np.nan
        spec_net = np.nan
        comm_cot_index_slow = np.nan
        comm_cot_index_fast = np.nan

    contract_multiplier = cmi.contract_multiplier[ticker_head]

    return {'ticker': ticker2, 'comm_net': comm_net, 'spec_net': spec_net,
            'comm_cot_index_slow': comm_cot_index_slow, 'comm_cot_index_fast': comm_cot_index_fast, 'trend_direction': trend_direction,'curve_slope': curve_slope,
            'rsi_3': ticker_data['rsi_3'].iloc[-1], 'rsi_7': ticker_data['rsi_7'].iloc[-1], 'rsi_14': ticker_data['rsi_14'].iloc[-1],
            'change1': ticker_data['change1'].iloc[-1]/daily_noise,
            'change1_instant': ticker_data['change1_instant'].iloc[-1]/daily_noise,
            'change5': ticker_data['change5'].iloc[-1]/daily_noise,
            'change10': ticker_data['change10'].iloc[-1]/daily_noise,
            'change20': ticker_data['change20'].iloc[-1]/daily_noise,
            'change1_dollar': ticker_data['change1'].iloc[-1]*contract_multiplier,
            'change1_instant_dollar': ticker_data['change1_instant'].iloc[-1]*contract_multiplier,
            'change5_dollar': ticker_data['change5'].iloc[-1]*contract_multiplier,
            'change10_dollar': ticker_data['change10'].iloc[-1]*contract_multiplier,
            'change20_dollar': ticker_data['change20'].iloc[-1]*contract_multiplier}
def get_backtest_summary_4_date(**kwargs):

    report_date = kwargs["report_date"]
    futures_data_dictionary = kwargs["futures_data_dictionary"]

    if "use_existing_filesQ" in kwargs.keys():
        use_existing_filesQ = kwargs["use_existing_filesQ"]
    else:
        use_existing_filesQ = True

    output_dir = ts.create_strategy_output_dir(strategy_class="futures_butterfly", report_date=report_date)

    if os.path.isfile(output_dir + "/backtest_results.pkl") and use_existing_filesQ:
        return pd.read_pickle(output_dir + "/backtest_results.pkl")

    butt_out = opfb.generate_futures_butterfly_sheet_4date(date_to=report_date)

    strategy_sheet = butt_out["butterflies"]
    num_trades = len(strategy_sheet.index)

    holding_period5 = [np.NAN] * num_trades
    holding_period10 = [np.NAN] * num_trades
    holding_period15 = [np.NAN] * num_trades
    holding_period20 = [np.NAN] * num_trades
    holding_period25 = [np.NAN] * num_trades

    path_pnl5 = [np.NAN] * num_trades
    path_pnl10 = [np.NAN] * num_trades
    path_pnl15 = [np.NAN] * num_trades
    path_pnl20 = [np.NAN] * num_trades
    path_pnl25 = [np.NAN] * num_trades

    hold_pnl1long = [np.NAN] * num_trades
    hold_pnl2long = [np.NAN] * num_trades
    hold_pnl5long = [np.NAN] * num_trades
    hold_pnl10long = [np.NAN] * num_trades
    hold_pnl20long = [np.NAN] * num_trades

    hold_pnl1short = [np.NAN] * num_trades
    hold_pnl2short = [np.NAN] * num_trades
    hold_pnl5short = [np.NAN] * num_trades
    hold_pnl10short = [np.NAN] * num_trades
    hold_pnl20short = [np.NAN] * num_trades

    path_pnl5_per_contract = [np.NAN] * num_trades
    path_pnl10_per_contract = [np.NAN] * num_trades
    path_pnl15_per_contract = [np.NAN] * num_trades
    path_pnl20_per_contract = [np.NAN] * num_trades
    path_pnl25_per_contract = [np.NAN] * num_trades

    hold_pnl1long_per_contract = [np.NAN] * num_trades
    hold_pnl2long_per_contract = [np.NAN] * num_trades
    hold_pnl5long_per_contract = [np.NAN] * num_trades
    hold_pnl10long_per_contract = [np.NAN] * num_trades
    hold_pnl20long_per_contract = [np.NAN] * num_trades

    hold_pnl1short_per_contract = [np.NAN] * num_trades
    hold_pnl2short_per_contract = [np.NAN] * num_trades
    hold_pnl5short_per_contract = [np.NAN] * num_trades
    hold_pnl10short_per_contract = [np.NAN] * num_trades
    hold_pnl20short_per_contract = [np.NAN] * num_trades

    for i in range(num_trades):
        sheet_entry = strategy_sheet.iloc[i]

        data_list = []

        for j in range(3):

            ticker_frame = gfp.get_futures_price_preloaded(
                ticker=sheet_entry["ticker" + str(j + 1)],
                futures_data_dictionary=futures_data_dictionary,
                settle_date_from_exclusive=report_date,
            )

            ticker_frame.set_index("settle_date", drop=False, inplace=True)
            data_list.append(ticker_frame)

        merged_data = pd.concat(data_list, axis=1, join="inner")

        mid_price = (
            merged_data["close_price"].iloc[:, 0] * sheet_entry["weight1"]
            + merged_data["close_price"].iloc[:, 2] * sheet_entry["weight3"]
        )
        ratio_path = mid_price / (-sheet_entry["weight2"] * merged_data["close_price"].iloc[:, 1])

        if len(ratio_path.index) < 6:
            continue

        if sheet_entry["second_spread_weight_1"] < 0:
            continue

        quantity_long = round(10000 / abs(sheet_entry["downside"]))
        quantity_short = -round(10000 / abs(sheet_entry["upside"]))

        contracts_traded_per_unit = 4 * (1 + sheet_entry["second_spread_weight_1"])

        if sheet_entry["QF"] > 50:
            trigger_direction = "going_down"
            quantity = quantity_short
        elif sheet_entry["QF"] < 50:
            trigger_direction = "going_up"
            quantity = quantity_long
        else:
            quantity = np.NAN

        total_contracts_traded_per_unit = abs(quantity) * contracts_traded_per_unit

        exit5 = bu.find_exit_point(
            time_series=ratio_path,
            trigger_value=sheet_entry["ratio_target5"],
            trigger_direction=trigger_direction,
            max_exit_point=min(20, len(ratio_path.index) - 1),
        )

        exit10 = bu.find_exit_point(
            time_series=ratio_path,
            trigger_value=sheet_entry["ratio_target10"],
            trigger_direction=trigger_direction,
            max_exit_point=min(20, len(ratio_path.index) - 1),
        )

        exit15 = bu.find_exit_point(
            time_series=ratio_path,
            trigger_value=sheet_entry["ratio_target15"],
            trigger_direction=trigger_direction,
            max_exit_point=min(20, len(ratio_path.index) - 1),
        )

        exit20 = bu.find_exit_point(
            time_series=ratio_path,
            trigger_value=sheet_entry["ratio_target20"],
            trigger_direction=trigger_direction,
            max_exit_point=min(20, len(ratio_path.index) - 1),
        )

        exit25 = bu.find_exit_point(
            time_series=ratio_path,
            trigger_value=sheet_entry["ratio_target25"],
            trigger_direction=trigger_direction,
            max_exit_point=min(20, len(ratio_path.index) - 1),
        )

        holding_period5[i] = exit5
        holding_period10[i] = exit10
        holding_period15[i] = exit15
        holding_period20[i] = exit20
        holding_period25[i] = exit25

        path_path_list = []
        hold_pnl_list = []

        for exit_indx in [exit5, exit10, exit15, exit20, exit25]:

            exit_indx_robust = min(len(ratio_path.index) - 1, exit_indx)

            raw_pnl = (
                (merged_data["close_price"].iloc[exit_indx_robust, 0] - merged_data["close_price"].iloc[0, 0])
                - (1 + sheet_entry["second_spread_weight_1"])
                * (merged_data["close_price"].iloc[exit_indx_robust, 1] - merged_data["close_price"].iloc[0, 1])
                + (sheet_entry["second_spread_weight_1"])
                * (merged_data["close_price"].iloc[exit_indx_robust, 2] - merged_data["close_price"].iloc[0, 2])
            )

            path_path_list.append(raw_pnl * sheet_entry["multiplier"] * quantity)

        for hold_indx in [1, 2, 5, 10, 20]:

            hold_indx_robust = min(len(ratio_path.index) - 1, hold_indx)

            hold_pnl = (
                (merged_data["close_price"].iloc[hold_indx_robust, 0] - merged_data["close_price"].iloc[0, 0])
                - (1 + sheet_entry["second_spread_weight_1"])
                * (merged_data["close_price"].iloc[hold_indx_robust, 1] - merged_data["close_price"].iloc[0, 1])
                + (sheet_entry["second_spread_weight_1"])
                * (merged_data["close_price"].iloc[hold_indx_robust, 2] - merged_data["close_price"].iloc[0, 2])
            )

            hold_pnl_list.append(hold_pnl * sheet_entry["multiplier"])

        path_pnl5[i] = path_path_list[0]
        path_pnl10[i] = path_path_list[1]
        path_pnl15[i] = path_path_list[2]
        path_pnl20[i] = path_path_list[3]
        path_pnl25[i] = path_path_list[4]

        path_pnl5_per_contract[i] = path_path_list[0] / total_contracts_traded_per_unit
        path_pnl10_per_contract[i] = path_path_list[1] / total_contracts_traded_per_unit
        path_pnl15_per_contract[i] = path_path_list[2] / total_contracts_traded_per_unit
        path_pnl20_per_contract[i] = path_path_list[3] / total_contracts_traded_per_unit
        path_pnl25_per_contract[i] = path_path_list[4] / total_contracts_traded_per_unit

        hold_pnl1long[i] = hold_pnl_list[0] * quantity_long
        hold_pnl2long[i] = hold_pnl_list[1] * quantity_long
        hold_pnl5long[i] = hold_pnl_list[2] * quantity_long
        hold_pnl10long[i] = hold_pnl_list[3] * quantity_long
        hold_pnl20long[i] = hold_pnl_list[4] * quantity_long

        hold_pnl1long_per_contract[i] = hold_pnl_list[0] / contracts_traded_per_unit
        hold_pnl2long_per_contract[i] = hold_pnl_list[1] / contracts_traded_per_unit
        hold_pnl5long_per_contract[i] = hold_pnl_list[2] / contracts_traded_per_unit
        hold_pnl10long_per_contract[i] = hold_pnl_list[3] / contracts_traded_per_unit
        hold_pnl20long_per_contract[i] = hold_pnl_list[4] / contracts_traded_per_unit

        hold_pnl1short[i] = hold_pnl_list[0] * quantity_short
        hold_pnl2short[i] = hold_pnl_list[1] * quantity_short
        hold_pnl5short[i] = hold_pnl_list[2] * quantity_short
        hold_pnl10short[i] = hold_pnl_list[3] * quantity_short
        hold_pnl20short[i] = hold_pnl_list[4] * quantity_short

        hold_pnl1short_per_contract[i] = -hold_pnl_list[0] / contracts_traded_per_unit
        hold_pnl2short_per_contract[i] = -hold_pnl_list[1] / contracts_traded_per_unit
        hold_pnl5short_per_contract[i] = -hold_pnl_list[2] / contracts_traded_per_unit
        hold_pnl10short_per_contract[i] = -hold_pnl_list[3] / contracts_traded_per_unit
        hold_pnl20short_per_contract[i] = -hold_pnl_list[4] / contracts_traded_per_unit

    strategy_sheet["holding_period5"] = holding_period5
    strategy_sheet["holding_period10"] = holding_period10
    strategy_sheet["holding_period15"] = holding_period15
    strategy_sheet["holding_period20"] = holding_period20
    strategy_sheet["holding_period25"] = holding_period25

    strategy_sheet["path_pnl5"] = path_pnl5
    strategy_sheet["path_pnl10"] = path_pnl10
    strategy_sheet["path_pnl15"] = path_pnl15
    strategy_sheet["path_pnl20"] = path_pnl20
    strategy_sheet["path_pnl25"] = path_pnl25

    strategy_sheet["path_pnl5_per_contract"] = path_pnl5_per_contract
    strategy_sheet["path_pnl10_per_contract"] = path_pnl10_per_contract
    strategy_sheet["path_pnl15_per_contract"] = path_pnl15_per_contract
    strategy_sheet["path_pnl20_per_contract"] = path_pnl20_per_contract
    strategy_sheet["path_pnl25_per_contract"] = path_pnl25_per_contract

    strategy_sheet["hold_pnl1long"] = hold_pnl1long
    strategy_sheet["hold_pnl2long"] = hold_pnl2long
    strategy_sheet["hold_pnl5long"] = hold_pnl5long
    strategy_sheet["hold_pnl10long"] = hold_pnl10long
    strategy_sheet["hold_pnl20long"] = hold_pnl20long

    strategy_sheet["hold_pnl1long_per_contract"] = hold_pnl1long_per_contract
    strategy_sheet["hold_pnl2long_per_contract"] = hold_pnl2long_per_contract
    strategy_sheet["hold_pnl5long_per_contract"] = hold_pnl5long_per_contract
    strategy_sheet["hold_pnl10long_per_contract"] = hold_pnl10long_per_contract
    strategy_sheet["hold_pnl20long_per_contract"] = hold_pnl20long_per_contract

    strategy_sheet["hold_pnl1short"] = hold_pnl1short
    strategy_sheet["hold_pnl2short"] = hold_pnl2short
    strategy_sheet["hold_pnl5short"] = hold_pnl5short
    strategy_sheet["hold_pnl10short"] = hold_pnl10short
    strategy_sheet["hold_pnl20short"] = hold_pnl20short

    strategy_sheet["hold_pnl1short_per_contract"] = hold_pnl1short_per_contract
    strategy_sheet["hold_pnl2short_per_contract"] = hold_pnl2short_per_contract
    strategy_sheet["hold_pnl5short_per_contract"] = hold_pnl5short_per_contract
    strategy_sheet["hold_pnl10short_per_contract"] = hold_pnl10short_per_contract
    strategy_sheet["hold_pnl20short_per_contract"] = hold_pnl20short_per_contract

    strategy_sheet["report_date"] = report_date

    strategy_sheet["hold_pnl1"] = [np.NAN] * num_trades
    strategy_sheet["hold_pnl2"] = [np.NAN] * num_trades
    strategy_sheet["hold_pnl5"] = [np.NAN] * num_trades
    strategy_sheet["hold_pnl10"] = [np.NAN] * num_trades
    strategy_sheet["hold_pnl20"] = [np.NAN] * num_trades

    strategy_sheet["hold_pnl1_per_contract"] = [np.NAN] * num_trades
    strategy_sheet["hold_pnl2_per_contract"] = [np.NAN] * num_trades
    strategy_sheet["hold_pnl5_per_contract"] = [np.NAN] * num_trades
    strategy_sheet["hold_pnl10_per_contract"] = [np.NAN] * num_trades
    strategy_sheet["hold_pnl20_per_contract"] = [np.NAN] * num_trades

    strategy_sheet.loc[strategy_sheet["QF"] > 50, "hold_pnl1"] = strategy_sheet.loc[
        strategy_sheet["QF"] > 50, "hold_pnl1short"
    ]
    strategy_sheet.loc[strategy_sheet["QF"] > 50, "hold_pnl2"] = strategy_sheet.loc[
        strategy_sheet["QF"] > 50, "hold_pnl2short"
    ]
    strategy_sheet.loc[strategy_sheet["QF"] > 50, "hold_pnl5"] = strategy_sheet.loc[
        strategy_sheet["QF"] > 50, "hold_pnl5short"
    ]
    strategy_sheet.loc[strategy_sheet["QF"] > 50, "hold_pnl10"] = strategy_sheet.loc[
        strategy_sheet["QF"] > 50, "hold_pnl10short"
    ]
    strategy_sheet.loc[strategy_sheet["QF"] > 50, "hold_pnl20"] = strategy_sheet.loc[
        strategy_sheet["QF"] > 50, "hold_pnl20short"
    ]

    strategy_sheet.loc[strategy_sheet["QF"] < 50, "hold_pnl1"] = strategy_sheet.loc[
        strategy_sheet["QF"] < 50, "hold_pnl1long"
    ]
    strategy_sheet.loc[strategy_sheet["QF"] < 50, "hold_pnl2"] = strategy_sheet.loc[
        strategy_sheet["QF"] < 50, "hold_pnl2long"
    ]
    strategy_sheet.loc[strategy_sheet["QF"] < 50, "hold_pnl5"] = strategy_sheet.loc[
        strategy_sheet["QF"] < 50, "hold_pnl5long"
    ]
    strategy_sheet.loc[strategy_sheet["QF"] < 50, "hold_pnl10"] = strategy_sheet.loc[
        strategy_sheet["QF"] < 50, "hold_pnl10long"
    ]
    strategy_sheet.loc[strategy_sheet["QF"] < 50, "hold_pnl20"] = strategy_sheet.loc[
        strategy_sheet["QF"] < 50, "hold_pnl20long"
    ]

    strategy_sheet.loc[strategy_sheet["QF"] > 50, "hold_pnl1_per_contract"] = strategy_sheet.loc[
        strategy_sheet["QF"] > 50, "hold_pnl1short_per_contract"
    ]
    strategy_sheet.loc[strategy_sheet["QF"] > 50, "hold_pnl2_per_contract"] = strategy_sheet.loc[
        strategy_sheet["QF"] > 50, "hold_pnl2short_per_contract"
    ]
    strategy_sheet.loc[strategy_sheet["QF"] > 50, "hold_pnl5_per_contract"] = strategy_sheet.loc[
        strategy_sheet["QF"] > 50, "hold_pnl5short_per_contract"
    ]
    strategy_sheet.loc[strategy_sheet["QF"] > 50, "hold_pnl10_per_contract"] = strategy_sheet.loc[
        strategy_sheet["QF"] > 50, "hold_pnl10short_per_contract"
    ]
    strategy_sheet.loc[strategy_sheet["QF"] > 50, "hold_pnl20_per_contract"] = strategy_sheet.loc[
        strategy_sheet["QF"] > 50, "hold_pnl20short_per_contract"
    ]

    strategy_sheet.loc[strategy_sheet["QF"] < 50, "hold_pnl1_per_contract"] = strategy_sheet.loc[
        strategy_sheet["QF"] < 50, "hold_pnl1long_per_contract"
    ]
    strategy_sheet.loc[strategy_sheet["QF"] < 50, "hold_pnl2_per_contract"] = strategy_sheet.loc[
        strategy_sheet["QF"] < 50, "hold_pnl2long_per_contract"
    ]
    strategy_sheet.loc[strategy_sheet["QF"] < 50, "hold_pnl5_per_contract"] = strategy_sheet.loc[
        strategy_sheet["QF"] < 50, "hold_pnl5long_per_contract"
    ]
    strategy_sheet.loc[strategy_sheet["QF"] < 50, "hold_pnl10_per_contract"] = strategy_sheet.loc[
        strategy_sheet["QF"] < 50, "hold_pnl10long_per_contract"
    ]
    strategy_sheet.loc[strategy_sheet["QF"] < 50, "hold_pnl20_per_contract"] = strategy_sheet.loc[
        strategy_sheet["QF"] < 50, "hold_pnl20long_per_contract"
    ]

    strategy_sheet.to_pickle(output_dir + "/backtest_results.pkl")

    return strategy_sheet
def get_cot_strategy_signals(**kwargs):

    ticker_head = kwargs['ticker_head']
    date_to = kwargs['date_to']
    target_noise = 5000

    ticker_class = cmi.ticker_class[ticker_head]
    datetime_to = cu.convert_doubledate_2datetime(date_to)

    data_out = gfp.get_futures_price_preloaded(ticker_head=ticker_head)
    data_out = data_out[data_out['settle_date'] <= datetime_to]

    data_out_front = data_out[data_out['tr_dte'] <= 60]
    data_out_front.drop_duplicates(subset=['settle_date'], keep='last', inplace=True)

    data_out_back = data_out[data_out['tr_dte'] > 60]
    data_out_back.drop_duplicates(subset=['settle_date'], keep='last', inplace=True)

    merged_data = pd.merge(data_out_front[['settle_date','tr_dte','close_price']],data_out_back[['tr_dte','close_price','settle_date','ticker','change_1']],how='inner',on='settle_date')
    merged_data['const_mat']=((merged_data['tr_dte_y']-60)*merged_data['close_price_x']+
                              (60-merged_data['tr_dte_x'])*merged_data['close_price_y'])/\
                             (merged_data['tr_dte_y']-merged_data['tr_dte_x'])

    merged_data['const_mat_change_1'] = merged_data['const_mat']-merged_data['const_mat'].shift(1)
    merged_data['const_mat_change_10'] = merged_data['const_mat']-merged_data['const_mat'].shift(10)
    merged_data['const_mat_change_20'] = merged_data['const_mat']-merged_data['const_mat'].shift(20)

    merged_data['const_mat_change_1_std'] = pd.rolling_std(merged_data['const_mat_change_1'], window=150, min_periods=75)

    merged_data['const_mat_ma5'] = pd.rolling_mean(merged_data['const_mat'], window=5, min_periods=4)
    merged_data['const_mat_ma10'] = pd.rolling_mean(merged_data['const_mat'], window=10, min_periods=8)
    merged_data['const_mat_ma20'] = pd.rolling_mean(merged_data['const_mat'], window=20, min_periods=16)
    merged_data['const_mat_ma40'] = pd.rolling_mean(merged_data['const_mat'], window=40, min_periods=32)
    merged_data['const_mat_ma80'] = pd.rolling_mean(merged_data['const_mat'], window=80, min_periods=64)

    merged_data['const_mat_ma5spread'] = (merged_data['const_mat']-merged_data['const_mat_ma5'])/merged_data['const_mat_change_1_std']
    merged_data['const_mat_ma10spread'] = (merged_data['const_mat']-merged_data['const_mat_ma10'])/merged_data['const_mat_change_1_std']
    merged_data['const_mat_ma20spread'] = (merged_data['const_mat']-merged_data['const_mat_ma20'])/merged_data['const_mat_change_1_std']
    merged_data['const_mat_ma40spread'] = (merged_data['const_mat']-merged_data['const_mat_ma40'])/merged_data['const_mat_change_1_std']
    merged_data['const_mat_ma80spread'] = (merged_data['const_mat']-merged_data['const_mat_ma80'])/merged_data['const_mat_change_1_std']

    merged_data['const_mat_change1norm'] = (merged_data['const_mat'].shift(-1)-merged_data['const_mat'])/merged_data['const_mat_change_1_std']
    merged_data['const_mat_change2norm'] = (merged_data['const_mat'].shift(-2)-merged_data['const_mat'])/merged_data['const_mat_change_1_std']
    merged_data['const_mat_change5norm'] = (merged_data['const_mat'].shift(-5)-merged_data['const_mat'])/merged_data['const_mat_change_1_std']
    merged_data['const_mat_change10norm'] = (merged_data['const_mat'].shift(-10)-merged_data['const_mat'])/merged_data['const_mat_change_1_std']
    merged_data['const_mat_change20norm'] = (merged_data['const_mat'].shift(-20)-merged_data['const_mat'])/merged_data['const_mat_change_1_std']

    merged_data['const_mat_change_10_std'] = pd.rolling_std(merged_data['const_mat_change_10'], window=150, min_periods=75)
    merged_data['const_mat_change_20_std'] = pd.rolling_std(merged_data['const_mat_change_20'], window=150, min_periods=75)

    merged_data['const_mat_change_10_norm'] = merged_data['const_mat_change_10']/merged_data['const_mat_change_10_std']
    merged_data['const_mat_change_20_norm'] = merged_data['const_mat_change_20']/merged_data['const_mat_change_20_std']

    merged_data['const_mat_min5'] = pd.rolling_min(merged_data['const_mat'], window=5, min_periods=4)
    merged_data['const_mat_min10'] = pd.rolling_min(merged_data['const_mat'], window=10, min_periods=8)
    merged_data['const_mat_min20'] = pd.rolling_min(merged_data['const_mat'], window=20, min_periods=16)

    merged_data['const_mat_max5'] = pd.rolling_max(merged_data['const_mat'], window=5, min_periods=4)
    merged_data['const_mat_max10'] = pd.rolling_max(merged_data['const_mat'], window=10, min_periods=8)
    merged_data['const_mat_max20'] = pd.rolling_max(merged_data['const_mat'], window=20, min_periods=16)

    cot_output = cot.get_cot_data(ticker_head=ticker_head,date_to=date_to)

    if ticker_class in ['FX','STIR','Index','Treasury']:

        cot_output['comm_net'] = cot_output['Dealer Longs']-cot_output['Dealer Shorts']
        cot_output['comm_long'] = cot_output['Dealer Longs']
        cot_output['comm_short'] = cot_output['Dealer Shorts']
        cot_output['spec_net'] = cot_output['Asset Manager Longs']-cot_output['Asset Manager Shorts']+cot_output['Leveraged Funds Longs']-cot_output['Leveraged Funds Shorts']
        cot_output['spec_long'] = cot_output['Asset Manager Longs']+cot_output['Leveraged Funds Longs']
        cot_output['spec_short'] = cot_output['Asset Manager Shorts']+cot_output['Leveraged Funds Shorts']
    else:
        cot_output['comm_net'] = cot_output['Producer/Merchant/Processor/User Longs']-cot_output['Producer/Merchant/Processor/User Shorts']
        cot_output['comm_long'] = cot_output['Producer/Merchant/Processor/User Longs']
        cot_output['comm_short'] = cot_output['Producer/Merchant/Processor/User Shorts']
        cot_output['spec_net'] = cot_output['Money Manager Longs']-cot_output['Money Manager Shorts']
        cot_output['spec_long'] = cot_output['Money Manager Longs']
        cot_output['spec_short'] = cot_output['Money Manager Shorts']


    cot_output['spec_long_per_mean'] = pd.rolling_mean(cot_output['spec_long_per'],window=150,min_periods=75)
    cot_output['spec_short_per_mean'] = pd.rolling_mean(cot_output['spec_short_per'],window=150,min_periods=75)




    cot_output['comm_net_change_1'] = cot_output['comm_net']-cot_output['comm_net'].shift(1)
    cot_output['comm_net_change_2'] = cot_output['comm_net']-cot_output['comm_net'].shift(2)
    cot_output['comm_net_change_4'] = cot_output['comm_net']-cot_output['comm_net'].shift(4)

    cot_output['spec_net_change_1'] = cot_output['spec_net']-cot_output['spec_net'].shift(1)
    cot_output['spec_net_change_2'] = cot_output['spec_net']-cot_output['spec_net'].shift(2)
    cot_output['spec_net_change_4'] = cot_output['spec_net']-cot_output['spec_net'].shift(4)

    cot_output['comm_long_change_1'] = cot_output['comm_long']-cot_output['comm_long'].shift(1)
    cot_output['comm_short_change_1'] = cot_output['comm_short']-cot_output['comm_short'].shift(1)

    cot_output['comm_net_change_1_std'] = pd.rolling_std(cot_output['comm_net_change_1'], window=150, min_periods=75)
    cot_output['comm_net_change_2_std'] = pd.rolling_std(cot_output['comm_net_change_2'], window=150, min_periods=75)
    cot_output['comm_net_change_4_std'] = pd.rolling_std(cot_output['comm_net_change_4'], window=150, min_periods=75)

    cot_output['spec_net_change_1_std'] = pd.rolling_std(cot_output['spec_net_change_1'], window=150, min_periods=75)
    cot_output['spec_net_change_2_std'] = pd.rolling_std(cot_output['spec_net_change_2'], window=150, min_periods=75)
    cot_output['spec_net_change_4_std'] = pd.rolling_std(cot_output['spec_net_change_4'], window=150, min_periods=75)

    cot_output['comm_long_change_1_std'] = pd.rolling_std(cot_output['comm_long_change_1'], window=150, min_periods=75)
    cot_output['comm_short_change_1_std'] = pd.rolling_std(cot_output['comm_short_change_1'], window=150, min_periods=75)

    cot_output['comm_net_change_1_norm'] = cot_output['comm_net_change_1']/cot_output['comm_net_change_1_std']
    cot_output['comm_net_change_2_norm'] = cot_output['comm_net_change_2']/cot_output['comm_net_change_2_std']
    cot_output['comm_net_change_4_norm'] = cot_output['comm_net_change_4']/cot_output['comm_net_change_4_std']

    cot_output['spec_net_change_1_norm'] = cot_output['spec_net_change_1']/cot_output['spec_net_change_1_std']
    cot_output['spec_net_change_2_norm'] = cot_output['spec_net_change_2']/cot_output['spec_net_change_2_std']
    cot_output['spec_net_change_4_norm'] = cot_output['spec_net_change_4']/cot_output['spec_net_change_4_std']

    cot_output['comm_long_change_1_norm'] = cot_output['comm_long_change_1']/cot_output['comm_long_change_1_std']
    cot_output['comm_short_change_1_norm'] = cot_output['comm_short_change_1']/cot_output['comm_short_change_1_std']

    cot_output['comm_net_mean'] = pd.rolling_mean(cot_output['comm_net'],window=150,min_periods=75)
    cot_output['spec_net_mean'] = pd.rolling_mean(cot_output['spec_net'],window=150,min_periods=75)

    cot_output['comm_net_std'] = pd.rolling_std(cot_output['comm_net'],window=150,min_periods=75)
    cot_output['spec_net_std'] = pd.rolling_std(cot_output['spec_net'],window=150,min_periods=75)

    cot_output['comm_z'] = (cot_output['comm_net']-cot_output['comm_net_mean'])/cot_output['comm_net_std']
    cot_output['spec_z'] = (cot_output['spec_net']-cot_output['spec_net_mean'])/cot_output['spec_net_std']

    cot_output['settle_date'] = cot_output.index
    cot_output['settle_date'] = [x+dt.timedelta(days=3) for x in cot_output['settle_date']]

    combined_data = pd.merge(merged_data,cot_output,how='left',on='settle_date')

    combined_data['comm_net_change_1_norm'] = combined_data['comm_net_change_1_norm'].fillna(method='pad')
    combined_data['comm_net_change_2_norm'] = combined_data['comm_net_change_2_norm'].fillna(method='pad')
    combined_data['comm_net_change_4_norm'] = combined_data['comm_net_change_4_norm'].fillna(method='pad')

    combined_data['spec_net_change_1_norm'] = combined_data['spec_net_change_1_norm'].fillna(method='pad')
    combined_data['spec_net_change_2_norm'] = combined_data['spec_net_change_2_norm'].fillna(method='pad')
    combined_data['spec_net_change_4_norm'] = combined_data['spec_net_change_4_norm'].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')

    position = 0
    position_list = []
    entry_index_list = []
    exit_index_list = []
    entry_price_list = []
    exit_price_list = []

    for i in range(len(combined_data.index)):

        spec_change1_signal = combined_data['spec_net_change_1_norm'].iloc[i]
        spec_change4_signal = combined_data['spec_net_change_4_norm'].iloc[i]
        spec_z_signal = combined_data['spec_z'].iloc[i]
        price_i = combined_data['const_mat'].iloc[i]

        min_10 = combined_data['const_mat_min10'].iloc[i]
        max_10 = combined_data['const_mat_max10'].iloc[i]
        min_20 = combined_data['const_mat_min20'].iloc[i]
        max_20 = combined_data['const_mat_max20'].iloc[i]

        const_mat_change_10_norm = combined_data['const_mat_change_10_norm'].iloc[i]
        const_mat_change_20_norm = combined_data['const_mat_change_20_norm'].iloc[i]

        if i == len(combined_data.index)-1:
            if position != 0:
                exit_index_list.append(i)
                exit_price_list.append(price_i)
            break

        price_i1 = combined_data['const_mat'].iloc[i+1]

        if (position == 0) and (spec_z_signal>0.5) and (price_i==min_10):
            position = 1
            position_list.append(position)
            entry_index_list.append(i)
            entry_price_list.append(price_i1)
        elif (position == 0) and (spec_z_signal<-0.5) and (price_i==max_10):
            position = -1
            position_list.append(position)
            entry_index_list.append(i)
            entry_price_list.append(price_i1)
        elif (position == 1) and ((price_i==min_20)):
            position = 0
            exit_index_list.append(i)
            exit_price_list.append(price_i1)
        elif (position == -1) and ((price_i==max_20)):
            position = 0
            exit_index_list.append(i)
            exit_price_list.append(price_i1)

    return {'combined_data': combined_data}
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_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_past_realized_vol_until_expiration(**kwargs):

    ticker = kwargs['ticker']
    date_to = kwargs['date_to']

    contract_specs_output = cmi.get_contract_specs(ticker)
    ticker_class = contract_specs_output['ticker_class']
    ticker_head = contract_specs_output['ticker_head']

    if ticker_class in ['Index', 'FX', 'Metal', 'Treasury'] or ticker_head == 'CL':
        contracts_back = 100
        aggregation_method = 1
    elif ticker_class in ['Ag', 'Livestock'] or ticker_head == 'NG':
        contracts_back = 20
        aggregation_method = 12

    con = msu.get_my_sql_connection(**kwargs)

    datetime_to = cu.convert_doubledate_2datetime(date_to)

    exp_output = exp.get_days2_expiration(ticker=ticker, con=con,
                                          instrument='options',
                                          date_to=date_to)

    cal_dte = exp_output['cal_dte']
    expiration_datetime = exp_output['expiration_datetime']

    min_num_obs_4realized_vol_2expiration = np.floor(cal_dte*0.6*250/365)

    expiration_date = int(expiration_datetime.strftime('%Y%m%d'))

    if aggregation_method == 1:
        additional_contracts_2request = round(cal_dte/30) + 5
    else:
        additional_contracts_2request = 10

    report_date_list = sutil.get_bus_dates_from_agg_method_and_contracts_back(ref_date=date_to,
                                                           aggregation_method=aggregation_method,
                                                           contracts_back=contracts_back + additional_contracts_2request,
                                                           shift_bus_days=2)

    exp_date_list = sutil.get_bus_dates_from_agg_method_and_contracts_back(ref_date=expiration_date,
                                                           aggregation_method=aggregation_method,
                                                           contracts_back=contracts_back+ additional_contracts_2request)

    observed_real_vol_date_from = sutil.get_bus_dates_from_agg_method_and_contracts_back(ref_date=date_to,
                                                           aggregation_method=aggregation_method,
                                                           contracts_back=contracts_back + additional_contracts_2request,
                                                           shift_bus_days=-30)

    observed_real_vol_date_to = sutil.get_bus_dates_from_agg_method_and_contracts_back(ref_date=date_to,
                                                           aggregation_method=aggregation_method,
                                                           contracts_back=contracts_back + additional_contracts_2request)

    if 'con' not in kwargs.keys():
        con.close()

    data_frame_out = pd.DataFrame.from_items([('date_from', report_date_list), ('date_to', exp_date_list),
                                              ('observed_real_vol_date_from', observed_real_vol_date_from),
                                              ('observed_real_vol_date_to', observed_real_vol_date_to)])

    selection_indx = data_frame_out['date_to'] < datetime_to
    data_frame_out = data_frame_out[selection_indx]
    data_frame_out = data_frame_out[:contracts_back]
    data_frame_out.reset_index(drop=True, inplace=True)

    data_frame_out['real_vol_till_expiration'] = np.NaN
    data_frame_out['real_vol20'] = np.NaN
    data_frame_out['ticker'] = None

    get_futures_price_input = {}

    if 'futures_data_dictionary' in kwargs.keys():
            get_futures_price_input['futures_data_dictionary'] = kwargs['futures_data_dictionary']

    if ticker_class in ['Index', 'FX', 'Metal', 'Treasury']:

        rolling_price = sutil.get_rolling_futures_price(ticker_head=ticker_head, **get_futures_price_input)
        for i in data_frame_out.index:
            selected_price = rolling_price[(rolling_price['settle_date'] >= data_frame_out['date_from'].loc[i])&
            (rolling_price['settle_date'] <= data_frame_out['date_to'].loc[i])]

            if len(selected_price.index) >= min_num_obs_4realized_vol_2expiration:

                data_frame_out['real_vol_till_expiration'].loc[i] = 100*np.sqrt(252*np.mean(np.square(selected_price['log_return'])))

            selected_price = rolling_price[(rolling_price['settle_date'] >= data_frame_out['observed_real_vol_date_from'].loc[i])&
            (rolling_price['settle_date'] <= data_frame_out['observed_real_vol_date_to'].loc[i])]

            data_frame_out['real_vol20'].loc[i] = 100*np.sqrt(252*np.mean(np.square(selected_price['log_return'][-20:])))

    elif ticker_class in ['Ag', 'Livestock', 'Energy']:

        ticker_list = sutil.get_tickers_from_agg_method_and_contracts_back(ticker=ticker,
                                                             aggregation_method=aggregation_method,
                                                             contracts_back=contracts_back+additional_contracts_2request)

        ticker_list = [ticker_list[x] for x in range(len(ticker_list)) if selection_indx[x]]
        ticker_list = ticker_list[:contracts_back]
        data_frame_out['ticker'] = ticker_list

        for i in data_frame_out.index:
            ticker_data = gfp.get_futures_price_preloaded(ticker=data_frame_out['ticker'].loc[i], **get_futures_price_input)
            ticker_data.sort('settle_date', ascending=True, inplace=True)
            shifted = ticker_data.shift(1)

            ticker_data['log_return'] = np.log(ticker_data['close_price']/shifted['close_price'])

            selected_price = ticker_data[(ticker_data['settle_date'] >= data_frame_out['date_from'].loc[i])&
            (ticker_data['settle_date'] <= data_frame_out['date_to'].loc[i])]

            if len(selected_price.index) >= min_num_obs_4realized_vol_2expiration:

                data_frame_out['real_vol_till_expiration'].loc[i] = 100*np.sqrt(252*np.mean(np.square(selected_price['log_return'])))

            selected_price = ticker_data[(ticker_data['settle_date'] >= data_frame_out['observed_real_vol_date_from'].loc[i])&
            (ticker_data['settle_date'] <= data_frame_out['observed_real_vol_date_to'].loc[i])]

            data_frame_out['real_vol20'].loc[i] = 100*np.sqrt(252*np.mean(np.square(selected_price['log_return'][-20:])))

    return data_frame_out
def get_ticker_list_4tickerhead(**kwargs):

    if 'volume_filter' in kwargs.keys():
        volume_filter = kwargs['volume_filter']
    else:
        volume_filter = 1000

    ticker_head = kwargs['ticker_head']

    futures_frame = gfp.get_futures_price_preloaded(**kwargs)

    futures_frame = futures_frame[futures_frame['volume']>=volume_filter]

    outright_frame = pd.DataFrame()
    spread_frame = pd.DataFrame()
    wide_spread_frame1 = pd.DataFrame()
    wide_spread_frame2 = pd.DataFrame()

    outright_frame['ticker1'] = futures_frame['ticker']
    outright_frame['ticker2'] = None

    spread_frame['ticker1'] = futures_frame['ticker']
    spread_frame['ticker2'] = futures_frame['ticker'].shift(-1)

    if ticker_head in ['CL', 'HO', 'RB', 'NG', 'ED']:

        if ticker_head == 'ED':
            diff = 3
        else:
            diff = 1

        spread_frame['ticker_month1'] = futures_frame['ticker_month']
        spread_frame['ticker_month2'] = futures_frame['ticker_month'].shift(-1)

        spread_frame['ticker_year1'] = futures_frame['ticker_year']
        spread_frame['ticker_year2'] = futures_frame['ticker_year'].shift(-1)

        spread_frame['diff'] = 12*(spread_frame['ticker_year2']-spread_frame['ticker_year1'])+\
                           (spread_frame['ticker_month2']-spread_frame['ticker_month1'])

        spread_frame = spread_frame[spread_frame['diff'] == diff]

        spread_frame.drop(['ticker_month1','ticker_month2','ticker_year1','ticker_year2','diff'],axis=1,inplace=True)

    else:

        spread_frame.drop(spread_frame.index[-1],inplace=True)

    if ticker_head == 'CL':

        wide_futures_frame1 = futures_frame[futures_frame['ticker_month'] % 3 == 0]
        wide_spread_frame1['ticker1'] = wide_futures_frame1['ticker']
        wide_spread_frame1['ticker2'] = wide_futures_frame1['ticker'].shift(-1)
        wide_spread_frame1.drop(wide_spread_frame1.index[-1],inplace=True)

        wide_futures_frame2 = futures_frame[futures_frame['ticker_month'] % 6 == 0]
        wide_spread_frame2['ticker1'] = wide_futures_frame2['ticker']
        wide_spread_frame2['ticker2'] = wide_futures_frame2['ticker'].shift(-1)
        wide_spread_frame2.drop(wide_spread_frame2.index[-1],inplace=True)

    output_frame = pd.concat([outright_frame,spread_frame,wide_spread_frame1,wide_spread_frame2])
    output_frame['tickerHead'] = ticker_head

    return output_frame.drop_duplicates(['ticker1','ticker2'],inplace=False)