def generate_futures_butterfly_formatted_output(**kwargs):

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

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

    butterfly_output = fb.generate_futures_butterfly_sheet_4date(
        date_to=report_date)
    butterflies = butterfly_output['butterflies']

    filter_out = ff.get_futures_butterfly_filters(
        data_frame_input=butterflies, filter_list=['long7', 'short7'])
    good_butterflies = filter_out['selected_frame']

    good_butterflies = good_butterflies[
        (good_butterflies['second_spread_weight_1'] <= 2.5)
        & (good_butterflies['second_spread_weight_1'] >= 0.4)]

    butterflies_w_selected_columns = butterflies[[
        'ticker1', 'ticker2', 'ticker3', 'tickerHead', 'trDte1', 'trDte2',
        'trDte3', 'Q', 'QF', 'z1', 'z2', 'z3', 'z4', 'theo_pnl', 'r1', 'r2',
        'bf_price', 'RC', 'seasonality', 'second_spread_weight_1', 'upside',
        'downside', 'recent_vol_ratio', 'recent_5day_pnl', 'bf_sell_limit',
        'bf_buy_limit'
    ]]

    good_butterflies_w_selected_columns = good_butterflies[[
        'ticker1', 'ticker2', 'ticker3', 'tickerHead', 'trDte1', 'trDte2',
        'trDte3', 'Q', 'QF', 'z1', 'z2', 'z3', 'z4', 'theo_pnl', 'r1', 'r2',
        'bf_price', 'RC', 'seasonality', 'second_spread_weight_1', 'upside',
        'downside', 'recent_vol_ratio', 'recent_5day_pnl', 'bf_sell_limit',
        'bf_buy_limit'
    ]]

    writer = pd.ExcelWriter(
        output_dir + '/' + futil.xls_file_names['futures_butterfly'] + '.xlsx',
        engine='xlsxwriter')

    butterflies_w_selected_columns.to_excel(writer, sheet_name='all')
    good_butterflies_w_selected_columns.to_excel(writer, sheet_name='good')

    worksheet_good = writer.sheets['good']
    worksheet_all = writer.sheets['all']

    worksheet_good.freeze_panes(1, 0)
    worksheet_all.freeze_panes(1, 0)

    worksheet_good.autofilter(0, 0,
                              len(good_butterflies_w_selected_columns.index),
                              len(good_butterflies_w_selected_columns.columns))

    worksheet_all.autofilter(0, 0, len(butterflies_w_selected_columns.index),
                             len(butterflies_w_selected_columns.columns))

    writer.save()
def get_butterfly_panel_plot(**kwargs):

    report_date = kwargs['report_date']
    id = kwargs['id']

    bf_output = fb.generate_futures_butterfly_sheet_4date(date_to=report_date)
    butterflies = bf_output['butterflies']

    contract_list = [butterflies['ticker1'][id], butterflies['ticker2'][id], butterflies['ticker3'][id]]
    tr_dte_list = [butterflies['trDte1'][id], butterflies['trDte2'][id], butterflies['trDte3'][id]]

    if 'aggregation_method' in kwargs.keys():
        aggregation_method = kwargs['aggregation_method']
    else:
        aggregation_method = butterflies['agg'][id]

    if 'contracts_back' in kwargs.keys():
        contracts_back = kwargs['contracts_back']
    else:
        contracts_back = butterflies['cBack'][id]

    post_report_date = exp.doubledate_shift_bus_days(double_date=report_date,shift_in_days=-20)

    bf_signals_output = fs.get_futures_butterfly_signals(ticker_list=contract_list,
                                          tr_dte_list=tr_dte_list,
                                          aggregation_method=aggregation_method,
                                          contracts_back=contracts_back,
                                          date_to=post_report_date,
                                          contract_multiplier=butterflies['multiplier'][id],
                                          use_last_as_current=True)

    aligned_data = bf_signals_output['aligned_output']['aligned_data']

    new_index = list(range(len(aligned_data.index)))
    contract_change_indx = (aligned_data['c1']['ticker_year']-aligned_data['c1']['ticker_year'].shift(1)!=0).values
    front_contract_year = aligned_data['c1']['ticker_year'] % 10
    contract_change_indx[0] = False

    report_datetime = cu.convert_doubledate_2datetime(report_date)

    x_index = [x for x in new_index if aligned_data['settle_date'][x] == report_datetime][0]

    x_tick_locations = [x for x in new_index if contract_change_indx[x]]
    x_tick_locations.append(x_index)

    x_tick_values = [cmi.letter_month_string[aligned_data['c1']['ticker_month'].values[x]-1]+
                     str(front_contract_year.values[x]) for x in new_index if contract_change_indx[x]]
    x_tick_values.append('X')

    plt.figure(figsize=(16, 7))
    plt.plot(aligned_data['residuals'])
    plt.xticks(x_tick_locations,x_tick_values)
    plt.grid()
    plt.title('Contracts: ' + str(contract_list) + ', weight2: ' + str(bf_signals_output['second_spread_weight_1'].round(2)))
    plt.show()

    return bf_signals_output
def get_butterfly_panel_plot(**kwargs):

    report_date = kwargs['report_date']
    id = kwargs['id']

    bf_output = fb.generate_futures_butterfly_sheet_4date(date_to=report_date)
    butterflies = bf_output['butterflies']

    contract_list = [butterflies['ticker1'][id], butterflies['ticker2'][id], butterflies['ticker3'][id]]
    tr_dte_list = [butterflies['trDte1'][id], butterflies['trDte2'][id], butterflies['trDte3'][id]]

    if 'aggregation_method' in kwargs.keys():
        aggregation_method = kwargs['aggregation_method']
    else:
        aggregation_method = butterflies['agg'][id]

    if 'contracts_back' in kwargs.keys():
        contracts_back = kwargs['contracts_back']
    else:
        contracts_back = butterflies['cBack'][id]

    post_report_date = exp.doubledate_shift_bus_days(double_date=report_date,shift_in_days=-20)

    bf_signals_output = fs.get_futures_butterfly_signals(ticker_list=contract_list,
                                          tr_dte_list=tr_dte_list,
                                          aggregation_method=aggregation_method,
                                          contracts_back=contracts_back,
                                          date_to=post_report_date,
                                          contract_multiplier=butterflies['multiplier'][id],
                                          use_last_as_current=True)

    aligned_data = bf_signals_output['aligned_output']['aligned_data']

    new_index = list(range(len(aligned_data.index)))
    contract_change_indx = (aligned_data['c1']['ticker_year']-aligned_data['c1']['ticker_year'].shift(1)!=0).values
    front_contract_year = aligned_data['c1']['ticker_year'] % 10
    contract_change_indx[0] = False

    report_datetime = cu.convert_doubledate_2datetime(report_date)

    x_index = [x for x in new_index if aligned_data['settle_date'][x] == report_datetime][0]

    x_tick_locations = [x for x in new_index if contract_change_indx[x]]
    x_tick_locations.append(x_index)

    x_tick_values = [cmi.letter_month_string[aligned_data['c1']['ticker_month'].values[x]-1]+
                     str(front_contract_year.values[x]) for x in new_index if contract_change_indx[x]]
    x_tick_values.append('X')

    plt.figure(figsize=(16, 7))
    plt.plot(aligned_data['residuals'])
    plt.xticks(x_tick_locations,x_tick_values)
    plt.grid()
    plt.title('Contracts: ' + str(contract_list) + ', weight2: ' + str(bf_signals_output['second_spread_weight_1'].round(2)))
    plt.show()

    return bf_signals_output
def get_butterfly_scatter_plot(**kwargs):

    report_date = kwargs['report_date']
    id = kwargs['id']

    bf_output = fb.generate_futures_butterfly_sheet_4date(date_to=report_date)
    butterflies = bf_output['butterflies']

    contract_list = [butterflies['ticker1'][id],butterflies['ticker2'][id],butterflies['ticker3'][id]]
    tr_dte_list = [butterflies['trDte1'][id],butterflies['trDte2'][id],butterflies['trDte3'][id]]

    if 'aggregation_method' in kwargs.keys():
        aggregation_method = kwargs['aggregation_method']
    else:
        aggregation_method = butterflies['agg'][id]

    if 'contracts_back' in kwargs.keys():
        contracts_back = kwargs['contracts_back']
    else:
        contracts_back = butterflies['cBack'][id]

    bf_signals_output = fs.get_futures_butterfly_signals(ticker_list=contract_list,
                                          tr_dte_list=tr_dte_list,
                                          aggregation_method=aggregation_method,
                                          contracts_back=contracts_back,
                                          date_to=report_date,
                                          contract_multiplier=butterflies['multiplier'][id])

    last5_years_indx = bf_signals_output['last5_years_indx']

    yield1 = bf_signals_output['yield1']
    yield2 = bf_signals_output['yield2']

    yield1_current = bf_signals_output['yield1_current']
    yield2_current = bf_signals_output['yield2_current']

    yield1_last5_years = yield1[last5_years_indx]
    yield2_last5_years = yield2[last5_years_indx]

    plt.figure(figsize=(16,7))
    plt.scatter(yield2, yield1, color='b')
    plt.scatter(yield2_last5_years,yield1_last5_years, color='k')
    plt.scatter(yield2_current, yield1_current, color='r')
    plt.legend(['old', 'recent', 'last'], frameon=False)
    plt.grid()
    plt.show()

    return bf_signals_output
def get_butterfly_scatter_plot(**kwargs):

    report_date = kwargs['report_date']
    id = kwargs['id']

    bf_output = fb.generate_futures_butterfly_sheet_4date(date_to=report_date)
    butterflies = bf_output['butterflies']

    contract_list = [butterflies['ticker1'][id],butterflies['ticker2'][id],butterflies['ticker3'][id]]
    tr_dte_list = [butterflies['trDte1'][id],butterflies['trDte2'][id],butterflies['trDte3'][id]]

    if 'aggregation_method' in kwargs.keys():
        aggregation_method = kwargs['aggregation_method']
    else:
        aggregation_method = butterflies['agg'][id]

    if 'contracts_back' in kwargs.keys():
        contracts_back = kwargs['contracts_back']
    else:
        contracts_back = butterflies['cBack'][id]

    bf_signals_output = fs.get_futures_butterfly_signals(ticker_list=contract_list,
                                          tr_dte_list=tr_dte_list,
                                          aggregation_method=aggregation_method,
                                          contracts_back=contracts_back,
                                          date_to=report_date,
                                          contract_multiplier=butterflies['multiplier'][id])

    last5_years_indx = bf_signals_output['last5_years_indx']

    yield1 = bf_signals_output['yield1']
    yield2 = bf_signals_output['yield2']

    yield1_current = bf_signals_output['yield1_current']
    yield2_current = bf_signals_output['yield2_current']

    yield1_last5_years = yield1[last5_years_indx]
    yield2_last5_years = yield2[last5_years_indx]

    plt.figure(figsize=(16,7))
    plt.scatter(yield2, yield1, color='b')
    plt.scatter(yield2_last5_years,yield1_last5_years, color='k')
    plt.scatter(yield2_current, yield1_current, color='r')
    plt.legend(['old', 'recent', 'last'], frameon=False)
    plt.grid()
    plt.show()

    return bf_signals_output
def 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
Beispiel #7
0
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
Beispiel #8
0
def save_trade_paths(**kwargs):

    risk_per_trade = 10000
    report_date = kwargs['report_date']

    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_ws.pkl') and use_existing_filesQ:
        return pd.read_pickle(output_dir + '/backtest_results_ws.pkl')

    butt_out = opfb.generate_futures_butterfly_sheet_4date(date_to=report_date)
    strategy_sheet = butt_out['butterflies']

    strategy_sheet['long_pnl_ws1'] = np.nan
    strategy_sheet['long_pnl_ws2'] = np.nan
    strategy_sheet['long_pnl_ws3'] = np.nan

    strategy_sheet['short_pnl_ws1'] = np.nan
    strategy_sheet['short_pnl_ws2'] = np.nan
    strategy_sheet['short_pnl_ws3'] = np.nan

    strategy_sheet['long_stop_days1'] = np.nan
    strategy_sheet['long_stop_days2'] = np.nan
    strategy_sheet['long_stop_days3'] = np.nan

    strategy_sheet['short_stop_days1'] = np.nan
    strategy_sheet['short_stop_days2'] = np.nan
    strategy_sheet['short_stop_days3'] = np.nan

    strategy_sheet['long_pnl20'] = np.nan
    strategy_sheet['long_pnl40'] = np.nan
    strategy_sheet['long_pnl60'] = np.nan

    strategy_sheet['short_pnl20'] = np.nan
    strategy_sheet['short_pnl40'] = np.nan
    strategy_sheet['short_pnl60'] = np.nan
    strategy_sheet['report_date'] = report_date

    for i in range(len(strategy_sheet.index)):
        selected_trade = strategy_sheet.iloc[i]
        quantity_long = round(risk_per_trade / abs(selected_trade['downside']))
        quantity_short = -round(risk_per_trade / abs(selected_trade['upside']))
        data_list = []
        for j in range(3):
            ticker_frame = gfp.get_futures_price_preloaded(
                ticker=selected_trade['ticker' + str(j + 1)],
                settle_date_from=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')
        merged_data = merged_data[merged_data['tr_dte'].iloc[:, 0] >= 15]
        merged_data = merged_data[:71]

        spread_price = (merged_data['close_price'].iloc[:, 0] -
                        merged_data['close_price'].iloc[:, 1]
                        ) - selected_trade['second_spread_weight_1'] * (
                            merged_data['close_price'].iloc[:, 1] -
                            merged_data['close_price'].iloc[:, 2])

        long_entry_slippage = quantity_long * selected_trade['multiplier'] * (
            spread_price[1] - spread_price[0])
        short_entry_slippage = quantity_long * selected_trade['multiplier'] * (
            spread_price[1] - spread_price[0])

        if (abs(long_entry_slippage) > risk_per_trade / 2) or (
                abs(short_entry_slippage) > risk_per_trade / 2):
            continue

        long_path = quantity_long * selected_trade['multiplier'] * (
            spread_price[2:] - spread_price[1])
        short_path = quantity_short * selected_trade['multiplier'] * (
            spread_price[2:] - spread_price[1])

        if len(spread_price.index) < 10:
            continue

        long_path.reset_index(drop=True, inplace=True)
        short_path.reset_index(drop=True, inplace=True)

        long_stop1 = long_path[(long_path < -risk_per_trade) |
                               (long_path > (risk_per_trade / 3))]
        long_stop2 = long_path[(long_path < -2 * risk_per_trade) |
                               (long_path > (risk_per_trade / 3))]
        long_stop3 = long_path[(long_path < -3 * risk_per_trade) |
                               (long_path > (risk_per_trade / 3))]

        short_stop1 = short_path[(short_path < -risk_per_trade) |
                                 (short_path > (risk_per_trade / 3))]
        short_stop2 = short_path[(short_path < -2 * risk_per_trade) |
                                 (short_path > (risk_per_trade / 3))]
        short_stop3 = short_path[(short_path < -3 * risk_per_trade) |
                                 (short_path > (risk_per_trade / 3))]

        long_output1 = get_spike_robust_stop_results(long_stop1)
        long_output2 = get_spike_robust_stop_results(long_stop2)
        long_output3 = get_spike_robust_stop_results(long_stop3)
        short_output1 = get_spike_robust_stop_results(short_stop1)
        short_output2 = get_spike_robust_stop_results(short_stop2)
        short_output3 = get_spike_robust_stop_results(short_stop3)

        strategy_sheet['long_stop_days1'].iloc[i] = long_output1[
            'holding_period']
        strategy_sheet['long_pnl_ws1'].iloc[i] = long_output1['pnl']

        strategy_sheet['long_stop_days2'].iloc[i] = long_output2[
            'holding_period']
        strategy_sheet['long_pnl_ws2'].iloc[i] = long_output2['pnl']

        strategy_sheet['long_stop_days3'].iloc[i] = long_output3[
            'holding_period']
        strategy_sheet['long_pnl_ws3'].iloc[i] = long_output3['pnl']

        strategy_sheet['short_stop_days1'].iloc[i] = short_output1[
            'holding_period']
        strategy_sheet['short_pnl_ws1'].iloc[i] = short_output1['pnl']

        strategy_sheet['short_stop_days2'].iloc[i] = short_output2[
            'holding_period']
        strategy_sheet['short_pnl_ws2'].iloc[i] = short_output2['pnl']

        strategy_sheet['short_stop_days3'].iloc[i] = short_output3[
            'holding_period']
        strategy_sheet['short_pnl_ws3'].iloc[i] = short_output3['pnl']

        if len(spread_price.index) > 21:
            strategy_sheet['long_pnl20'].iloc[i] = long_path[19]
            strategy_sheet['short_pnl20'].iloc[i] = short_path[19]

        if len(spread_price.index) > 41:
            strategy_sheet['long_pnl40'].iloc[i] = long_path[39]
            strategy_sheet['short_pnl40'].iloc[i] = short_path[39]

        if len(spread_price.index) > 61:
            strategy_sheet['long_pnl60'].iloc[i] = long_path[59]
            strategy_sheet['short_pnl60'].iloc[i] = short_path[59]

    strategy_sheet.to_pickle(output_dir + '/backtest_results_ws.pkl')

    return strategy_sheet
import opportunity_constructs.futures_butterfly as fb
import opportunity_constructs.overnight_calendar_spreads as ocs
import contract_utilities.expiration as exp
import ta.prepare_daily as prep
import ta.underlying_proxy as up
import fundamental_data.cot_data as cot
import datetime as dt
import ta.email_reports as er

con = msu.get_my_sql_connection()

fpl.update_futures_price_database(con=con)
pp.generate_and_update_futures_data_files(ticker_head_list='butterfly')

report_date = exp.doubledate_shift_bus_days()
fb.generate_futures_butterfly_sheet_4date(date_to=report_date, con=con)

try:
    ocs.generate_overnight_spreads_sheet_4date(date_to=report_date, con=con)
    fsf.generate_ocs_formatted_output(report_date=report_date)
except Exception:
    pass

fsf.generate_futures_butterfly_formatted_output()

prep.prepare_strategy_daily(strategy_class='futures_butterfly')

try:
    fsf.generate_spread_carry_formatted_output(report_date=report_date)
except Exception:
    pass
import formats.risk_pnl_formats as rpf
import my_sql_routines.futures_price_loader as fpl
import my_sql_routines.my_sql_utilities as msu
import get_price.presave_price as pp
import opportunity_constructs.futures_butterfly as fb
import contract_utilities.expiration as exp
import ta.prepare_daily as prep
import ta.email_reports as er

con = msu.get_my_sql_connection()

fpl.update_futures_price_database(con=con)
pp.generate_and_update_futures_data_files(ticker_head_list='butterfly')

report_date = exp.doubledate_shift_bus_days()
fb.generate_futures_butterfly_sheet_4date(date_to=report_date, con=con)

fsf.generate_futures_butterfly_formatted_output()

prep.prepare_strategy_daily(strategy_class='futures_butterfly')

try:
    fsf.generate_curve_pca_formatted_output()
    prep.prepare_strategy_daily(strategy_class='curve_pca')
except Exception:
    pass

try:
    rpf.generate_historic_risk_report(as_of_date=report_date, con=con)
    prep.move_from_dated_folder_2daily_folder(ext='ta', file_name='risk', folder_date=report_date)
except Exception:
def generate_futures_butterfly_formatted_output(**kwargs):

    if "report_date" in kwargs.keys():
        report_date = kwargs["report_date"]
    else:
        report_date = exp.doubledate_shift_bus_days()

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

    butterfly_output = fb.generate_futures_butterfly_sheet_4date(date_to=report_date)
    butterflies = butterfly_output["butterflies"]

    filter_out = ff.get_futures_butterfly_filters(data_frame_input=butterflies, filter_list=["long1", "short1"])
    good_butterflies = filter_out["selected_frame"]

    butterflies_w_selected_columns = butterflies[
        [
            "ticker1",
            "ticker2",
            "ticker3",
            "tickerHead",
            "trDte1",
            "trDte2",
            "trDte3",
            "Q",
            "QF",
            "z1",
            "z2",
            "z3",
            "z4",
            "theo_pnl",
            "r1",
            "r2",
            "bf_price",
            "RC",
            "seasonality",
            "second_spread_weight_1",
            "upside",
            "downside",
            "recent_vol_ratio",
            "recent_5day_pnl",
            "bf_sell_limit",
            "bf_buy_limit",
        ]
    ]

    good_butterflies_w_selected_columns = good_butterflies[
        [
            "ticker1",
            "ticker2",
            "ticker3",
            "tickerHead",
            "trDte1",
            "trDte2",
            "trDte3",
            "Q",
            "QF",
            "z1",
            "z2",
            "z3",
            "z4",
            "theo_pnl",
            "r1",
            "r2",
            "bf_price",
            "RC",
            "seasonality",
            "second_spread_weight_1",
            "upside",
            "downside",
            "recent_vol_ratio",
            "recent_5day_pnl",
            "bf_sell_limit",
            "bf_buy_limit",
        ]
    ]

    writer = pd.ExcelWriter(output_dir + "/" + futil.xls_file_names["futures_butterfly"] + ".xlsx", engine="xlsxwriter")

    butterflies_w_selected_columns.to_excel(writer, sheet_name="all")
    good_butterflies_w_selected_columns.to_excel(writer, sheet_name="good")

    worksheet_good = writer.sheets["good"]
    worksheet_all = writer.sheets["all"]

    worksheet_good.freeze_panes(1, 0)
    worksheet_all.freeze_panes(1, 0)

    worksheet_good.autofilter(
        0, 0, len(good_butterflies_w_selected_columns.index), len(good_butterflies_w_selected_columns.columns)
    )

    worksheet_all.autofilter(
        0, 0, len(butterflies_w_selected_columns.index), len(butterflies_w_selected_columns.columns)
    )