SYSTEMATIC ML LONG/SHORT · v0.1

横截面 多因子多空 回测

和左边那条/quant/backtest(单股、规则化、long/cash)不一样。 这里是 Voleon / D.E. Shaw 那一类"systematic ML quant"的最小骨架: 同一时刻把一篮子股票拉一起打分, 排名最高那批做多、最低那批做空, 模型从历史里学每个因子值多少钱(rank-IC 加权), 每隔 h 天再平衡。 数学透明 — 没有黑盒, 没有 LLM, 没有"AI 解盘"。

横截面

同一天打分排名 (相对强弱), 不押大盘方向

多空中性

多头 +0.5 / 空头 -0.5, 净敞口 ≈ 0

Walk-forward

滚动训练窗 + purge, 杜绝 look-ahead

标签

未来 h 日横截面去均值收益 (学相对涨跌)

模型

rank-IC 加权合成 (白盒, 跑得快)

成本

按 |Δw| × bps 扣换手成本, 不假装零成本

系统里装了哪 7 个因子

每一个都能在 lib/quant/ml-ls.ts 里看到公式

所有因子先按公式算原始值, 再做每日横截面 z-score, 最后用训练窗里的 rank-IC 加权合成 — 这是因子投资圈最经典的"白盒"组合方法。

因子公式直觉

1M Momentum

mom_21

close[t] / close[t-21] - 1过去 1 个月跑赢同行的, 短期容易继续跑赢

3M Momentum

mom_63

close[t] / close[t-63] - 1中期动量, 抓持续性强的趋势

6M Momentum

mom_126

close[t] / close[t-126] - 1长期动量, 区分结构性赢家 vs 临时反弹

1W Reversal

rev_5

-(close[t] / close[t-5] - 1)短期反转: 一周猛涨的, 接下来容易回调一点

1M Realized Vol

vol_21

std(ret_1d, 21)高波动股票长期跑输 (低波动异象)

Gap vs SMA50

ma_gap

close[t] / sma50(close) - 1偏离 50 日均线太远, 容易回归

Volume Z-score

vol_z

(vol - sma21(vol)) / std21(vol)近期成交量异动暗示关注度变化

回测设置 · Walk-Forward Cross-Section

股票池 → 因子 → 滚动训练 → 多空组合

每隔 h 天再平衡一次: 先用过去 train 天的横截面数据学每个因子的 rank-IC 权重, 再用今天的横截面预测未来 h 天的相对强弱, 排前 q 做多、排后 q 做空, 美元中性等权。Purge 防泄漏: 训练样本的标签窗口必须在预测日之前已经闭合。

7 个因子 · IC 加权合成 · 净值从 1.00 起步 (不是美元额)

老实写下来的限制

这版故意没做的事

  • 没用 GBM / 神经网络。 用的是 rank-IC 加权合成 — 和因子投资圈几十年来的标准做法一致, 白盒、跑得快、TS 里不需要矩阵求逆。 真要上 GBM, 应该在更好的数据 + 更多特征上再考虑。
  • 有幸存者偏差。 Yahoo 只给"今天还活着"的票, 退市/破产的看不到 — 回测会偏乐观。要真做, 得用 CRSP / Compustat 这类含退市的数据库。
  • 没做行业/市值中性化。 现在的多空组合可能集中 在某个行业 (例如全做多科技股、做空银行股) — 真实组合需要约束。
  • 交易成本只算了换手 × bps。 没建模冲击成本、没建模 资金借贷成本 (做空要付 short rebate)。真实净收益会更低。
  • 很大概率 Sharpe 很低甚至为负。 这是诚实的、典型的 "免费日线 + 7 个简单因子"的结果。真正的 edge 在更好的数据 + 更细的特征 + 更严的成本控制里, 而不是"换个更花哨的模型"。