示例#1
0
def get_data4datelist(**kwargs):

    ticker_list = kwargs['ticker_list']
    date_list = kwargs['date_list']

    ticker_head_list = [cmi.get_contract_specs(x)['ticker_head'] for x in ticker_list]

    if 'spread_weights' in kwargs.keys():
        spread_weights = kwargs['spread_weights']
    else:
        weights_output = sutil.get_spread_weights_4contract_list(ticker_head_list=ticker_head_list)
        spread_weights = weights_output['spread_weights']

    num_contracts = len(ticker_list)

    ticker_class_list = [cmi.ticker_class[x] for x in ticker_head_list]

    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())
    intraday_data['hour_minute'] = [100*x.hour+x.minute for x in intraday_data['time_stamp']]

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

    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]

    return intraday_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_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}
示例#4
0
def backtest_ifs2_4date(**kwargs):

    report_date = kwargs['report_date']
    backtest_date = exp.doubledate_shift_bus_days(double_date=report_date,
                                                  shift_in_days=-1)

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

    sheet_output = ifs.generate_ifs_sheet_4date(date_to=report_date)
    intraday_spreads = sheet_output['intraday_spreads']

    intraday_spreads.sort(['spread_description', 'min_volume'],
                          ascending=[True, False],
                          inplace=True)
    intraday_spreads.drop_duplicates('spread_description', inplace=True)
    intraday_spreads.reset_index(drop=True, inplace=True)

    intraday_spreads['pnl'] = np.nan
    intraday_spreads['num_trades'] = np.nan
    intraday_spreads['mean_holding_period'] = np.nan

    signal_name = 'ma40_spread'

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

        ticker_list = [
            intraday_spreads.iloc[i]['contract1'],
            intraday_spreads.iloc[i]['contract2'],
            intraday_spreads.iloc[i]['contract3']
        ]
        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
        ]
        num_contracts = len(ticker_list)
        weights_output = sutil.get_spread_weights_4contract_list(
            ticker_head_list=ticker_head_list)
        contract_multiplier_list = [
            cmi.contract_multiplier[x] for x in ticker_head_list
        ]
        spread_weights = weights_output['spread_weights']

        intraday_data = iml.get_intraday_data_4spread(
            ticker_list=ticker_list,
            date_to=backtest_date,
            num_days_back=0,
            spread_weights=spread_weights)

        intraday_data = intraday_data[intraday_data['hour_minute'] > 930]
        pnl_list = []
        holding_period_list = []
        current_position = 0

        for j in range(len(intraday_data.index)):

            if (current_position
                    == 0) & (intraday_data[signal_name].iloc[j] <
                             intraday_spreads['maSpreadLowL'].iloc[i]):
                current_position = 1
                entry_point = j
                entry_price = intraday_data['spread'].iloc[j]
            elif (current_position
                  == 0) & (intraday_data[signal_name].iloc[j] >
                           intraday_spreads['maSpreadHighL'].iloc[i]):
                current_position = -1
                entry_point = j
                entry_price = intraday_data['spread'].iloc[j]
            elif (current_position == 1) & (
                (intraday_data[signal_name].iloc[j] > 0) |
                (j == len(intraday_data.index) - 1)):
                current_position = 0
                exit_price = intraday_data['spread'].iloc[j]
                pnl_list.append(contract_multiplier_list[0] *
                                (exit_price - entry_price) /
                                spread_weights[0] - 2 * num_contracts)
                holding_period_list.append(j - entry_point)
            elif (current_position == -1) & (
                (intraday_data[signal_name].iloc[j] < 0) |
                (j == len(intraday_data.index) - 1)):
                current_position = 0
                exit_price = intraday_data['spread'].iloc[j]
                pnl_list.append(contract_multiplier_list[0] *
                                (entry_price - exit_price) /
                                spread_weights[0] - 2 * num_contracts)
                holding_period_list.append(j - entry_point)

        intraday_spreads['pnl'].iloc[i] = sum(pnl_list)
        intraday_spreads['num_trades'].iloc[i] = len(pnl_list)
        intraday_spreads['mean_holding_period'].iloc[i] = np.mean(
            holding_period_list)

    return intraday_spreads
def backtest_ifs_4date(**kwargs):

    report_date = kwargs['report_date']

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

    #if os.path.isfile(output_dir + '/backtest_results.pkl'):
    #    intraday_spreads = pd.read_pickle(output_dir + '/backtest_results.pkl')
    #    return intraday_spreads

    start_hour = dt.time(9, 0, 0, 0)
    end_hour = dt.time(12, 55, 0, 0)

    sheet_output = ifs.generate_ifs_sheet_4date(date_to=report_date)
    intraday_spreads = sheet_output['intraday_spreads']

    intraday_spreads['pnl1'] = 0
    intraday_spreads['pnl2'] = 0
    intraday_spreads['pnl5'] = 0
    intraday_spreads['pnl6'] = 0
    intraday_spreads['pnl7'] = 0

    intraday_spreads['pnl1_wc'] = 0
    intraday_spreads['pnl2_wc'] = 0
    intraday_spreads['pnl5_wc'] = 0
    intraday_spreads['pnl6_wc'] = 0
    intraday_spreads['pnl7_wc'] = 0

    intraday_spreads['report_date'] = report_date

    intraday_spreads['spread_description'] = intraday_spreads.apply(lambda x: x['ticker_head1']+ '_' +x['ticker_head2'] if x['ticker_head3'] is None else x['ticker_head1']+ '_' +x['ticker_head2'] + '_' + x['ticker_head3'] ,axis=1)
    intraday_spreads['min_volume'] = intraday_spreads.apply(lambda x: min(x['volume1'],x['volume2']) if x['ticker_head3'] is None else min(x['volume1'],x['volume2'],x['volume3']) ,axis=1)

    intraday_spreads.sort(['spread_description','min_volume'],ascending=[True, False],inplace=True)
    intraday_spreads.drop_duplicates('spread_description',inplace=True)

    intraday_spreads = intraday_spreads[intraday_spreads['hs']>-1]

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

    date_list = [exp.doubledate_shift_bus_days(double_date=report_date, shift_in_days=x) for x in [-1,-2]]

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

        #print(i)

        ticker_list = [intraday_spreads.iloc[i]['contract1'],intraday_spreads.iloc[i]['contract2'],intraday_spreads.iloc[i]['contract3']]
        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]
        num_contracts = len(ticker_list)
        weights_output = sutil.get_spread_weights_4contract_list(ticker_head_list=ticker_head_list)
        contract_multiplier_list = [cmi.contract_multiplier[x] for x in ticker_head_list]
        spread_weights = weights_output['spread_weights']

        intraday_data = opUtil.get_aligned_futures_data_intraday(contract_list=ticker_list,
                                       date_list=date_list)


        intraday_data['spread'] = 0

        for j in range(num_contracts):

            intraday_data['c' + str(j+1), 'mid_p'] = (intraday_data['c' + str(j+1)]['best_bid_p'] +
                                         intraday_data['c' + str(j+1)]['best_ask_p'])/2

            intraday_data['spread'] = intraday_data['spread']+intraday_data['c' + str(j+1)]['mid_p']*spread_weights[j]

        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['time_stamp'] = [x.to_datetime() for x in intraday_data.index]
        intraday_data['settle_date'] = intraday_data['time_stamp'].apply(lambda x: x.date())
        unique_settle_dates = intraday_data['settle_date'].unique()
        intraday_data['spread1'] = np.nan

        if len(unique_settle_dates)<2:
            continue

        final_spread_price = np.mean(intraday_data['spread'][(intraday_data['settle_date'] == unique_settle_dates[1])])

        intraday_data = intraday_data[(intraday_data['settle_date'] == unique_settle_dates[0])]

        intraday_data['spread_diff'] = contract_multiplier_list[0]*(final_spread_price-intraday_data['spread'])/spread_weights[0]

        mean5 = intraday_spreads.iloc[i]['mean']
        std5 = intraday_spreads.iloc[i]['std']

        mean1 = intraday_spreads.iloc[i]['mean1']
        std1 = intraday_spreads.iloc[i]['std1']

        mean2 = intraday_spreads.iloc[i]['mean2']
        std2 = intraday_spreads.iloc[i]['std2']

        long_qty = -5000/intraday_spreads.iloc[i]['downside']
        short_qty = -5000/intraday_spreads.iloc[i]['upside']

        intraday_data['z5'] = (intraday_data['spread']-mean5)/std5
        intraday_data['z1'] = (intraday_data['spread']-mean1)/std1
        intraday_data['z2'] = (intraday_data['spread']-mean2)/std2
        intraday_data['z6'] = (intraday_data['spread']-mean1)/std5

        intraday_data11 = intraday_data[intraday_data['z1']>1]
        intraday_data1_1 = intraday_data[intraday_data['z1']<-1]

        if intraday_data1_1.empty:
            pnl1_1 = 0
            pnl1_1_wc = 0
        else:
            pnl1_1 = long_qty*intraday_data1_1['spread_diff'].mean()
            pnl1_1_wc = pnl1_1 - 2*2*long_qty*num_contracts

        if intraday_data11.empty:
            pnl11 = 0
            pnl11_wc = 0
        else:
            pnl11 = short_qty*intraday_data11['spread_diff'].mean()
            pnl11_wc = pnl11 + 2*2*short_qty*num_contracts

        intraday_data21 = intraday_data[intraday_data['z2']>1]
        intraday_data2_1 = intraday_data[intraday_data['z2']<-1]

        if intraday_data2_1.empty:
            pnl2_1 = 0
            pnl2_1_wc = 0
        else:
            pnl2_1 = long_qty*intraday_data2_1['spread_diff'].mean()
            pnl2_1_wc = pnl2_1 - 2*2*long_qty*num_contracts

        if intraday_data21.empty:
            pnl21 = 0
            pnl21_wc = 0
        else:
            pnl21 = short_qty*intraday_data21['spread_diff'].mean()
            pnl21_wc = pnl21 + 2*2*short_qty*num_contracts

        intraday_data51 = intraday_data[intraday_data['z5']>1]
        intraday_data5_1 = intraday_data[intraday_data['z5']<-1]

        if intraday_data5_1.empty:
            pnl5_1 = 0
            pnl5_1_wc = 0
        else:
            pnl5_1 = long_qty*intraday_data5_1['spread_diff'].mean()
            pnl5_1_wc = pnl5_1 - 2*2*long_qty*num_contracts

        if intraday_data51.empty:
            pnl51 = 0
            pnl51_wc = 0
        else:
            pnl51 = short_qty*intraday_data51['spread_diff'].mean()
            pnl51_wc = pnl51 + 2*2*short_qty*num_contracts

        intraday_data61 = intraday_data[intraday_data['z6']>0.25]
        intraday_data6_1 = intraday_data[intraday_data['z6']<-0.25]

        if intraday_data6_1.empty:
            pnl6_1 = 0
            pnl6_1_wc = 0
        else:
            pnl6_1 = long_qty*intraday_data6_1['spread_diff'].mean()
            pnl6_1_wc = pnl6_1 - 2*2*long_qty*num_contracts

        if intraday_data61.empty:
            pnl61 = 0
            pnl61_wc = 0
        else:
            pnl61 = short_qty*intraday_data61['spread_diff'].mean()
            pnl61_wc = pnl61 + 2*2*short_qty*num_contracts

        intraday_data71 = intraday_data[(intraday_data['z6']>0.1)&(intraday_data['z5']>0.5)]
        intraday_data7_1 = intraday_data[(intraday_data['z6']<-0.1)&(intraday_data['z5']<0.5)]

        if intraday_data7_1.empty:
            pnl7_1 = 0
            pnl7_1_wc = 0
        else:
            pnl7_1 = long_qty*intraday_data7_1['spread_diff'].mean()
            pnl7_1_wc = pnl7_1 - 2*2*long_qty*num_contracts

        if intraday_data71.empty:
            pnl71 = 0
            pnl71_wc = 0
        else:
            pnl71 = short_qty*intraday_data71['spread_diff'].mean()
            pnl71_wc = pnl71 + 2*2*short_qty*num_contracts

        intraday_spreads['pnl1'].iloc[i] = pnl1_1 + pnl11
        intraday_spreads['pnl2'].iloc[i] = pnl2_1 + pnl21
        intraday_spreads['pnl5'].iloc[i] = pnl5_1 + pnl51
        intraday_spreads['pnl6'].iloc[i] = pnl6_1 + pnl61
        intraday_spreads['pnl7'].iloc[i] = pnl7_1 + pnl71

        intraday_spreads['pnl1_wc'].iloc[i] = pnl1_1_wc + pnl11_wc
        intraday_spreads['pnl2_wc'].iloc[i] = pnl2_1_wc + pnl21_wc
        intraday_spreads['pnl5_wc'].iloc[i] = pnl5_1_wc + pnl51_wc
        intraday_spreads['pnl6_wc'].iloc[i] = pnl6_1_wc + pnl61_wc
        intraday_spreads['pnl7_wc'].iloc[i] = pnl7_1_wc + pnl71_wc

    intraday_spreads.to_pickle(output_dir + '/backtest_results.pkl')
    return intraday_spreads
示例#6
0
def calc_pnl4date(**kwargs):

    ticker_list = kwargs['ticker_list']
    pnl_date = kwargs['pnl_date']
    #print(pnl_date)

    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]

    contract_multiplier_list = [cmi.contract_multiplier[x] for x in ticker_head_list]

    date_list = [exp.doubledate_shift_bus_days(double_date=pnl_date,shift_in_days=x) for x in [2, 1]]
    date_list.append(pnl_date)

    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())
    intraday_data['time'] = intraday_data['time_stamp'].apply(lambda x: x.time())

    weights_output = sutil.get_spread_weights_4contract_list(ticker_head_list=ticker_head_list)
    spread_weights = weights_output['spread_weights']

    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)
    num_contracts = len(ticker_list)

    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()

    if len(unique_settle_dates)<3:
        return {'pnl_date': pnl_date, 'total_pnl': np.nan,'long_pnl':np.nan, 'short_pnl': np.nan }

    final_spread_price = np.mean(intraday_data['spread'][(intraday_data['settle_date'] == unique_settle_dates[2])&(intraday_data['time']>=trade_start_hour)])

    calibration_data = intraday_data[(intraday_data['settle_date'] == unique_settle_dates[0])]

    backtest_data = intraday_data[(intraday_data['settle_date'] == unique_settle_dates[1])]
    backtest_data = backtest_data[backtest_data['time']>=trade_start_hour]
    backtest_data['spread_diff'] = contract_multiplier_list[0]*(final_spread_price-backtest_data['spread'])/spread_weights[0]

    calibration_mean = calibration_data['spread'].mean()
    calibration_std = calibration_data['spread'].std()

    cheap_data = backtest_data[backtest_data['spread'] < calibration_mean-1*calibration_std]
    expensive_data = backtest_data[backtest_data['spread'] > calibration_mean+1*calibration_std]

    if cheap_data.empty:
        long_pnl = 0
    else:
        long_pnl = cheap_data['spread_diff'].mean()-2*2*num_contracts

    if expensive_data.empty:
        short_pnl = 0
    else:
        short_pnl = -expensive_data['spread_diff'].mean()-2*2*num_contracts

    return {'pnl_date': pnl_date, 'total_pnl': long_pnl+short_pnl,'long_pnl':long_pnl, 'short_pnl': short_pnl }