第三章:宏观状态识别——用PMI、CPI、利率判断市场状态

说实话,做因子投资最怕什么?

不是因子失效,而是你根本不知道它为什么失效。

我见过太多人,拿着回测漂亮的因子冲进市场,结果三个月就被打得鼻青脸肿。为什么?因为市场状态变了,而你的因子还停留在牛市思维里。

这一章,我们就聊聊怎么用宏观经济指标来判断市场状态。说白了,就是给因子择时找个宏观背景板。

3.1 为什么宏观状态对因子择时这么重要?

先讲个我自己的经历。

2018年,我管理的一个多因子策略突然连续回撤。回测里明明很稳健的估值因子,怎么就不灵了?我翻来覆去查代码,查数据,最后发现——那年是典型的“紧信用+去杠杆”环境,市场对高估值股票极度厌恶,但我的估值因子用的是静态PE,根本没考虑宏观环境。

嗯,从那以后,我再也不敢忽略宏观状态了。

宏观状态对因子的影响,其实可以归纳为三点:

  • 因子收益的周期性:比如动量因子在牛市中表现好,在熊市中容易崩盘
  • 因子风险的聚集性:经济衰退时,低质量因子的风险会集中爆发
  • 因子之间的相关性:不同宏观状态下,因子间的相关性会剧烈变化

核心观点:因子择时不是预测未来,而是识别当前状态,然后选择最适配的因子。

3.2 三个核心宏观指标:PMI、CPI、利率

宏观指标那么多,为什么我偏偏选这三个?

你想想看,一个经济体无非就三个维度:增长通胀货币环境。PMI代表增长,CPI代表通胀,利率代表货币环境。三个指标基本能勾勒出宏观全貌。

3.2.1 PMI(采购经理人指数)

PMI是经济的“体温计”。高于50说明经济在扩张,低于50说明在收缩。

我个人习惯用PMI的三个月移动平均来平滑噪音。为什么?因为单月PMI波动太大,经常被季节性因素干扰。平滑后,趋势更清晰。

PMI状态 经济含义 因子偏好
> 52 强劲扩张 动量、成长因子
48 - 52 温和增长 价值、质量因子
< 48 收缩/衰退 低波、防御因子

3.2.2 CPI(消费者物价指数)

CPI反映通胀压力。通胀高的时候,市场会预期加息,这对很多因子都是利空。

我在项目中遇到过一个问题:CPI同比数据波动太大,直接用来做信号会频繁切换。后来我改用CPI的环比折年率,加上三个月平滑,效果好了很多。

小技巧:CPI数据发布有滞后性,建议用市场预期的CPI(比如彭博调查值)代替实际值。预期数据更能反映市场定价。

3.2.3 利率(政策利率或10年期国债收益率)

利率是资金的“价格”。低利率环境有利于成长股,高利率环境有利于价值股。

这里要注意:利率的变化方向比利率的绝对水平更重要。我曾经犯过这个错——只看利率绝对值,结果在利率下降周期里配置了价值因子,亏得挺惨。

3.3 宏观状态分类:一个简单的四象限框架

把PMI和利率结合起来,我们可以构建一个四象限框架。这是我个人最常用的方法。

PMI(经济增长) 利率(货币环境) 复苏 高PMI + 低利率 偏好:动量、成长 过热 高PMI + 高利率 偏好:价值、商品 衰退 低PMI + 低利率 偏好:低波、质量 滞胀 低PMI + 高利率 偏好:防御、现金

这个框架虽然简单,但非常实用。我每次做因子配置前,都会先看看当前落在哪个象限。

3.4 实战:用Python实现宏观状态识别

光说不练假把式。下面是我实际项目中用的一段代码,用来识别宏观状态。

import pandas as pd
import numpy as np

def identify_macro_state(pmi, cpi, rate):
    """
    识别宏观状态
    pmi: 最新PMI值
    cpi: 最新CPI同比
    rate: 最新政策利率
    """
    # 定义阈值(可根据历史分位数调整)
    pmi_threshold = 50
    cpi_threshold = 3.0  # 3%通胀警戒线
    rate_threshold = 2.5  # 中性利率估计
    
    # 判断增长状态
    growth = '扩张' if pmi > pmi_threshold else '收缩'
    
    # 判断通胀状态
    inflation = '高通胀' if cpi > cpi_threshold else '低通胀'
    
    # 判断货币环境
    monetary = '紧缩' if rate > rate_threshold else '宽松'
    
    # 综合判断
    if growth == '扩张' and monetary == '宽松':
        state = '复苏'
    elif growth == '扩张' and monetary == '紧缩':
        state = '过热'
    elif growth == '收缩' and monetary == '宽松':
        state = '衰退'
    else:
        state = '滞胀'
    
    return {
        'state': state,
        'growth': growth,
        'inflation': inflation,
        'monetary': monetary
    }

# 示例:2023年Q4数据
result = identify_macro_state(pmi=49.5, cpi=2.8, rate=3.0)
print(f"当前宏观状态:{result['state']}")
# 输出:当前宏观状态:滞胀

注意:阈值不是固定的。我建议每季度重新计算一次阈值,用过去5年的历史分位数来动态调整。固定阈值在结构性变化的市场里会失效。

3.5 宏观状态与因子择时的联动

识别出宏观状态后,怎么用它来指导因子配置?

我的做法是:建立一个状态-因子映射表,每个状态对应一组偏好因子。

宏观状态 偏好因子 规避因子 配置权重调整
复苏 动量、成长、小盘 低波、防御 动量+20%,低波-10%
过热 价值、商品、通胀对冲 成长、长久期 价值+15%,成长-15%
衰退 低波、质量、国债 动量、小盘 低波+25%,动量-20%
滞胀 防御、现金、商品 几乎所有权益因子 现金+30%,权益-30%

这里有个坑:状态切换有滞后性。我曾经在2020年3月,PMI刚跌破50就切换到衰退配置,结果错过了随后的大反弹。后来我加了两个规则:

  • 状态确认需要连续两个月的数据支持
  • 切换时采用渐进式调整,而不是一步到位

3.6 进阶:用宏观因子做状态概率估计

如果你觉得硬分类太粗糙,可以试试概率化方法。

我个人喜欢用逻辑回归朴素贝叶斯来估计每个状态的概率。这样配置因子时,可以按概率加权,而不是非黑即白。

from sklearn.linear_model import LogisticRegression

# 假设我们有历史数据
X = historical_macro_data  # PMI, CPI, 利率等
y = historical_states      # 0=复苏, 1=过热, 2=衰退, 3=滞胀

model = LogisticRegression(multi_class='multinomial')
model.fit(X, y)

# 预测当前状态概率
current_data = [[49.5, 2.8, 3.0]]
probs = model.predict_proba(current_data)[0]

state_names = ['复苏', '过热', '衰退', '滞胀']
for name, prob in zip(state_names, probs):
    print(f"{name}: {prob:.2%}")
# 输出示例:
# 复苏: 12.3%
# 过热: 8.7%
# 衰退: 35.6%
# 滞胀: 43.4%

有了概率,因子配置就变成了一个优化问题:目标权重 = sum(状态概率 * 该状态下的因子权重)。这样切换更平滑,回撤也更小。

3.7 避坑指南

最后,分享几个我踩过的坑:

  • 不要过度拟合:宏观指标就那么几个,别想着用20个变量做回归。我见过有人用30个宏观指标做因子择时,结果样本外一塌糊涂。
  • 注意数据频率:PMI是月度数据,CPI也是月度,利率可以日度。做状态识别时,统一用月度频率,别混用。
  • 宏观状态不是万能的:它只能提供背景,不能替代因子本身的质量。烂因子在什么宏观状态下都是烂因子。

我的习惯:每周末花10分钟,看看最新的PMI、CPI和利率数据,判断当前状态。然后检查因子组合是否需要微调。这个习惯坚持了5年,帮我躲过了好几次大回撤。

宏观状态识别,说白了就是给因子择时找个“天气预报”。有了它,你至少知道今天是晴天还是雨天,该带伞还是该涂防晒霜。至于具体怎么走,那是下一章的事了。


公众号:蓝海资料掘金营,微信deep3321