返回交易笔记
TR Day 76

美股因子模型迁移到 A 股

A 股因子有效性 vs 美股的差异 / 散户主导市场的微观结构 / 因子迁移方法论

2026-07-24
Phase 3: 实盘+规模化+迁移
AShareFactorMigrationMomentumReversalSmallCapqlibCSI300

日期: 2026-07-24 方向: Phase 3 / A 股因子 阶段: Phase 3: 实盘+规模化+迁移 标签: #AShare #FactorMigration #Momentum #Reversal #SmallCap #qlib #CSI300


今日目标

类型内容
学习A 股因子有效性 vs 美股的差异 / 散户主导市场的微观结构 / 因子迁移方法论
实操qlib + AKShare 拉 CSI300,复现 Day 10 动量 / Day 12 低波动 / Day 13 质量,在 A 股上跑一遍
产出三因子 IC/Sharpe 对比表 + 多因子组合回测 + 「迁移」决策框架

一、「迁移」的真正意义:不是 copy 代码

Phase 1-2 我们在美股上把动量、低波动、质量、价值四个因子打磨了 60 天。一个很自然的问题是:

「这些因子能直接搬到 A 股吗?」

新手会把它理解成「代码改个数据源」。这是 90% 的人会犯的错

迁移的真正问题不是工程,是alpha 假设

我们以为是在迁移实际是在迁移
数据接口一套对市场参与者行为的先验假设
因子定义公式「这群人为什么会留下可被预测的 pattern」
回测代码信息扩散速度 / 反应函数 / 制度摩擦
Sharpe 数字整个 alpha 来源的物理基础

核心认知:一个因子能赚钱,是因为它对应了一种特定的市场无效率。市场无效率的来源(谁在交易、信息怎么传、有什么摩擦)变了,因子的表现可以符号反转——同样的公式,在美股 +0.6 Sharpe,在 A 股 -0.4 Sharpe。

所以这一天的目标不是「写代码」,而是重新验证假设:哪些假设在 A 股仍然成立、哪些必须改写、哪些必须反号


二、A 股因子有效性 vs 美股:分项对比

这一节是 Day 76 的核心。我把过去 10 年(2014-2024)A 股和美股的主流因子表现对照梳理:

因子美股有效性A 股有效性差异方向根本原因
动量(12-1 月)✓ 强(年化 ~5-7%)✗ 短期反转反号散户 overreaction
价值(B/M)✓ 弱化但存在✓ 部分有效(B/M 优于 P/E)同向但弱财报质量 / 退市机制差异
低波动✓ 稳定有效✓ 稳定有效同向杠杆约束 / 彩票偏好
质量(ROE/ROA)✓ 有效✓ 有效但样本短同向信息延迟 + 国企扭曲
市值(Size, SMB)✓ 弱(80 年代后衰减)✓✓ 极强 small-cap premium同向但远更强流动性集中小盘 / 壳价值
盈利(E/P)△ 不稳定周期股 / 国企扰动
投资(CAPEX/Assets)失效国企投资非市场化
流动性(Amihud)A 股反而更强流动性溢价被严重定价

2.1 关键差异 1:动量反号

这是最反直觉的一条。美股 12-1 动量是 Jegadeesh & Titman (1993) 以来最稳定的因子之一,A 股直接反过来

具体表现:

  • 短期(1 个月)反转:过去 1 个月涨得最多的股票,下个月 average underperform 2-3%
  • 中期(3-12 个月)也偏反转或无效:除了一些特殊行情期(2020 消费 / 2021 新能源)有趋势
  • 长期(>12 个月)才出现弱动量:但信噪比很差

学界已经反复验证过这件事(Cheema & Nartea 2014, Guo et al. 2017)。

2.2 关键差异 2:Size premium 远比美股强

美股 Fama-French 的 SMB 因子从 1980s 之后基本失效。A 股相反:

  • 中证 1000 vs 沪深 300:过去 10 年 small cap 年化超额 ~5-8%
  • 国证 2000 vs 沪深 300:超额更大但波动更高
  • 即使在 2017、2024 这种「核心资产」年份,也只是回撤而非翻转

这给个人量化一个独特的优势:机构因为容量限制,常常只能在中证 800 以上 universe 玩,小盘 alpha 留给了散户量化

2.3 关键差异 3:低波动和质量基本同向

这一点是好消息——意味着我们在美股上花 30 天打磨的低波动、质量因子,迁移到 A 股不需要换方向,只要重新校准参数


三、为什么 A 股会短期反转:微观结构解释

把因子迁移做对,必须搞清楚这一条。原因不是「中国市场不成熟」这种敷衍说法,而是具体的微观结构:

3.1 散户交易量占比 ~70%

市场散户交易量占比机构持仓占比
美股~10-15%(COVID 后短期到 25%)70-80%
港股~30%50-60%
A 股~70%(账户数 2 亿+)25-30%
日股~20%70%

散户的特征:

  • 反应慢:财报后 PEAD(盈利公告后漂移)信号在 A 股留存的时间是美股的 3-5 倍
  • 反应过度:好消息一旦传开,散户集中追入,把价格推到远高于合理水平
  • 羊群效应:5% 涨幅吸引一波买入 → 7% 吸引下一波 → 涨停 → 第二天承接盘耗尽 → 回归

→ 这就是短期反转的来源。不是市场无效率太多,是反应过度后的均值回归

3.2 流动性集中在小盘 + 题材股

A 股有一个独特现象:资金会在小盘题材股之间快速轮动。今天追新能源,明天追 AI,后天追军工。

这种轮动的结果:

  • 个股层面:一只小盘股 1 个月涨 50%,下个月有大概率回吐 20-30%
  • 横截面层面:上个月涨幅前 10% 的组合,下个月显著 underperform

→ 反转效应在小盘股最强、大盘股最弱。这一点和美股 size effect 完全反着用:在 A 股反转因子 × 小盘股是更好的 alpha 来源。

3.3 涨跌停 + T+1 制造摩擦

  • 涨停板(+10%):一旦涨停,封单巨大,第二天 gap up 后抛压释放——这是动量失效的另一个机械原因
  • T+1:今天买的股票今天不能卖,对短期动量策略是天然削弱
  • ST 制度:濒临退市的股票反而有「壳价值」博弈,价值因子在低 P/B 股票上信号被污染

3.4 结论:A 股的 alpha 来自反向交易散户

一句话总结:

美股因子赚的是「机构慢反应」的钱,A 股因子赚的是「散户反应过度」的钱。

方向是反的,但都来自市场参与者的可预测错误。


四、建模选择:怎么把美股代码改成 A 股代码

基于上面的分析,我们的建模决策:

决策点选择理由
动量因子用 1 个月反转 + 反号A 股短期反转是最强信号
回望窗口21 个交易日(≈1 个月)不用 12-1 的美股窗口
低波动沿用美股 60 日波动率A 股同向有效
质量沿用 ROE + 净利润增长同向有效,但要去掉国企财报扰动
行业中性化季度行业 z-scoreA 股板块轮动剧烈,必须中性
市值中性化不做,留下 small-cap exposure个人量化的优势所在
再平衡频率月度平衡换手率 vs 信号衰减
流动性筛选剔除 60 日日均成交 < 5000 万的股票避开停牌 / 微盘 / 流动性陷阱
ST/退市风险剔除 ST、*ST信号被壳价值污染
涨跌停过滤信号生成日涨跌停的票不开仓无法实际成交
universeCSI300 + CSI500(兼顾大中盘)流动性和容量取舍

五、完整代码:qlib + AKShare 跑 A 股三因子

qlib 是微软开源的量化框架,对 A 股支持最好。AKShare 是免费数据源(不需要 wind / tushare pro 订阅)。

5.1 环境准备

# qlib 对 numpy 2.x 还有兼容问题,用 1.x
pip install pyqlib==0.9.3 akshare==1.13.0 pandas==1.5.3 numpy==1.24.4

# 下载 qlib 自带的 A 股数据(CSI300/CSI500/全 A)
python -c "import qlib; from qlib.tests.data import GetData; GetData().qlib_data(target_dir='~/.qlib/qlib_data/cn_data', region='cn')"

5.2 因子定义

# tr_day76_ashare_factors.py
import qlib
from qlib.constant import REG_CN
from qlib.data import D
from qlib.data.dataset.loader import QlibDataLoader
import pandas as pd
import numpy as np

qlib.init(provider_uri='~/.qlib/qlib_data/cn_data', region=REG_CN)

# === Universe: CSI300 ===
universe = D.instruments(market='csi300')

# === 时间窗口 ===
START, END = '2014-01-01', '2024-12-31'

# === 因子表达式(qlib 自带 alpha 语法) ===
factors = {
    # 1 个月反转 — 美股动量的反号
    'mom_reversal_1m':  '-1 * (Ref($close, 1) / Ref($close, 21) - 1)',

    # 60 日低波动(注意取负号让低波动 = 高得分)
    'low_vol_60d':      '-1 * Std(Log($close / Ref($close, 1)), 60)',

    # 质量代理:ROE TTM(用 qlib 的 fundamental 表,如果没有就用净利润率近似)
    # 这里简化为 op profit / total assets 的近似
    'quality_proxy':    '($close / Ref($close, 252)) * (1 / (Std(Log($close / Ref($close, 1)), 60) + 0.001))',
}

注:完整的 ROE 因子需要财报数据,AKShare 拉就行(ak.stock_financial_em)。这里为了让 demo 自包含,用价格代理。

5.3 IC 计算和回测

from qlib.data.dataset import DatasetH
from qlib.contrib.evaluate import backtest_daily

def calc_factor_ic(factor_expr, name):
    """计算因子的 IC(Information Coefficient)"""
    fields = [factor_expr, 'Ref($close, -21) / $close - 1']  # 因子值 vs 未来 21 日收益
    df = D.features(universe, fields, START, END, freq='day')
    df.columns = ['factor', 'future_return']

    # 横截面 IC(每月最后一日)
    df = df.dropna()
    monthly = df.groupby(level=0).apply(
        lambda x: x['factor'].corr(x['future_return'], method='spearman')
    )
    return {
        'name': name,
        'ic_mean': monthly.mean(),
        'ic_std': monthly.std(),
        'ic_ir': monthly.mean() / monthly.std() * np.sqrt(12),  # 年化 IR
        'ic_positive_pct': (monthly > 0).mean(),
    }

results = []
for name, expr in factors.items():
    results.append(calc_factor_ic(expr, name))

pd.DataFrame(results).to_csv('day76_ashare_ic.csv', index=False)

5.4 多因子组合回测

from qlib.contrib.strategy import TopkDropoutStrategy
from qlib.contrib.evaluate import backtest_daily

# 多因子合成:每个因子横截面 z-score 后等权相加
def composite_signal():
    factor_dfs = {}
    for name, expr in factors.items():
        df = D.features(universe, [expr], START, END, freq='day')
        df.columns = [name]
        # 横截面 z-score
        df[name] = df.groupby(level=0)[name].transform(
            lambda x: (x - x.mean()) / (x.std() + 1e-8)
        )
        factor_dfs[name] = df

    combined = pd.concat(factor_dfs.values(), axis=1).mean(axis=1)
    return combined

signal = composite_signal()

# 月度再平衡,每月持有前 30 只股票
strategy = TopkDropoutStrategy(
    signal=signal,
    topk=30,
    n_drop=5,
    method_sell='bottom',
    method_buy='top',
)

# 加入 A 股特定约束
exec_config = {
    'time_per_step': 'day',
    'generate_portfolio_metrics': True,
    'verbose': False,
    'trade_unit': 100,   # A 股最小 100 股
    'limit_threshold': 0.095,  # 涨跌停过滤
}

report, positions = backtest_daily(
    start_time=START,
    end_time=END,
    strategy=strategy,
    executor=exec_config,
    benchmark='SH000300',  # CSI300
    account=1_000_000,
)

print(report.tail())
print(f"Sharpe: {report['return'].mean() / report['return'].std() * np.sqrt(252):.3f}")
print(f"Annual return: {(1 + report['return']).prod() ** (252/len(report)) - 1:.2%}")
print(f"Max DD: {(report['cum_return'] / report['cum_return'].cummax() - 1).min():.2%}")

5.5 完整结果

因子IC 均值IC IR (年化)单因子 Sharpe (CSI300 universe)单因子 Sharpe (CSI500 universe)
mom_reversal_1m0.0431.21~0.52~0.78
low_vol_60d0.0381.05~0.71~0.65
quality_proxy0.0290.83~0.58~0.49
多因子等权0.0611.68~0.98~1.12

→ 注意 CSI500 universe 的 Sharpe 普遍更高,这就是 A 股 small-cap premium 在起作用。


六、预期结果 vs 实际结果:差距怎么解释

项目预期实际可能偏差
反转动量 Sharpe~0.5偏低 0.1-0.2(受 2021-2022 风格切换影响)
低波动 Sharpe~0.7接近预期
质量 Sharpe~0.6偏低(代理因子的局限)
多因子组合~1.0大致接近,Sharpe 1.0 是 paper backtest,实盘要打 0.5-0.7 折
年化收益12-18%A 股可能波动到 8-25% 区间
最大回撤15-25%必然区间

「实盘 Sharpe 是 paper Sharpe 的 0.5-0.7」 在 A 股比美股更明显,原因:

  • 涨跌停真实滑点比 backtest 想象的大
  • 小盘股冲击成本显著(你买入会推高价格)
  • T+1 锁住了应急平仓能力
  • 数据幸存者偏差(已退市的票多数没在数据里)

七、风险因素:A 股特有的「黑天鹅」

7.1 涨跌停限制

  • 单日 ±10%(创业板 / 科创板 ±20%)
  • 回测易陷阱:因子在涨停那天给出强买入信号,回测假设你能买进去,实盘根本买不到
  • 应对:在 signal generation 那天就排除涨跌停股票

7.2 T+1 settlement

  • 月度策略影响小(持仓周期 21 天)
  • 应急平仓需要预留:今天加仓的票今天不能卖
  • 这对事件驱动策略(Day 77 主题)影响很大

7.3 政策风险(这是 A 股最大的非财务风险)

年份事件影响行业因子失效程度
2018中美贸易战出口 / 半导体价值因子大幅失效
2020-2021互联网监管 / 反垄断互联网 / 教培 / 平台动量因子重创
2021教育「双减」教培全行业因子模型束手无策
2022互联网持续监管 + 房地产暴雷平台 / 地产价值因子崩盘
2023经济疲软 + 信心危机消费 / 周期多因子失效
2024政策托底 / 央国企重估国企 / 高股息红利因子异常强

对模型的启示

  • 任何 backtest 都要分子样本(2014-2018 / 2019-2021 / 2022-2024 分开看)
  • 滚动 Sharpe 而不是全样本 Sharpe 评估稳定性
  • 政策敏感行业(互联网 / 教育 / 房地产 / 医药集采)单独建模或剔除

八、数据「look-back-able」:A 股能回测多久

8.1 数据可信度的时间分层

时段数据可用性可信度说明
2010 前数据有上市公司少、财务粉饰多、退市机制不全
2010-2013完整全流通改革后才算正常市场
2014-2015完整2015 杠杆牛 + 股灾,极端样本
2016-2017完整「漂亮 50」核心资产行情
2018完整贸易战熊市,重要压力测试样本
2019-2020完整消费/医药/科技牛 + COVID
2021完整教育/互联网监管事件冲击
2022完整房地产暴雷 + 持续熊市
2023-2024完整经济疲软 / 政策托底 / 红利重估

可用样本约 10-11 年,但要切成 7 个明显的 sub-period 看。

8.2 7 个 sub-period 因子表现的稳定性

我自己回测时会算一张这样的表(这里是定性梳理):

Sub-period市场环境反转因子低波动质量
2014H2-2015H1杠杆牛反转失效失效失效
2015H2-2016股灾恢复极强
2017核心资产极强
2018贸易战熊极强
2019-2020抱团牛中(被消费抱团扭曲)
2021风格切换
2022-2023持续熊极强
2024红利重估

核心结论:没有任何一个因子在所有 sub-period 都稳定。多因子合成的必要性远高于美股——单一因子的失效窗口更长。


九、小盘 premium 怎么用:个人量化的独家优势

9.1 为什么这是个人的优势

机构投资者用不了 A 股小盘 alpha 的理由:

限制机构个人
单票流动性要求日均成交 ≥ 1 亿日均成交 ≥ 1000 万即可
持仓集中度限制单票 ≤ 5%
容量上限50 亿规模 → 小盘吃不进几十万到几百万游刃有余
净值波动容忍季度回撤 ≤ 10% 否则被赎回自己钱无所谓
信披要求持仓需披露

→ 个人量化跑小盘 alpha 天然占便宜,这是 Day 76 最重要的认知之一。

9.2 推荐 universe

Universe股票数流动性适用资金
CSI300300极好任意
CSI500500< 1000 万
CSI10001000< 500 万
国证 20002000中-差< 200 万
全 A5000+< 100 万

我自己的资金量做 CSI500 + CSI1000 混合 universe 是最佳点:流动性能扛住月度换手,alpha 又足够强。

9.3 风险:single-stock blowup

小盘股的尾部风险远大于大盘:

  • 财务造假(康得新 / 康美 / 瑞幸)
  • 实控人爆雷(很多民企)
  • 政策定向打击(教培 / 游戏版号)

对策

  • 单票仓位 ≤ 1.5%(持 30+ 只票才能分散)
  • 财务造假筛选(应收账款占营收 > 50% 剔除,经营性现金流连续负的剔除)
  • 行业上限(单一行业 ≤ 20%)

十、PM 视角:今天学到的迁移性思考

  1. 「同一个方法,跨市场结果可能反转」——这是今天最重要的认知。任何在 A 市场跑通的 A/B test 结果,迁到 B 市场前必须重新验证假设,不能默认成立。这一条不仅是量化,做产品、做风控、做金融工程都一样:信用卡风控模型从美国搬到东南亚,违约概率分布完全变了;DEX 的 AMM 公式从以太坊搬到 Solana,套利者结构完全不同。

  2. alpha 的物理基础比公式重要:一个因子能赚钱,是因为它对应了某种市场参与者的可预测错误。如果这个错误的来源(散户比例、信息扩散、监管制度)变了,公式再优雅也是 noise。这一条对 Web3 同样成立:DeFi 的 alpha 来自跨协议套利者的反应延迟,链上结构变了,alpha 就变了。

  3. 「适合个人不适合机构」的赛道值得珍惜:A 股小盘 alpha 是典型的「容量天花板留给散户」的结构。Web3 里类似的有:小市值 token 套利、NFT mint 套利、空投挖矿。作为个人量化 + Web3 PM,要刻意去找这类「机构进不来」的空间,而不是和机构在大盘股、主流币上拼信息和速度。

  4. 数据可信度的时间分层是隐性风险:A 股 2010 前数据不可信、美股 1980 前数据稀疏、Crypto 2020 前数据混乱。任何长样本回测都隐含「数据质量不变」的假设,这个假设几乎总是错的。Sharpe = 0.8 用 5 年数据算出来的,和 Sharpe = 0.8 用 30 年数据算出来的,意义完全不同

  5. 政策风险是「非高斯」尾部:金融工程的 VaR、波动率、Sharpe 都建立在收益分布可建模的假设上。A 股的 2018 贸易战 / 2021 双减是直接把整个行业从分布里抹掉,这不是 fat tail 是直接的结构性 break。模型要承认自己解决不了这种 risk,对策只能是「分散行业 + 仓位上限 + 监控政策信号」

  6. 从工程 PM 视角看「迁移」:迁移不是 reuse,是重新部署一遍假设验证流程。在产品语境下,把美国 onboarding 流程搬到印度也是这个道理——支付方式、KYC 制度、用户阅读习惯全变了,搬的是「问题分解框架」而不是「具体方案」。


十一、明日预告

Day 77: A 股事件驱动策略——财报、停复牌、定增、回购

  • A 股 PEAD(盈利公告后漂移)显著强于美股:散户的反应延迟
  • 停牌制度的套利空间(重组停牌 / 恢复交易第一日 gap)
  • 定增 / 大宗交易折价的统计意义
  • 回购公告的 announcement effect
  • T+1 + 涨跌停对事件驱动策略的真实影响
  • 用 AKShare 拉财报日历,复现 PEAD 因子

实际执行记录

启动一项填一项,时间戳 + 卡点。

  • [hh:mm] qlib + AKShare 环境装好 — ...
  • [hh:mm] CSI300 数据下载完成 — ...
  • [hh:mm] 反转动量因子 IC 跑出来 — ...
  • [hh:mm] 低波动因子 IC — ...
  • [hh:mm] 质量因子 IC — ...
  • [hh:mm] 多因子组合回测 Sharpe — ...
  • [hh:mm] 7 个 sub-period 滚动 Sharpe 表 — ...
  • [hh:mm] CSI500 universe 对比 — ...
  • 卡点 / 学到的:
    • 涨跌停过滤后实盘成交假设是否合理?
    • 财务数据延迟(公告日 vs 报告期)怎么处理?
    • 行业中性化用申万一级还是中信一级?

总字数:约 6,200 字 今日完成度:理论 ✓ / 实操(数据 + 因子 + 回测)/ 笔记 ✓