Ejemplo n.º 1
0
def out_sample_perf(pnl_df_out, way=1, cut_point_list=None):
    # 根据sharpe大小,统计样本外的表现
    if cut_point_list is None:
        cut_point_list = [0.30]
    if way == 1:
        rolling_sharpe, cut_sharpe = \
            bt.AZ_Rolling_sharpe(pnl_df_out, roll_year=0.5, year_len=250, cut_point_list=cut_point_list, output=True)
    else:
        rolling_sharpe, cut_sharpe = \
            bt.AZ_Rolling_sharpe(-pnl_df_out, roll_year=0.5, year_len=250, cut_point_list=cut_point_list, output=True)

    sharpe_quantile = cut_sharpe.values[0]
    out_condition = sharpe_quantile > 0.8
    return out_condition, round(sharpe_quantile * way, 4)
Ejemplo n.º 2
0
def filter_all(cut_date,
               pos_df_daily,
               pct_n,
               if_return_pnl=False,
               if_only_long=False):
    if if_only_long:
        pnl_df = (pos_df_daily[pos_df_daily > 0] * pct_n).sum(axis=1)
        pnl_df = pnl_df.replace(np.nan, 0)
    else:
        pnl_df = (pos_df_daily * pct_n).sum(axis=1)
        pnl_df = pnl_df.replace(np.nan, 0)
    # pnl_df = pd.Series(pnl_df)
    # 样本内表现
    return_in = pct_n[pct_n.index < cut_date]

    pnl_df_in = pnl_df[pnl_df.index < cut_date]
    asset_df_in = pnl_df_in.cumsum()
    last_asset_in = asset_df_in.iloc[-1]
    pos_df_daily_in = pos_df_daily[pos_df_daily.index < cut_date]
    pot_in = AZ_Pot(pos_df_daily_in, last_asset_in)

    leve_ratio = AZ_Leverage_ratio(asset_df_in)
    if leve_ratio < 0:
        leve_ratio = 100
    sharpe_q_in_df = bt.AZ_Rolling_sharpe(pnl_df_in,
                                          roll_year=1,
                                          year_len=250,
                                          min_periods=1,
                                          cut_point_list=[0.3, 0.5, 0.7],
                                          output=False)
    sp_in = bt.AZ_Sharpe_y(pnl_df_in)
    fit_ratio = bt.AZ_fit_ratio(pos_df_daily_in, return_in)
    ic = round(
        bt.AZ_Normal_IC(pos_df_daily_in, pct_n, min_valids=None, lag=0).mean(),
        6)
    sharpe_q_in_df_u, sharpe_q_in_df_m, sharpe_q_in_df_d = sharpe_q_in_df.values
    in_condition_u = sharpe_q_in_df_u > 0.9 and leve_ratio > 1
    in_condition_d = sharpe_q_in_df_d < -0.9 and leve_ratio > 1
    # 分双边和只做多
    if if_only_long:
        in_condition = in_condition_u
    else:
        in_condition = in_condition_u | in_condition_d

    if sharpe_q_in_df_m > 0:
        way = 1
    else:
        way = -1

    # 样本外表现
    pnl_df_out = pnl_df[pnl_df.index >= cut_date]
    out_condition, sharpe_q_out = out_sample_perf_c(pnl_df_out, way=way)
    if if_return_pnl:
        return in_condition, out_condition, ic, sharpe_q_in_df_u, sharpe_q_in_df_m, sharpe_q_in_df_d, pot_in, \
               fit_ratio, leve_ratio, sp_in, sharpe_q_out, pnl_df
    else:
        return in_condition, out_condition, ic, sharpe_q_in_df_u, sharpe_q_in_df_m, sharpe_q_in_df_d, pot_in, \
               fit_ratio, leve_ratio, sp_in, sharpe_q_out
Ejemplo n.º 3
0
def filter_pot_sharpe(cut_date,
                      signal,
                      pct_n,
                      index_df,
                      lag=1,
                      hold_time=5,
                      if_hedge=True,
                      hedge_ratio=1,
                      if_return_pnl=False):
    # signal向下移动一天,避免未来函数
    signal = signal.shift(lag)
    # # 将所有的0替换为nan,使得计算ic时更加合理, 计算pnl时没影响
    # signal = signal.replace(0, np.nan)
    pos_df_daily = pos_daily_fun(signal, n=hold_time)

    if if_hedge:
        hedge_df = hedge_ratio * index_df.mul(pos_df_daily.sum(axis=1), axis=0)
        # pnl_df = (signal * pct_n).sum(axis=1).sub(hedge_df, axis=0)
        pnl_df = -hedge_df.sub((pos_df_daily * pct_n).sum(axis=1), axis=0)
        pnl_df = pnl_df[pnl_df.columns[0]]
    else:
        pnl_df = (pos_df_daily * pct_n).sum(axis=1)
    # pnl_df = pd.Series(pnl_df)
    # 样本内表现
    pnl_df_in = pnl_df[pnl_df.index < cut_date]
    asset_df_in = pnl_df_in.cumsum()
    last_asset_in = asset_df_in.iloc[-1]
    pos_df_daily_in = pos_df_daily[pos_df_daily.index < cut_date]
    pot = AZ_Pot(pos_df_daily_in, last_asset_in)

    sharpe_q_in_df = bt.AZ_Rolling_sharpe(pnl_df_in,
                                          roll_year=1,
                                          year_len=250,
                                          min_periods=1,
                                          cut_point_list=[0.3, 0.5, 0.7],
                                          output=False)

    sharpe_q_in_df_u, sharpe_q_in_df_m, sharpe_q_in_df_d = sharpe_q_in_df.values
    in_condition_u = sharpe_q_in_df_u > 0.9
    in_condition_d = sharpe_q_in_df_d < -0.9
    in_condition = in_condition_u | in_condition_d
    if sharpe_q_in_df_m > 0:
        way = 1
    else:
        way = -1

    # 样本外表现
    pnl_df_out = pnl_df[pnl_df.index >= cut_date]
    out_condition, sharpe_q_out = out_sample_perf(pnl_df_out, way=way)
    if if_return_pnl:
        return in_condition, out_condition, sharpe_q_in_df_u, sharpe_q_in_df_m, sharpe_q_in_df_d, pot, sharpe_q_out, \
               pnl_df
    else:
        return in_condition, out_condition, sharpe_q_in_df_u, sharpe_q_in_df_m, sharpe_q_in_df_d, pot, sharpe_q_out
Ejemplo n.º 4
0
def filter_time_para_fun(time_para_dict, pos_df_daily, adj_return,
                         if_return_pnl, if_only_long):
    if if_only_long:
        pnl_df = (pos_df_daily[pos_df_daily > 0] * adj_return).sum(axis=1)
        pnl_df = pnl_df.replace(np.nan, 0)
    else:
        pnl_df = (pos_df_daily * adj_return).sum(axis=1)
        pnl_df = pnl_df.replace(np.nan, 0)
    result_dict = OrderedDict()
    for time_key in time_para_dict.keys():
        begin_para, cut_para, end_para_1, end_para_2, end_para_3, end_para_4 = time_para_dict[
            time_key]

        # 样本内索引
        sample_in_index = (adj_return.index >= begin_para) & (adj_return.index
                                                              < cut_para)
        # 样本外索引
        sample_out_index_1 = (adj_return.index >= cut_para) & (adj_return.index
                                                               < end_para_1)
        sample_out_index_2 = (adj_return.index >= cut_para) & (adj_return.index
                                                               < end_para_2)
        sample_out_index_3 = (adj_return.index >= cut_para) & (adj_return.index
                                                               < end_para_3)
        sample_out_index_4 = (adj_return.index >= cut_para) & (adj_return.index
                                                               < end_para_4)
        # 样本内表现
        pos_df_daily_in = pos_df_daily[sample_in_index]
        if len(pos_df_daily_in.abs().sum(axis=1).replace(
                0, np.nan).dropna()) / len(pos_df_daily_in) < 0.1:
            continue
        adj_return_in = adj_return[sample_in_index]
        pnl_df_in = pnl_df[sample_in_index]

        asset_df_in = pnl_df_in.cumsum()
        last_asset_in = asset_df_in.iloc[-1]

        pot_in = AZ_Pot(pos_df_daily_in, last_asset_in)

        leve_ratio = AZ_Leverage_ratio(asset_df_in)

        if leve_ratio < 0:
            leve_ratio = 100
        sharpe_q_in_df = bt.AZ_Rolling_sharpe(pnl_df_in,
                                              roll_year=1,
                                              year_len=250,
                                              min_periods=1,
                                              cut_point_list=[0.3, 0.5, 0.7],
                                              output=False)
        sharpe_q_in_df = round(sharpe_q_in_df, 4)
        sp_in = bt.AZ_Sharpe_y(pnl_df_in)
        fit_ratio = bt.AZ_fit_ratio(pos_df_daily_in, adj_return_in)

        ic = round(
            bt.AZ_Normal_IC(pos_df_daily_in,
                            adj_return_in,
                            min_valids=None,
                            lag=0).mean(), 6)
        sp_in_u, sp_in_m, sp_in_d = sharpe_q_in_df.values

        in_condition_u = sp_in_u > 0.9 and leve_ratio > 1
        in_condition_d = sp_in_d < -0.9 and leve_ratio > 1
        # 分双边和只做多
        if if_only_long:
            in_condition = in_condition_u
        else:
            in_condition = in_condition_u | in_condition_d

        if sp_in_m > 0:
            way = 1
        else:
            way = -1

        # 样本外表现
        pnl_df_out_1 = pnl_df[sample_out_index_1]
        pnl_df_out_2 = pnl_df[sample_out_index_2]
        pnl_df_out_3 = pnl_df[sample_out_index_3]
        pnl_df_out_4 = pnl_df[sample_out_index_4]

        out_condition_1, sp_out_1 = out_sample_perf_c(pnl_df_out_1, way=way)
        out_condition_2, sp_out_2 = out_sample_perf_c(pnl_df_out_2, way=way)
        out_condition_3, sp_out_3 = out_sample_perf_c(pnl_df_out_3, way=way)
        out_condition_4, sp_out_4 = out_sample_perf_c(pnl_df_out_4, way=way)
        if if_return_pnl:
            result_dict[time_key] = [
                in_condition, out_condition_1, out_condition_2,
                out_condition_3, out_condition_4, ic, sp_in_u, sp_in_m,
                sp_in_d, pot_in, fit_ratio, leve_ratio, sp_in, sp_out_1,
                sp_out_2, sp_out_3, sp_out_4, pnl_df
            ]
        else:
            result_dict[time_key] = [
                in_condition, out_condition_1, out_condition_2,
                out_condition_3, out_condition_4, ic, sp_in_u, sp_in_m,
                sp_in_d, pot_in, fit_ratio, leve_ratio, sp_in, sp_out_1,
                sp_out_2, sp_out_3, sp_out_4
            ]
    return result_dict