Пример #1
0
 def _get_df_factor(self):
     begin_date = ps.shift_n_trading_day(str(self.begin_year) + '0101', n=1)
     self._df_factor = ps.pickle_read(self._ts_data_path + 'df_factor.pkl')
     self._df_factor = self._df_factor.loc[begin_date:]
     if self.cut_small == True:
         self._df_factor = self._df_factor.groupby(
             level=0, group_keys=False).apply(lambda x: x.loc[x[
                 'circ_mv'] > x['circ_mv'].quantile(0.3), :])
Пример #2
0
 def _get_pos_hold(self):
     self.large_high_pos = {}
     self.small_high_pos = {}
     self.large_low_pos = {}
     self.small_low_pos = {}
     for month_date in sorted(list(self.context.df_ret_dict.keys())):
         buy_date = ps.shift_n_trading_day(month_date, -1)
         self.large_high_pos[buy_date], self.small_high_pos[buy_date], self.large_low_pos[buy_date], self.small_low_pos[buy_date] =\
         self._cal_factor_pos(month_date)
Пример #3
0
 def _cal_ret(self, pos_hold_raw):
     ret_list = []
     turnover_dict = {}
     delist_turnover_dict = {}
     pos_hold = pos_hold_raw.copy()
     rebalance_dates = sorted(list(pos_hold.keys()))
     for i, date in enumerate(rebalance_dates):
         pre_date = ps.shift_n_trading_day(date)
         df = pd.merge(pos_hold[date].to_frame(),
                       self.context.df_ret_dict[pre_date].iloc[:, 1:],
                       left_index=True,
                       right_index=True,
                       how='left').fillna(0)
         ret = df.iloc[:, 1:].apply(np.average, weights=df.iloc[:, 0])
         if i == 0:
             ret = ret.append(pd.Series(index=[date], data=0))
             turnover_dict[date] = 1.0
         if i < len(rebalance_dates) - 1:
             nav_end = df.iloc[:, 1:].multiply(df.iloc[:, 0],
                                               axis=0).add(1).prod(axis=1)
             wgt_end = nav_end / nav_end.sum()
             cannot_sell_stock = self.context.cannot_sell_dict[
                 df.iloc[:, -1].name]
             delist_stock = self.context.delist_stock_dict[df.iloc[:,
                                                                   -1].name]
             delist_stock = set(cannot_sell_stock).intersection(
                 set(delist_stock))
             if len(delist_stock) != 0:
                 cannot_sell_stock = set(cannot_sell_stock) - set(
                     delist_stock)
                 delist_turnover = wgt_end.loc[wgt_end.index.isin(
                     delist_stock)].sum()
             else:
                 delist_turnover = 0
             delist_turnover_dict[date] = delist_turnover
             wgt_cannot_sell = wgt_end.loc[wgt_end.index.isin(
                 cannot_sell_stock)]
             origin_pos = pos_hold[df.iloc[:, -1].name]
             new_pos = (1 - wgt_cannot_sell.sum()) * origin_pos
             new_pos = new_pos.append(wgt_cannot_sell).groupby(
                 level=0).sum()
             pos_hold[df.iloc[:, -1].name] = new_pos
             turnover_rate = pd.merge(
                 wgt_end.to_frame(),
                 new_pos.to_frame(),
                 left_index=True,
                 right_index=True,
                 how='outer').fillna(0).diff(axis=1).abs().sum().iloc[-1]
             ret_list.append(ret)
             turnover_dict[df.iloc[:, -1].name] = turnover_rate
         else:
             ret_list.append(ret)
     res = pd.concat(ret_list, axis=0).sort_index(ascending=True)
     df_turnover = pd.Series(turnover_dict)
     df_delist_turnover = pd.Series(delist_turnover_dict)
     return res, df_turnover, df_delist_turnover
Пример #4
0
 def _get_cannot_sell_dict(self):
     begin_date = ps.shift_n_trading_day(str(self.begin_year) + '0131',
                                         n=-1)
     self._cannot_sell_dict = ps.pickle_read(self._ts_data_path +
                                             'cannot_sell_stock.pkl')
     self._cannot_sell_dict = self._cannot_sell_dict.loc[begin_date:]
     if self.cannot_sell:
         pass
     else:
         for date in self._cannot_sell_dict.index():
             self._cannot_sell_dict[date] = []
Пример #5
0
    def _cal_factor_pos(self, date):
        if self.context.factor_name == 'circ_mv':
            df = self.context.df_factor.loc[date][[
                self.context.factor_name, self.cut_item
            ]].dropna(axis=0, how='any')
            df['bp'] = 1 / df[self.cut_item]
            del df[self.cut_item]
        df['mv_cut'] = pd.qcut(df['circ_mv'], 2, ['small', 'large'])
        df['factor_cut'] = None
        df.loc[df['mv_cut'] == 'small',
               'factor_cut'] = pd.qcut(df.loc[df['mv_cut'] == 'small',
                                              'bp'], [0, 0.3, 0.7, 1],
                                       ['low', 'medium', 'high'])
        df.loc[df['mv_cut'] == 'large',
               'factor_cut'] = pd.qcut(df.loc[df['mv_cut'] == 'large',
                                              'bp'], [0, 0.3, 0.7, 1],
                                       ['low', 'medium', 'high'])
        buy_date = ps.shift_n_trading_day(date, n=-1)
        df = df.loc[list(
            set(df.index.tolist()) -
            set(self.context.cannot_buy_dict[buy_date]))]
        df_large_high = df.query('mv_cut=="large" and factor_cut=="high"')
        df_small_high = df.query('mv_cut=="small" and factor_cut=="high"')
        df_large_low = df.query('mv_cut=="large" and factor_cut=="low"')
        df_small_low = df.query('mv_cut=="small" and factor_cut=="low"')
        df_large_medium = df.query('mv_cut=="large" and factor_cut=="medium"')
        df_small_medium = df.query('mv_cut=="small" and factor_cut=="medium"')

        if self.context.weighted_method == 'eql_weighted':

            def cal_weight(df):
                return pd.Series(index=df.index,
                                 name='eql_weighted').fillna(1 / len(df))

            return cal_weight(df_large_high), cal_weight(
                df_small_high), cal_weight(df_large_low), cal_weight(
                    df_small_low), cal_weight(df_large_medium), cal_weight(
                        df_small_medium)

        if self.context.weighted_method == 'mv_weighted':

            def cal_weight(df):
                return df['circ_mv'] / df['circ_mv'].sum()

            return cal_weight(df_large_high), cal_weight(
                df_small_high), cal_weight(df_large_low), cal_weight(
                    df_small_low), cal_weight(df_large_medium), cal_weight(
                        df_small_medium)
Пример #6
0
 def _get_df_ret_dict(self):
     begin_date = ps.shift_n_trading_day(str(self.begin_year) + '0101', n=1)
     self._df_ret_dict = ps.pickle_read(self._ts_data_path + 'df_ret.pkl')
     self._df_ret_dict = self._df_ret_dict.loc[begin_date:]
Пример #7
0
 def _get_delist_stock_dict(self):
     begin_date = ps.shift_n_trading_day(str(self.begin_year) + '0131',
                                         n=-1)
     self._delist_stock_dict = ps.pickle_read(self._ts_data_path +
                                              'delist_stock.pkl')
     self._delist_stock_dict = self._delist_stock_dict.loc[begin_date:]
Пример #8
0
 def _get_cannot_buy_dict(self):
     begin_date = ps.shift_n_trading_day(str(self.begin_year) + '0101',
                                         n=-1)
     self._cannot_buy_dict = ps.pickle_read(self._ts_data_path +
                                            'cannot_buy_stock.pkl')
     self._cannot_buy_dict = self._cannot_buy_dict.loc[begin_date:]
Пример #9
0
 def _get_pos_hold(self):
     self.mkt_pos = {}
     for month_date in sorted(list(self.context.df_ret_dict.keys())):
         buy_date = ps.shift_n_trading_day(month_date, -1)
         self.mkt_pos[buy_date] = self._cal_factor_pos(month_date)