Пример #1
0
def part_test_fun(instrument):
    adj_close_df = FutData().load_act_adj_fut_data(instrument, 'Close', active_df, aadj_factor_df)
    adj_high_df = FutData().load_act_adj_fut_data(instrument, 'High', active_df, aadj_factor_df)
    adj_low_df = FutData().load_act_adj_fut_data(instrument, 'Low', active_df, aadj_factor_df)

    adj_return_df = adj_close_df/adj_close_df.shift(1) - 1

    for n in window_list:
        raw_factor = FutIndex.boll_fun(adj_close_df, n)
        for limit in limit_list:
            signal = Signal.fun_1(raw_factor, limit)
            pos = Position.fun_1(signal)
            pnl_df = (pos.shift(2) * adj_return_df).fillna(0)
            sp = bt.AZ_Sharpe_y(pnl_df)
            pot = bt.AZ_Pot(pos, pnl_df.sum())
            print(instrument, sp, pot, n, limit)
            if abs(sp) > 1.4:
                print('!!!!!!!!!!!!!!!!')
Пример #2
0
def part_test(
    con_id,
    begin_time,
    end_time,
    # p_window, p_limit,
    # v_window, v_limit,
    # voli_window, voli_limit,
    CCI_window,
    CCI_limit,
    # hold_time
):
    try:
        # print(con_id, begin_time, end_time)
        data_df = fut_data.load_intra_data(con_id,
                                           ['High', 'Low', 'Close', 'Volume'])
        # begin_time = pd.to_datetime('20190101')
        # # end_time = begin_time + timedelta(1)
        # end_time = pd.to_datetime('20190401')

        # p_window = 1
        # p_limit = 1
        # v_window = 20
        # v_limit = 2

        part_data_df = data_df.truncate(before=begin_time, after=end_time)

        part_data_df['weekday'] = pd.to_datetime(
            part_data_df['Date']).dt.weekday
        part_data_df['weekday_pos'] = (part_data_df['weekday'] !=
                                       2).astype(int)
        part_data_df['month'] = part_data_df['Date'].str.slice(5, 7)
        # part_data_df['month_pos'] = ((part_data_df['month'] != '2') &
        #                              (part_data_df['month'] != '5')).astype(int)

        v_window = 60
        part_data_df['Volume_zscore'] = bt.AZ_Col_zscore(
            part_data_df[['Volume']], v_window)
        part_data_df['Volume_signal'] = (part_data_df['Volume_zscore'] <
                                         2).astype(int).replace(0, -1)

        p_window = 3
        part_data_df['past_min_pct_change'] = (part_data_df['Close'] - part_data_df['Close'].shift(p_window)) \
                                              / part_data_df['Close'].shift(p_window)
        # part_data_df['past_min_pct_change'] = (part_data_df['Close'] - part_data_df['Close'].shift(p_window))
        part_data_df['past_min_pct_signal'] = part_data_df['past_min_pct_change'] \
            .apply(lambda x: 0 if abs(x) < 0.005 else (1 if x > 0.005 else -1))

        part_data_df['CCI_score'] = FutIndex.CCI_fun(part_data_df['High'],
                                                     part_data_df['Low'],
                                                     part_data_df['Close'],
                                                     CCI_window)

        part_data_df['CCI_signal'] = Signal.fun_1(part_data_df['CCI_score'],
                                                  CCI_limit)

        part_data_df['CCI_pos'] = Position.fun_1(part_data_df['CCI_signal'])

        part_data_df['boll_score'] = FutIndex.boll_fun(part_data_df['Close'],
                                                       CCI_window)
        part_data_df['boll_signal'] = Signal.fun_1(part_data_df['boll_score'],
                                                   CCI_limit)
        part_data_df['boll_pos'] = Position.fun_1(part_data_df['boll_signal'])

        part_data_df['trend_signal'] = bt.AZ_Rolling(part_data_df['Close'],
                                                     500).std()
        part_data_df['trend_pos'] = (part_data_df['trend_signal'] <
                                     45).astype(int).replace(0, -1)

        part_data_df['position'] = part_data_df['boll_pos']

        part_data_df['position_sft'] = part_data_df['position'].shift(
            2) * part_data_df['weekday_pos']
        part_data_df['price_return'] = part_data_df['Close'] - part_data_df[
            'Close'].shift(1)

        # part_data_df['price_return_sum'] = bt.AZ_Rolling(part_data_df['price_return'], hold_time).sum() \
        #     .shift(-hold_time + 1)
        part_data_df['pnl'] = part_data_df['position_sft'] * part_data_df[
            'price_return']
        part_data_df['asset'] = part_data_df['pnl'].cumsum()
        # part_data_df['pnl_test'] = part_data_df['signal'] * part_data_df['price_return_sum'].shift(-2)

        part_data_df['turnover'] = (part_data_df['position_sft'] - part_data_df['position_sft'].shift(1)) \
                                   * part_data_df['Close']

        # 剔除开盘收盘5min的signal
        part_pnl_df = part_data_df.groupby('Date')['pnl'].sum()
        part_turnover = part_data_df.groupby('Date')['turnover'].apply(
            lambda x: sum(abs(x)))
        return part_pnl_df, part_turnover, part_data_df
    except Exception as error:
        print(error)
        return None
Пример #3
0
                print('!!!!!!!!!!!!!!!!')


window_list = [10, 20, 40, 100]
limit_list = [1, 1.5, 2]
for instrument in instrument_list:
    # part_test_fun(instrument)
    adj_close_df = FutData().load_act_adj_fut_data(instrument, 'Close', active_df, aadj_factor_df)
    adj_high_df = FutData().load_act_adj_fut_data(instrument, 'High', active_df, aadj_factor_df)
    adj_low_df = FutData().load_act_adj_fut_data(instrument, 'Low', active_df, aadj_factor_df)

    adj_return_df = adj_close_df / adj_close_df.shift(1) - 1
    month_signal = pd.DataFrame(adj_return_df.index.strftime('%m'), index=adj_return_df.index, columns=['month'])

    for n in window_list:
        raw_factor = FutIndex.boll_fun(adj_close_df, n)
        for limit in limit_list:
            signal = Signal.fun_1(raw_factor, limit)
            pos = Position.fun_1(signal)
            pnl_df = (pos.shift(2) * adj_return_df).fillna(0)

            sp = bt.AZ_Sharpe_y(pnl_df)
            pot = bt.AZ_Pot(pos, pnl_df.sum())
            print(instrument, sp, pot, n, limit)
            if abs(sp) > 1.4:
                print('!!!!!!!!!!!!!!!!')
            print(f'sum:', sum(pnl_df))
            if abs(sp) > 0.7:
                for x, y in month_signal.groupby(by=['month']):
                    print(x, round(sum(pnl_df.loc[y.index]), 5))
                plt.plot(pnl_df.cumsum())
Пример #4
0
def part_test(
    con_id,
    begin_time,
    end_time,
    # p_window, p_limit,
    # v_window, v_limit,
    # voli_window, voli_limit,
    CCI_window,
    CCI_limit,
    # hold_time
):
    try:
        # print(con_id, begin_time, end_time)
        data_df = fut_data.load_intra_data(con_id,
                                           ['High', 'Low', 'Close', 'Volume'])
        # begin_time = pd.to_datetime('20190101')
        # # end_time = begin_time + timedelta(1)
        # end_time = pd.to_datetime('20190401')

        # p_window = 1
        # p_limit = 1
        # v_window = 20
        # v_limit = 2

        part_data_df = data_df.truncate(before=begin_time, after=end_time)

        part_data_df['weekday'] = pd.to_datetime(
            part_data_df['Date']).dt.weekday
        part_data_df['weekday_pos'] = (
            (part_data_df['weekday'] != 2)
            & (part_data_df['weekday'] != 1)
            # & (part_data_df['weekday'] != 3)
            # (part_data_df['weekday'] != 4)
        ).astype(int)
        part_data_df['month'] = part_data_df['Date'].str.slice(5, 7)
        part_data_df['month_pos'] = (
            (part_data_df['month'] != '10') &
            (part_data_df['month'] != '12')).astype(int)

        # part_data_df['time_pos_cut'] = part_data_df.apply(lambda x: -1 if (((x['Time'] > '14:51')
        #                                                                     & (x['Time'] <= '15:00')
        #                                                                     # | (x['Time'] > '21:00')
        #                                                                     # & (x['Time'] <= '22:00')
        #                                                                     # | (x['Time'] > '21:00')
        #                                                                     # & (x['Time'] <= '22:00')
        #                                                                     )) else 1, axis=1)

        v_window = 60
        part_data_df['Volume_zscore'] = bt.AZ_Col_zscore(
            part_data_df[['Volume']], v_window)
        part_data_df['Volume_signal'] = (part_data_df['Volume_zscore'] <
                                         2).astype(int).replace(0, -1)

        p_window = 3
        # part_data_df['past_min_pct_change'] = (part_data_df['Close'] - part_data_df['Close'].shift(p_window)) \
        #                                       / part_data_df['Close'].shift(p_window)
        part_data_df['past_min_pct_change'] = (
            part_data_df['Close'] - part_data_df['Close'].shift(p_window))
        part_data_df['past_min_pct_signal'] = part_data_df['past_min_pct_change'] \
            .apply(lambda x: 0 if abs(x) < 0.005 else (1 if x > 0.005 else -1))

        part_data_df['CCI_score'] = FutIndex.CCI_fun(part_data_df['High'],
                                                     part_data_df['Low'],
                                                     part_data_df['Close'],
                                                     CCI_window)

        part_data_df['CCI_signal'] = Signal.fun_1(part_data_df['CCI_score'],
                                                  CCI_limit)

        part_data_df['CCI_pos'] = Position.fun_1(part_data_df['CCI_signal'])

        part_data_df['boll_score'] = FutIndex.boll_fun(part_data_df['Close'],
                                                       CCI_window)
        part_data_df['boll_signal'] = Signal.fun_1(part_data_df['boll_score'],
                                                   CCI_limit)
        part_data_df['boll_pos'] = Position.fun_1(part_data_df['boll_signal'])

        part_data_df['trend_signal'] = bt.AZ_Rolling(part_data_df['Close'],
                                                     500).std()
        part_data_df['trend_pos'] = (part_data_df['trend_signal'] <
                                     20).astype(int)

        # part_data_df['position'] = part_data_df['boll_pos'] * part_data_df['weekday_pos'] * part_data_df['month_pos']
        part_data_df[
            'position'] = part_data_df['boll_pos'] * part_data_df['trend_pos']

        part_data_df['position_sft'] = (part_data_df['position'].shift(2) *
                                        part_data_df['weekday_pos']).fillna(0)
        part_data_df['price_return'] = part_data_df['Close'] - part_data_df[
            'Close'].shift(1)

        # part_data_df['price_return_sum'] = bt.AZ_Rolling(part_data_df['price_return'], hold_time).sum() \
        #     .shift(-hold_time + 1)
        part_data_df['pnl'] = part_data_df['position_sft'] * part_data_df[
            'price_return']
        part_data_df['asset'] = part_data_df['pnl'].cumsum()
        # part_data_df['pnl_test'] = part_data_df['signal'] * part_data_df['price_return_sum'].shift(-2)

        part_data_df['turnover'] = (part_data_df['position_sft'] - part_data_df['position_sft'].shift(1)) \
                                   * part_data_df['Close']

        # 剔除开盘收盘5min的signal
        # plt.figure(figsize=[64, 64])
        # ax1 = plt.subplot(4, 1, 1)
        # ax2 = plt.subplot(4, 1, 2)
        # ax3 = plt.subplot(4, 1, 3)
        # ax1.plot(part_data_df['asset'].values)
        # # ax2.plot(part_data_df['Close'].values, '--', color='#75bbfd')
        # ax2.scatter(np.array(range(len(part_data_df.index)))[(part_data_df['position_sft'] > 0)],
        #             part_data_df['Close'][part_data_df['position_sft'] > 0], s=0.5, color='red')
        #
        # ax2.scatter(np.array(range(len(part_data_df.index)))[(part_data_df['position_sft'] == 0)],
        #             part_data_df['Close'][part_data_df['position_sft'] == 0], s=0.5, color='black')
        #
        # ax2.scatter(np.array(range(len(part_data_df.index)))[(part_data_df['position_sft'] < 0)],
        #             part_data_df['Close'][part_data_df['position_sft'] < 0], s=0.5, color='blue')
        # # ax2.scatter(np.array(range(len(part_data_df.index)))[(part_data_df['past_min_pct_signal'] > 0)],
        # #             part_data_df['Close'][part_data_df['past_min_pct_signal'] > 0], s=20, color='black')
        # # ax2.scatter(np.array(range(len(part_data_df.index)))[(part_data_df['past_min_pct_signal'] < 0)],
        # #             part_data_df['Close'][part_data_df['past_min_pct_signal'] < 0], s=20, color='y')
        #
        # ax3.bar(range(len(part_data_df.index)), part_data_df['Volume'].values)
        #
        # ax1.grid()
        # ax2.grid()
        # ax3.grid()
        # plt.title(con_id)
        # savfig_send(con_id)
        #
        part_pnl_df = part_data_df.groupby('Date')['pnl'].sum()
        part_turnover = part_data_df.groupby('Date')['turnover'].apply(
            lambda x: sum(abs(x)))
        return part_pnl_df, part_turnover, part_data_df
    except Exception as error:
        print(error)
        return pd.Series(), pd.Series(), pd.Series()
Пример #5
0
def part_test(
        con_id,
        begin_time,
        end_time,
        # p_window, p_limit,
        # v_window, v_limit,
        # voli_window, voli_limit,
        CCI_window,
        CCI_limit,
        # hold_time,
        cut_num):
    # print(con_id, begin_time, end_time)
    try:
        # print(con_id, begin_time, end_time)
        all_min_df = fut_data.load_intra_data(con_id, ['Close'])
        data_df = fut_data.load_intra_reshape_data(
            con_id, ['High', 'Low', 'Close', 'Volume', 'OpenInterest'],
            cut_num=cut_num)

        if con_id == 'J1501.DCE':
            print(1)
        # begin_time = pd.to_datetime('20190101')
        # # end_time = begin_time + timedelta(1)
        # end_time = pd.to_datetime('20190401')

        # p_window = 1
        # p_limit = 1
        # v_window = 20
        # v_limit = 2

        part_data_df = data_df.truncate(before=begin_time, after=end_time)
        part_data_df['OpenInterest_core'] = FutIndex.boll_fun(
            data_df['OpenInterest'], 100)
        part_data_df['weekday'] = pd.to_datetime(
            part_data_df['Date']).dt.weekday
        part_data_df['weekday_pos'] = (
            (part_data_df['weekday'] != 3)
            # & (part_data_df['weekday'] != 3)
            # & (part_data_df['weekday'] != 3)
            # (part_data_df['weekday'] != 4)
        ).astype(int)
        part_data_df['month'] = part_data_df['Date'].str.slice(5, 7)
        # part_data_df['month_pos'] = ((part_data_df['month'] != '10') & (part_data_df['month'] != '12')).astype(int)
        part_data_df['month_pos'] = (part_data_df['month'] != '1').astype(int)

        # part_data_df['time_pos_cut'] = part_data_df.apply(lambda x: -1 if (((x['Time'] > '14:51')
        #                                                                     & (x['Time'] <= '15:00')
        #                                                                     # | (x['Time'] > '21:00')
        #                                                                     # & (x['Time'] <= '22:00')
        #                                                                     # | (x['Time'] > '21:00')
        #                                                                     # & (x['Time'] <= '22:00')
        #                                                                     )) else 1, axis=1)
        part_data_df[
            'Vol_OI'] = part_data_df['Volume'] / part_data_df['OpenInterest']

        part_data_df['Volume_boll'] = FutIndex.boll_fun(
            part_data_df[['Volume']], CCI_window)
        part_data_df['past_roll_Volume'] = bt.AZ_Rolling_mean(
            part_data_df[['Volume']], CCI_window)
        v_window = 60
        part_data_df['Volume_zscore'] = bt.AZ_Col_zscore(
            part_data_df[['Volume']], CCI_window)
        part_data_df['Volume_signal'] = Signal.fun_1(
            part_data_df['Volume_zscore'], 0.01)
        # part_data_df['Volume_signal'] = (part_data_df['Volume_zscore'] < 2).astype(int).replace(0, -1)

        p_window = 5
        # part_data_df['past_min_pct_change'] = (part_data_df['Close'] - part_data_df['Close'].shift(p_window)) \
        #                                       / part_data_df['Close'].shift(p_window)

        part_data_df['past_min_pct_change'] = (
            part_data_df['Close'] / part_data_df['Close'].shift(p_window) - 1)
        part_data_df['past_min_pct_signal'] = part_data_df['past_min_pct_change'] \
            .apply(lambda x: 0 if abs(x) < 0.004 else (1 if x > 0.004 else -1))

        test_window = CCI_window
        macd, macdsignal, macdhist = ta.MACD(part_data_df['Close'], 12, 26, 9)
        part_data_df['macd'] = macd
        RSI = ta.RSI(part_data_df['Close'], test_window)
        RSI = RSI - 50
        RSI[RSI > 20] = 20
        RSI[RSI < -20] = -20
        part_data_df['RSI'] = RSI
        part_data_df['RSI_signal'] = Signal.fun_1(part_data_df['RSI'], 1)
        part_data_df['RSI_pos'] = Position.fun_1(part_data_df['RSI_signal'],
                                                 limit=60)

        # aroondown, aroonup = ta.AROON(part_data_df['High'], part_data_df['Low'], test_window)

        obv = ta.OBV(part_data_df['Close'], part_data_df['Volume'])
        part_data_df['obv'] = obv

        atr = ta.ATR(part_data_df['High'], part_data_df['Low'],
                     part_data_df['Close'], test_window)
        part_data_df['atr'] = atr

        adx = ta.ADX(part_data_df['High'], part_data_df['Low'],
                     part_data_df['Close'], test_window)
        part_data_df['adx'] = adx

        trix = ta.TRIX(part_data_df['Close'], 60)
        part_data_df['trix'] = trix

        willr = ta.WILLR(part_data_df['High'], part_data_df['Low'],
                         part_data_df['Close'], test_window)
        part_data_df['willr'] = willr

        part_data_df['CCI_score'] = FutIndex.CCI_fun(part_data_df['High'],
                                                     part_data_df['Low'],
                                                     part_data_df['Close'],
                                                     CCI_window)

        part_data_df['CCI_signal'] = Signal.fun_1(part_data_df['CCI_score'],
                                                  CCI_limit)

        part_data_df['CCI_pos'] = Position.fun_1(part_data_df['CCI_signal'])

        part_data_df['boll_score'], ma_n, md_n = FutIndex.boll_fun(
            part_data_df['Close'], CCI_window, return_line=True)
        part_data_df['boll_signal'] = Signal.fun_1(part_data_df['boll_score'],
                                                   CCI_limit)

        part_data_df['boll_pos'] = Position.fun_1(part_data_df['boll_signal'])
        # part_data_df['boll_pos'] = Position.fun_3(part_data_df['boll_signal'], part_data_df['past_min_pct_signal'])

        part_data_df['test_score'] = FutIndex.test_fun(part_data_df['Close'],
                                                       CCI_window,
                                                       cap=5,
                                                       num=3,
                                                       return_line=False)
        part_data_df['test_signal'] = Signal.fun_1(part_data_df['test_score'],
                                                   CCI_limit)

        part_data_df['test_pos'] = Position.fun_1(part_data_df['test_signal'])
        # part_data_df['trend_signal'] = bt.AZ_Rolling(part_data_df['Close'], 500).std()
        # part_data_df['trend_pos'] = (part_data_df['trend_signal'] < 40).astype(int)

        part_data_df['trend_indicator'] = bt.AZ_Rolling(part_data_df['Close'], 100). \
            apply(lambda x: (x[-1] / x[0] - 1) / (max(x) / min(x) - 1), raw=False)
        part_data_df['trend_pos'] = (part_data_df['trend_indicator'] <
                                     0.5).astype(int)

        # part_data_df['position'] = part_data_df['boll_pos'] * part_data_df['weekday_pos'] * part_data_df['month_pos']

        # part_data_df['position'] = part_data_df['CCI_pos']
        part_data_df['position'] = part_data_df['CCI_pos']

        part_data_df['position_exe'] = part_data_df['position'].shift(1)
        part_data_df['position_sft'] = part_data_df['position'].shift(2)

        # part_data_df['price_return'] = part_data_df['Close'] - part_data_df['Close'].shift(1)

        part_data_df['next_trade_close'] = all_min_df['Close'].shift(
            -2).reindex(part_data_df.index)
        part_data_df['price_return'] = part_data_df['next_trade_close'] - \
                                       part_data_df['next_trade_close'].shift(1)

        # part_data_df['price_return_sum'] = bt.AZ_Rolling(part_data_df['price_return'], hold_time).sum() \
        #     .shift(-hold_time + 1)
        # part_data_df['pnl'] = part_data_df['position_sft'] * part_data_df['price_return']
        part_data_df['pnl'] = part_data_df['position_exe'] * part_data_df[
            'price_return']
        part_data_df['asset'] = part_data_df['pnl'].cumsum()
        # part_data_df['pnl_test'] = part_data_df['signal'] * part_data_df['price_return_sum'].shift(-2)

        part_data_df['turnover'] = (part_data_df['position_sft'] - part_data_df['position_sft'].shift(1)) \
                                   * part_data_df['Close']

        # 剔除开盘收盘5min的signal
        # if '1910' in con_id:

        # plt.figure(figsize=[64, 64])
        # ax1 = plt.subplot(4, 1, 1)
        # ax2 = plt.subplot(4, 1, 2)
        # ax3 = plt.subplot(4, 1, 3)
        # ax1.plot(part_data_df['asset'].values)
        # # ax2.plot(part_data_df['Close'].values, '--', color='#75bbfd')
        # ax2.scatter(np.array(range(len(part_data_df.index)))[(part_data_df['position_sft'] > 0)],
        #             part_data_df['Close'][part_data_df['position_sft'] > 0], s=0.5, color='red')
        #
        # ax2.scatter(np.array(range(len(part_data_df.index)))[(part_data_df['position_sft'] == 0)],
        #             part_data_df['Close'][part_data_df['position_sft'] == 0], s=0.5, color='black')
        #
        # ax2.scatter(np.array(range(len(part_data_df.index)))[(part_data_df['position_sft'] < 0)],
        #             part_data_df['Close'][part_data_df['position_sft'] < 0], s=0.5, color='blue')
        #
        # # ax2.scatter(np.array(range(len(part_data_df.index)))[(part_data_df['past_min_pct_signal'] > 0)],
        # #             part_data_df['Close'][part_data_df['past_min_pct_signal'] > 0], s=20, color='y')
        # # ax2.scatter(np.array(range(len(part_data_df.index)))[(part_data_df['past_min_pct_signal'] < 0)],
        # #             part_data_df['Close'][part_data_df['past_min_pct_signal'] < 0], s=20, color='#f504c9')
        #
        # ax3.bar(range(len(part_data_df.index)), part_data_df['Volume'].values)
        #
        # ax1.grid()
        # ax2.grid()
        # ax3.grid()
        # plt.title(con_id)
        # savfig_send(con_id)

        part_pnl_df = part_data_df.groupby('Date')['pnl'].sum()
        part_turnover = part_data_df.groupby('Date')['turnover'].apply(
            lambda x: sum(abs(x)))
        return part_pnl_df, part_turnover, part_data_df
    except Exception as error:
        print(error)
        return pd.Series(), pd.Series(), pd.Series()
Пример #6
0
def part_test(con_id, begin_time, end_time, CCI_window, CCI_limit):
    try:
        data_df = fut_data.load_intra_data(con_id,
                                           ['High', 'Low', 'Close', 'Volume'])

        part_data_df = data_df.truncate(before=begin_time, after=end_time)

        part_data_df['weekday'] = pd.to_datetime(
            part_data_df['Date']).dt.weekday
        part_data_df['weekday_pos'] = (
            (part_data_df['weekday'] != 2)
            & (part_data_df['weekday'] != 1)
            # & (part_data_df['weekday'] != 3)
            # (part_data_df['weekday'] != 4)
        ).astype(int).shift(-2)

        part_data_df['boll_score'] = FutIndex.boll_fun(part_data_df['Close'],
                                                       CCI_window)
        part_data_df['boll_signal'] = Signal.fun_1(part_data_df['boll_score'],
                                                   CCI_limit)
        part_data_df['boll_pos'] = Position.fun_1(part_data_df['boll_signal'])

        part_data_df['trend_signal'] = bt.AZ_Rolling(part_data_df['Close'],
                                                     500).std()
        part_data_df['trend_pos'] = (part_data_df['trend_signal'] <
                                     20).astype(int)

        part_data_df['position'] = part_data_df['boll_pos'] * part_data_df[
            'trend_pos'] * part_data_df['weekday_pos']
        part_data_df['position_exe'] = part_data_df['position'].shift(
            1).fillna(0)
        part_data_df['position_sft'] = part_data_df['position'].shift(
            2).fillna(0)
        part_data_df['price_return'] = part_data_df['Close'] / part_data_df[
            'Close'].shift(1) - 1

        part_data_df['pnl'] = part_data_df['position_sft'] * part_data_df[
            'price_return']
        part_data_df['asset'] = part_data_df['pnl'].cumsum()

        part_data_df['turnover'] = (part_data_df['position_sft'] -
                                    part_data_df['position_sft'].shift(1))
        part_data_df['con_id'] = con_id
        part_pnl_df = part_data_df.groupby('Date')['pnl'].sum()
        part_turnover = part_data_df.groupby('Date')['turnover'].apply(
            lambda x: sum(abs(x)))
        # 剔除开盘收盘5min的signal
        plt.figure(figsize=[64, 64])
        ax1 = plt.subplot(4, 1, 1)
        ax2 = plt.subplot(4, 1, 2)
        ax3 = plt.subplot(4, 1, 3)
        ax1.plot(part_data_df['asset'].values)
        # ax2.plot(part_data_df['Close'].values, '--', color='#75bbfd')
        ax2.scatter(np.array(range(len(
            part_data_df.index)))[(part_data_df['position_sft'] > 0)],
                    part_data_df['Close'][part_data_df['position_sft'] > 0],
                    s=0.5,
                    color='red')

        ax2.scatter(np.array(range(len(
            part_data_df.index)))[(part_data_df['position_sft'] == 0)],
                    part_data_df['Close'][part_data_df['position_sft'] == 0],
                    s=0.5,
                    color='black')

        ax2.scatter(np.array(range(len(
            part_data_df.index)))[(part_data_df['position_sft'] < 0)],
                    part_data_df['Close'][part_data_df['position_sft'] < 0],
                    s=0.5,
                    color='blue')
        # ax2.scatter(np.array(range(len(part_data_df.index)))[(part_data_df['past_min_pct_signal'] > 0)],
        #             part_data_df['Close'][part_data_df['past_min_pct_signal'] > 0], s=20, color='black')
        # ax2.scatter(np.array(range(len(part_data_df.index)))[(part_data_df['past_min_pct_signal'] < 0)],
        #             part_data_df['Close'][part_data_df['past_min_pct_signal'] < 0], s=20, color='y')

        ax3.bar(range(len(part_data_df.index)), part_data_df['Volume'].values)

        ax1.grid()
        ax2.grid()
        ax3.grid()
        plt.title(con_id)

        savfig_send(con_id)
        return part_pnl_df, part_turnover, part_data_df
    except Exception as error:
        print(error)
        return None