예제 #1
0
    def tmp_fun(open_limit, limit, hold_time):
        data_df['open_signal'] = (data_df['Volume_zscore'] >
                                  open_limit).astype(int).replace(0, np.nan)
        x = data_df[[
            'Date', 'open_signal', 'return', 'time_pos_cut', 'roll_return',
            'price_f_return_3', 'price_f_return_5', 'price_f_return_10',
            'price_f_return_20', 'price_f_return_30', 'price_f_return_40',
            'price_f_return_50'
        ]]
        # y = x[x['open_signal'] == x['open_signal']]
        y = x
        y['way'] = y['roll_return'].apply(fun, args=(limit, ))
        y['pos'] = y['way'] * y['open_signal'] * y['time_pos_cut']
        y['pnl'] = y[f'price_f_return_{hold_time}'] * y['pos']
        y['asset'] = y['pnl'].fillna(0).cumsum()

        daily_pnl = y.groupby(by='Date')['pnl'].sum()
        sp = bt.AZ_Sharpe_y(daily_pnl)
        print(sum(y['pnl'].fillna(0)), sum(abs(y['pos'].fillna(0))))
        pot = round(
            sum(y['pnl'].fillna(0)) / sum(abs(y['pos'].fillna(0))) * 10000, 4)
        plt.plot(y['asset'])
        savfig_send(
            subject=
            f'open_limit={open_limit}, limit={limit}, hold_time={hold_time}, sp={sp}, pot={pot}'
        )
        return y
예제 #2
0
    def generation(self, fut_name, window, limit, concat=True, test=False):
        result_list = []
        pool = Pool(20)
        for con_id, part_info_df in self.active_df[[
                f'{fut_name}01'
        ]].groupby(f'{fut_name}01'):
            # active_begin = self.next_trade_date(part_info_df.index[0]) + timedelta(hours=17)
            # active_end = part_info_df.index[-1] + timedelta(hours=17)
            args = [fut_name, con_id, window, limit]
            result_list.append(
                pool.apply_async(self.part_generation, args=args))
            # self.part_generation(*args)
        pool.close()
        pool.join()
        print(123)
        pnl_df = pd.concat([res.get()[0] for res in result_list], axis=0)
        turnover_df = pd.concat([res.get()[1] for res in result_list], axis=0)
        data_df = pd.concat([res.get()[2] for res in result_list], axis=0)

        pot = pnl_df.sum() / turnover_df.sum() * 10000
        sp = bt.AZ_Sharpe_y(pnl_df)
        print(fut_name, sp, pot, window, limit, cut_num)

        Close_p = pd.read_csv(f'/mnt/mfs/DAT_FUT/day/{fut_name}/Close',
                              sep='|',
                              index_col=0,
                              parse_dates=True)
        Open_p = pd.read_csv(f'/mnt/mfs/DAT_FUT/day/{fut_name}/Open',
                             sep='|',
                             index_col=0,
                             parse_dates=True)
        jump_diff = Open_p / Close_p.shift(1) - 1
        self.jump_diff = jump_diff.reindex(self.active_df.index)
        act_info_sr = self.active_df[f'{fut_name}01']
        fut_jump = self.jump_diff.apply(lambda x, y: x * (y == x.name),
                                        args=(act_info_sr, )).sum(1)

        if (abs(sp) > 1.2 and pot > 4) or test:
            # if (sp < -1.2) or test:
            plt.figure(figsize=[16, 8])
            pnl_df.index = pd.to_datetime(pnl_df.index)
            plt.plot(pnl_df.cumsum())
            plt.grid()
            savfig_send(
                f'{fut_name} sp:{sp} pot={pot} CCI_window:{window}, CCI_limit:{limit} cut_num={self.cut_num}'
            )

            part_data_df = data_df
            col_name = 'Time'
            raw_return_df = part_data_df['pnl']
            signal_df = part_data_df[col_name].shift(2).replace(
                np.nan, '00:00')
            SignalAnalysis.CDF_c(signal_df,
                                 raw_return_df,
                                 hold_time=1,
                                 title=f'{fut_name} {col_name} CDF Figure',
                                 lag=0)

            ana_fun(data_df, fut_name, 'test_score')
            ana_fun(data_df, fut_name, 'boll_score')
            ana_fun(data_df, fut_name, 'CCI_score')

            ana_fun(data_df, fut_name, 'trend_indicator')

            ana_fun(data_df, fut_name, 'macd')
            ana_fun(data_df, fut_name, 'RSI')
            ana_fun(data_df, fut_name, 'obv')
            ana_fun(data_df, fut_name, 'atr')
            ana_fun(data_df, fut_name, 'adx')

            ana_fun(data_df, fut_name, 'trix')
            ana_fun(data_df, fut_name, 'willr')
            ana_fun(data_df, fut_name, 'past_min_pct_change')

            ana_fun(data_df, fut_name, 'Vol_OI')
            ana_fun(data_df, fut_name, 'OI_boll')
            ana_fun(data_df, fut_name, 'adosc')
            ana_fun(data_df, fut_name, 'cmo')
            ana_fun(data_df, fut_name, 'mfi')

            # raw_return_df = data_df.groupby(by=['Date'])['pnl'].apply(lambda x: x.iloc[1:].sum())
            # signal_df = fut_jump
            # SignalAnalysis.CDF(signal_df, raw_return_df, hold_time=1, title=f'{fut_name} jump CDF Figure', lag=1)

            self.pos_to_bkt(data_df, concat)
        return data_df, sp, pot
예제 #3
0
    def run(self, part_data_df, con_id, window, limit, active_begin=None):
        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'] != 2)
            # & (part_data_df['weekday'] != 3)
            # (part_data_df['weekday'] != 4)
        ).astype(int)
        part_data_df['time_pos_cut'] = part_data_df.apply(
            lambda x: 0
            if (((x['Time'] >= '14:50')
                 & (x['Time'] <= '15:00')
                 | (x['Time'] > '22:50')
                 & (x['Time'] <= '23:00')
                 # | (x['Time'] > '21:00')
                 # & (x['Time'] <= '22:00')
                 )) else 1,
            axis=1)
        part_data_df['tmp_return'] = part_data_df['Close'] / part_data_df[
            'Close'].shift(1) - 1
        part_data_df['reverse_signal'] = self.reverse_signal_fun(
            part_data_df['tmp_return'])
        part_data_df['month'] = part_data_df['Date'].str.slice(5, 7)
        part_data_df['month_pos'] = (
            (part_data_df['month'] != '05') &
            (part_data_df['month'] != '11')).astype(int)
        part_data_df[
            'Vol_OI'] = part_data_df['Volume'] / part_data_df['OpenInterest']
        # part_data_df['Vol_OI_pos'] = ((part_data_df['Vol_OI'] > 0.35) & (part_data_df['Vol_OI'] < 0.35)).astype(int)
        part_data_df['Vol_OI_pos'] = (part_data_df['Vol_OI'] <
                                      0.01).astype(int)

        part_data_df['OI_boll'], _, _ = FutIndex.boll_fun(
            part_data_df['OpenInterest'], window, return_line=True)
        macd, macdsignal, macdhist = ta.MACD(part_data_df['Close'], 12, 26, 9)
        part_data_df['macd'] = macd
        part_data_df['macd_pos'] = (macd < 25).astype(int)

        macd, macdsignal, macdhist = ta.MACD(part_data_df['Close'], 12, 26, 9)
        part_data_df['macd'] = macd
        part_data_df['macd_pos'] = (macd < 25).astype(int)
        RSI = ta.RSI(part_data_df['Close'], 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'])

        # 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
        part_data_df['obv_pos'] = (obv < 1600000).astype(int)

        atr = ta.ATR(part_data_df['High'], part_data_df['Low'],
                     part_data_df['Close'], window)
        part_data_df['atr'] = atr
        part_data_df['atr_pos'] = (atr < 10).astype(int).replace(0, -1)

        adx = ta.ADX(part_data_df['High'], part_data_df['Low'],
                     part_data_df['Close'], window)
        part_data_df['adx'] = adx
        part_data_df['adx_pos'] = (adx < 50).astype(int).replace(0, -1)

        trix = ta.TRIX(part_data_df['Close'], window)
        part_data_df['trix'] = trix
        part_data_df['trix_pos'] = (trix > -0.05).astype(int)

        willr = ta.WILLR(part_data_df['High'], part_data_df['Low'],
                         part_data_df['Close'], window)
        part_data_df['willr'] = willr
        part_data_df['willr_pos'] = ((willr < -70) |
                                     (willr > -30)).astype(int).replace(0, -1)

        adosc = ta.ADOSC(part_data_df['High'], part_data_df['Low'],
                         part_data_df['Close'], part_data_df['Volume'], window,
                         int(window / 2))
        part_data_df['adosc'] = adosc

        cmo = ta.CMO(part_data_df['Close'], window)
        part_data_df['cmo'] = cmo

        mfi = ta.MFI(part_data_df['High'], part_data_df['Low'],
                     part_data_df['Close'], part_data_df['Volume'], window)
        part_data_df['mfi'] = mfi

        p_window = 5
        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: 1 if abs(x) < 0.01 else -1)

        part_data_df['test_score'] = FutIndex.test_fun(part_data_df['Close'],
                                                       window,
                                                       cap=5,
                                                       num=5,
                                                       return_line=False)
        part_data_df['test_signal'] = Signal.fun_1(part_data_df['test_score'],
                                                   limit)
        # part_data_df['test_signal'] = Signal.fun_2(part_data_df['test_score'], limit, 0)

        part_data_df['test_pos'] = Position.fun_1(part_data_df['test_signal'])

        part_data_df['boll_score'], ma_n, md_n = FutIndex.boll_fun(
            part_data_df['Close'], window, return_line=True)
        part_data_df['boll_signal'] = Signal.fun_1(part_data_df['boll_score'],
                                                   limit)
        part_data_df['boll_pos'] = Position.fun_1(part_data_df['boll_signal'])

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

        part_data_df['CCI_signal'] = Signal.fun_1(part_data_df['CCI_score'],
                                                  limit)
        # part_data_df['CCI_signal'] = Signal.fun_2(part_data_df['CCI_score'], limit, 0)

        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'].abs() >
                                     0.25).astype(int)

        part_data_df['Volume_zscore'] = bt.AZ_Col_zscore(
            part_data_df[['Volume']], 10)
        part_data_df['Volume_signal'] = Signal.fun_1(
            part_data_df['Volume_zscore'], 2)

        part_data_df['open_signal'] = (part_data_df['Volume_zscore'] >
                                       4).astype(int).replace(0, np.nan)
        part_data_df['return'] = (part_data_df['Close'] /
                                  part_data_df['Close'].shift(1)) - 1
        part_data_df['roll_return'] = (
            (part_data_df['Close'] / part_data_df['Close'].shift(1)) -
            1).rolling(3).sum()

        # part_data_df['way'] = part_data_df['roll_return'].apply(fun, args=(0.002,))
        # part_data_df['pos'] = part_data_df['way'] * part_data_df['open_signal']

        part_data_df['signal'] = part_data_df['CCI_signal']
        part_data_df['position'] = Position.fun_1(part_data_df['signal'])
        # part_data_df['test_signal_c'] = Signal.fun_2(part_data_df['test_score'], limit, 0.5)
        # part_data_df['position'] = part_data_df['test_signal_c'].ffill()
        # part_data_df['position_open'] = part_data_df['position'][(part_data_df['position'] != 0) &
        #                                                          (part_data_df['position'].diff() != 0)]
        # part_data_df['position_open_fill'] = part_data_df['position_open'].ffill(limit=5)
        # part_data_df['position_na'] = part_data_df['position'].replace(0, np.nan)
        # part_data_df['position_new'] = part_data_df['position_na'].combine_first(part_data_df['position_open_fill'])
        # part_data_df['position'] = part_data_df['position_new'].fillna(0)
        # part_data_df['position'] = Position.fun_4(part_data_df['signal'], 30, cap=2) * part_data_df['atr_pos']
        # * part_data_df['atr_pos'] * part_data_df['weekday_pos']
        ###############################################################
        # part_data_df['position'] = part_data_df['CCI_signal']

        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[
            'next_trade_close'] / part_data_df['next_trade_close'].shift(1) - 1

        part_data_df['price_f_return_3'] = part_data_df['next_trade_close'].shift(-3) / \
                                           part_data_df['next_trade_close'] - 1

        part_data_df['price_f_return_5'] = part_data_df['next_trade_close'].shift(-5) / \
                                           part_data_df['next_trade_close'] - 1

        part_data_df['price_f_return_10'] = part_data_df['next_trade_close'].shift(-10) / \
                                            part_data_df['next_trade_close'] - 1

        part_data_df['price_f_return_20'] = part_data_df['next_trade_close'].shift(-20) / \
                                            part_data_df['next_trade_close'] - 1

        part_data_df['price_f_return_30'] = part_data_df['next_trade_close'].shift(-30) / \
                                            part_data_df['next_trade_close'] - 1

        part_data_df['price_f_return_40'] = part_data_df['next_trade_close'].shift(-40) / \
                                            part_data_df['next_trade_close'] - 1

        part_data_df['price_f_return_50'] = part_data_df['next_trade_close'].shift(-50) / \
                                            part_data_df['next_trade_close'] - 1

        part_data_df['pnl'] = part_data_df['position_exe'] * part_data_df[
            'price_return']

        part_data_df = part_data_df.truncate(before=active_begin)

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

        part_data_df['asset'] = part_data_df['pnl'].cumsum()

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

        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['open_signal'] == part_data_df['open_signal'])],
                    part_data_df['Close'][part_data_df['open_signal'] ==
                                          part_data_df['open_signal']],
                    s=10,
                    color='red')

        # ax2.scatter(np.array(range(len(part_data_df.index)))[(part_data_df['position'] > 0)],
        #             part_data_df['Close'][part_data_df['position'] > 0], s=2, color='red')
        #
        # ax2.scatter(np.array(range(len(part_data_df.index)))[(part_data_df['position'] == 0)],
        #             part_data_df['Close'][part_data_df['position'] == 0], s=2, color='black')
        #
        # ax2.scatter(np.array(range(len(part_data_df.index)))[(part_data_df['position'] < 0)],
        #             part_data_df['Close'][part_data_df['position'] < 0], s=2, color='blue')

        # ax2.scatter(part_data_df.index[(part_data_df['position'] > 0)],
        #             part_data_df['Close'][part_data_df['position'] > 0], s=0.5, color='red')
        #
        # ax2.scatter(part_data_df.index[(part_data_df['position'] == 0)],
        #             part_data_df['Close'][part_data_df['position'] == 0], s=0.5, color='black')
        #
        # ax2.scatter(part_data_df.index[(part_data_df['position'] < 0)],
        #             part_data_df['Close'][part_data_df['position'] < 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)

        return part_pnl_df, part_turnover, part_data_df
예제 #4
0
                                          open_limit).astype(int).replace(
                                              0, np.nan)
                x = data_df[[
                    'open_signal', 'return', 'time_pos_cut', 'roll_return',
                    'price_f_return_5', 'price_f_return_10',
                    'price_f_return_20', 'price_f_return_30',
                    'price_f_return_40', 'price_f_return_50'
                ]]
                # y = x[x['open_signal'] == x['open_signal']]
                y = x
                y['way'] = y['roll_return'].apply(fun, args=(limit, ))
                y['pos'] = (y['way'] * y['open_signal'] *
                            y['time_pos_cut']).fillna(0)
                y['pnl'] = (y[f'price_f_return_{hold_time}'] *
                            y['pos']).fillna(0)
                y['asset'] = y['pnl'].cumsum()
                sp = bt.AZ_Sharpe_y(y['pnl'])

                print(sum(y['pnl']), sum(abs(y['pos'])))
                pot = round(sum(y['pnl']) / sum(abs(y['pos'])) * 10000, 4)
                plt.plot(y['asset'])
                savfig_send(
                    subject=
                    f'open_limit={open_limit}, limit={limit}, hold_time={hold_time}, sp={sp}, pot={pot}'
                )

    # open_limit, limit, hold_time = 2, 0.003, 5
    # y = tmp_fun(open_limit, limit, hold_time)
    # z = y[y['open_signal'] == y['open_signal']]
    # zz = z[z['way'] != 0]
예제 #5
0
                for date_now in date_list[30:-1]:
                    # date_now = '2019_09_27'
                    print('_________________')
                    print(date_now)
                    # diff_df = date_fun(date_now)
                    # diff_df['rb2101'].iloc[:2400].quantile([0.05, 0.10, 0.90, 0.95])
                    #
                    # plt.figure(figsize=[40, 10])
                    # plt.plot(diff_df['rb2101'].dropna().values)
                    # plt.legend()
                    # savfig_send(date_now)
                    # pnl, turnover, pot, con_num = pnl_fun(date_now, fut_name)
                    # pnl_fun(date_now, fut_name)

                    result_list.append(pnl_fun(date_now, fut_name, bkt_num, buy_sell_list))

                a = pd.DataFrame(result_list, columns=['pnl', 'turnover', 'pot', 'con_num', 'vol'], index=date_list[30:-1])
                a['pnl_real'] = a['pnl'] - a['turnover'] * 0.00005
                a_list.append(a)
                plt.figure(figsize=[20, 10])
                plt.plot(a['pnl_real'].cumsum())
                pot_all = a['pnl'].sum() / a['turnover'].sum() * 10000
                savfig_send(fut_name + str(round(pot_all, 6)))
                print(pot_all)
                tmp_list.append([bkt_num, buy_sell_list, a])
                SignalAnalysis.CDF(a['vol'], a['pot'], 1)
                SignalAnalysis.CDF(a['vol'], a['pnl_real'], 1)



예제 #6
0
    # percent_list = [0.95, 1]
    # now_time = '10:30'
    # percent = 1
    # result_dict = dict()
    # vol_sr_list = []
    # for now_date in date_list:
    #     for now_time in now_time_list:
    #         for percent in percent_list:
    #             vol_sr = main_fun(now_date, now_time, percent)
    #             vol_sr_list.append(vol_sr)
    # vol_df = pd.concat(vol_sr_list, axis=1, sort=False).T

    # result_sr = pd.Series()
    # for i in range(3, len(date_list)):
    #     print('____________________________________')
    #
    #     now_date = date_list[i]
    #     print(now_date)
    #     part_date_list = date_list[i - 3:i]
    #
    #     try:
    #         result_sr[now_date] = simple_st(now_date, part_date_list)
    #     except Exception as error:
    #         print(error)
    #         result_sr[now_date] = 0
    from work_dmgr_fut.loc_lib.pre_load.plt import savfig_send
    result_df['rate_diff'] = result_df['rate_weight'] - result_df['fut_rt']
    plt.figure(figsize=[20, 10])
    plt.plot(result_df['rate_diff'])
    savfig_send()
예제 #7
0
    def generation(self,
                   fut_name,
                   window_s,
                   window_l,
                   hold_time,
                   limit,
                   concat=True,
                   test=False):
        result_list = []
        pool = Pool(20)
        for con_id, part_info_df in self.active_df[[
                f'{fut_name}01'
        ]].groupby(f'{fut_name}01'):
            # active_begin = self.next_trade_date(part_info_df.index[0]) + timedelta(hours=17)
            # active_end = part_info_df.index[-1] + timedelta(hours=17)
            args = [fut_name, con_id, window_s, window_l, hold_time, limit]
            result_list.append(
                pool.apply_async(self.part_generation, args=args))
            # self.part_generation(*args)
        pool.close()
        pool.join()
        print(123)
        pnl_df = pd.concat([res.get()[0] for res in result_list], axis=0)
        turnover_df = pd.concat([res.get()[1] for res in result_list], axis=0)
        data_df = pd.concat([res.get()[2] for res in result_list], axis=0)

        pot = pnl_df.sum() / turnover_df.sum() * 10000
        sp = bt.AZ_Sharpe_y(pnl_df)
        print(fut_name, sp, pot, window_s, window_l, hold_time, limit, cut_num)

        Close_p = pd.read_csv(f'/mnt/mfs/DAT_FUT/day/{fut_name}/Close',
                              sep='|',
                              index_col=0,
                              parse_dates=True)
        Open_p = pd.read_csv(f'/mnt/mfs/DAT_FUT/day/{fut_name}/Open',
                             sep='|',
                             index_col=0,
                             parse_dates=True)
        jump_diff = Open_p / Close_p.shift(1) - 1
        self.jump_diff = jump_diff.reindex(self.active_df.index)
        act_info_sr = self.active_df[f'{fut_name}01']

        # if (sp < -1.2) or test:
        plt.figure(figsize=[16, 8])
        pnl_df.index = pd.to_datetime(pnl_df.index)
        plt.plot(pnl_df.cumsum())
        plt.grid()
        savfig_send(
            f'{fut_name} sp:{sp} pot:{pot} window_s:{window_s} window_l:{window_l} hold_time:{hold_time}'
            f'limit:{limit} cut_num={self.cut_num}')

        part_data_df = data_df
        col_name = 'Time'
        raw_return_df = part_data_df['pnl']
        signal_df = part_data_df[col_name].shift(2).replace(np.nan, '00:00')
        SignalAnalysis.CDF_c(signal_df,
                             raw_return_df,
                             hold_time=1,
                             title=f'{fut_name} {col_name} CDF Figure',
                             lag=0)

        self.pos_to_bkt(data_df, concat)
        return data_df, sp, pot
예제 #8
0
    def generation(self, fut_name, window, limit, concat=True):
        result_list = []
        pool = Pool(20)
        for con_id, part_info_df in self.active_df[[
                f'{fut_name}01'
        ]].groupby(f'{fut_name}01'):
            # active_begin = self.last_trade_date(part_info_df.index[0]) + timedelta(hours=17)
            # active_end = part_info_df.index[-1] + timedelta(hours=17)
            args = [fut_name, con_id, window, limit]
            result_list.append(
                pool.apply_async(self.part_generation, args=args))
            # self.part_generation(*args)
        pool.close()
        pool.join()

        pnl_df = pd.concat([res.get()[0] for res in result_list], axis=0)
        turnover_df = pd.concat([res.get()[1] for res in result_list], axis=0)
        data_df = pd.concat([res.get()[2] for res in result_list], axis=0)

        pot = pnl_df.sum() / turnover_df.sum() * 10000
        sp = bt.AZ_Sharpe_y(pnl_df)
        print(fut_name, sp, pot, window, limit, cut_num)
        if abs(sp) > 1.2 and abs(pot) > 6:
            plt.figure(figsize=[16, 8])
            pnl_df.index = pd.to_datetime(pnl_df.index)
            plt.plot(pnl_df.cumsum())
            plt.grid()
            savfig_send(
                f'{fut_name} sp:{sp} pot={pot} CCI_window:{window}, CCI_limit:{limit} cut_num={self.cut_num}'
            )

            part_data_df = data_df
            col_name = 'Time'
            raw_return_df = part_data_df['pnl']
            signal_df = part_data_df[col_name].shift(2).replace(
                np.nan, '00:00')
            SignalAnalysis.CDF_c(signal_df,
                                 raw_return_df,
                                 hold_time=1,
                                 title=f'{fut_name} {col_name} CDF Figure',
                                 lag=0)

            ana_fun(data_df, fut_name, 'test_score')
            ana_fun(data_df, fut_name, 'boll_score')
            ana_fun(data_df, fut_name, 'CCI_score')

            ana_fun(data_df, fut_name, 'trend_indicator')

            ana_fun(data_df, fut_name, 'macd')
            ana_fun(data_df, fut_name, 'RSI')
            ana_fun(data_df, fut_name, 'obv')
            ana_fun(data_df, fut_name, 'atr')
            ana_fun(data_df, fut_name, 'adx')

            ana_fun(data_df, fut_name, 'trix')
            ana_fun(data_df, fut_name, 'willr')

            ana_fun(data_df, fut_name, 'Vol_OI')

        self.pos_to_bkt(data_df, concat)
        return data_df, sp, pot