PLUS会员

张伟_作业

由bqz709ry创建,最终由bqz709ry 被浏览 2 用户

https://bigquant.com/codesharev3/0b31571e-4809-4034-8605-b73b3234f64a

策略设计思路:

一、策略整体思路

多风格策略组合要产生协同的效果,策略之间的风格要有差异性和互补性,并且策略长期向上有收益。因此,我选择了两个策略:1.小市值低换手率策略,这个策略是守田老师上课分享的策略(在守田老师策略基础上剔除了北交所和科创板,避免近期风格对策略带来收益过高的异常)。2.红利低波策略(剔除微盘),这个主要是通过基本面来获取收益,并且剔除市值尾部20%的股票,避免与1的相关性太强。

在风格选择上,主要考虑Barra中的核心因子,且因子长期有一定单调性。最终选择了风格:'BETA','CROWD','DIVYILD','LIQUIDITY','MOMENTUM','RESVOL','SIZE','VALUE',作为基准。

二、小市值低换手率策略构建

1.构建逻辑:

  • 剔除科创板、北交所、ST股、次新股
  • 限制pe大于0
  • 用市值和换手率组合成复合因子选前10股

\

    weight =0.8
    from bigtrader.finance.commission import PerOrder

    # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
    context.sql = f"""
        select
        date,
        instrument,
        pct_rank_by(date,total_market_cap) as score1,
        pct_rank_by(date,turn) as score2,
        {weight}*score1+{1-weight}*score2 as score,
        
        from
        cn_stock_prefactors
        where
        is_risk_warning=0
        and
        list_days>365
        and
        pe_ttm>0
        and
        list_sector<3
    """

2.策略绩效:

策略收益尚可,但是最大回撤较大

3.策略风格

策略的风格主要是小市值、低股息、高beta、高流动性

各因子平均相关性:
BETA_corr         0.437988
LIQUIDITY_corr    0.224644
RESVOL_corr       0.154765
CROWD_corr        0.006127
VALUE_corr        0.005882
MOMENTUM_corr    -0.195275
DIVYILD_corr     -0.274981
SIZE_corr        -0.617573


三、红利低波策略构建

1.构建逻辑:

  • 剔除科创板、北交所、ST股、次新股
  • 限制pe大于0、股息率大于0,剔除市值最低的20%
  • 用股息率排名和成交量的波动率做复合因子,投资股息率高、成交量波动率小的股票
    weight =0.6
    from bigtrader.finance.commission import PerOrder

    # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
    context.sql = f"""
        select
        date,
        instrument,
        pct_rank_by(date,total_market_cap) as market_cap_rank,
        pct_rank_by(date,m_stddev(amount,20)) as amount_vol_rank,
        pct_rank_by(date,dividend_yield_ratio) as dv_rank,
        -{weight}*dv_rank+{1-weight}*amount_vol_rank as score,
        
        from
        cn_stock_prefactors
        where
        is_risk_warning=0
        and
        list_days>365
        and
        pe_ttm>0
        and
        list_sector<3
        and dividend_yield_ratio >0
    """
    context.data =  dai.query(context.sql,filters={'date':[context.start_date,context.end_date]}).df().dropna()
    context.data = context.data[context.data['market_cap_rank']>0.8]

2.策略绩效:

策略收益一般,最大回撤16%,尚可

3.策略风格

策略在市值上呈中性,并明显偏向于价值股,与策略1在风格上明显不同,而且具有一定的互补性

各因子平均相关性:
VALUE_corr        0.361654
BETA_corr         0.166647
LIQUIDITY_corr    0.022261
RESVOL_corr       0.002853
DIVYILD_corr     -0.011865
CROWD_corr       -0.040538
SIZE_corr        -0.077843
MOMENTUM_corr    -0.178057

四、组合轮动策略构建

1.构建逻辑

  1. 每个策略的因子风格,用120窗口滚动计算,从一个较长的周期计算一个稳定的风格。
  2. 在每日选取策略时,考虑5日窗口风格因子的累乘收益,使用较短的时间窗口,快速捕捉风格的变化
  3. 在调仓日用策略在各个风格的相关系数乘步骤2.风格收益后,加和形成策略的收益
  4. 选择收益高的策略来作为调仓使用的策略。(步骤2-步骤3的代码如下)
    context.sql ='select * from strategy_style'
    context.style_data =  dai.query(context.sql,filters={"date": [start_date, end_date]}).df().dropna()
    # 1. 预处理因子收益率数据 (df_cerm_factor_return)
    # 计算滚动5日收益率 - 使用累计收益率而非平均值
    def calculate_rolling_5d_return(df, columns):
        # 复制数据避免修改原始数据
        df = df.copy()
        for col in columns:
            # 计算5日累计收益率 (1+return1)*(1+return2)*...*(1+return5)-1
            df[col + '_5d'] = (1 + df[col]).rolling(5).apply(np.prod, raw=True) - 1
        return df

    # 因子列名(排除日期列)
    factor_columns = [col for col in df_cerm_factor_return.columns if col != 'date']
    # 计算5日滚动收益率
    df_factor = calculate_rolling_5d_return(df_cerm_factor_return, factor_columns)

    # 2. 预处理策略相关数据 (context.style_data)
    # 选择所需列并重命名
    strategy_df = context.style_data[['date', 'instrument'] + 
                                    [col for col in context.style_data.columns if col.endswith('_corr')]].copy()

    # 3. 合并数据并计算策略预期收益
    merged_df = pd.merge(strategy_df, df_factor, on='date', how='inner')

    # 计算每个策略的预期收益 = ∑(因子相关系数 × 因子5日收益率)
    for factor in factor_columns:
        merged_df[factor + '_score'] = merged_df[factor + '_5d'] * merged_df[factor + '_corr']

    # 计算每个策略的总分
    merged_df['total_score'] = merged_df[[col for col in merged_df.columns if col.endswith('_score')]].sum(axis=1)

    # 4. 选择每日最佳策略
    # 找出每日得分最高的策略
    best_strategy_df = merged_df.loc[merged_df.groupby('date')['total_score'].idxmax()]
    best_strategy_df = best_strategy_df[['date', 'instrument', 'total_score']]

    # 5. 创建最终的投资决策数据框架
    # 包含每日应选择的策略
    context.investment_decision = best_strategy_df[['date', 'instrument']].copy()
    context.investment_decision.columns = ['date', 'selected_strategy']

2.策略绩效

策略的绩效是不错的,年化收益率基本与小市值一致,但是最大回撤降低了一多半。会非常适合实盘。

五、策略的问题

1.策略的收益主要来源于小市值,在回撤时用低波红利策略做了缓冲。在A股市场缺少更具弹性的龙头股策略,如果能够有合适的游资龙头股策略轮动,策略的收益会更高

2在24年上半年熊市期,策略仍然有较高的回撤,是否有合适的策略能够应对这个时间段

3.在代码实现上,没有完全按照万老师框架那么优雅,很多我硬编码在代码中,后续再优化

标签

基本面分析市值管理风险控制
{link}