最近有感而发:因子开始衰减的时间节点比我意识到的更早。
以前理所当然的想法是,一个有效因子应该一直有效。后来做得越来越多才发现,市场上的 Alpha 更像一种资源。只有少数人发现的时候,它能持续产生超额收益;随着越来越多人开始使用,同样的收益会逐渐被套利掉。
所以很多因子会经历一个衰减过程:
- IC 越来越低
- Sharpe 越来越差
- 回撤越来越大
- 容量越来越小
最后虽然还有一点 Alpha ,但已经不足以覆盖交易成本。
还是要回测,但小心漂亮的回测
我曾经做过一个短周期因子。第一次测试:Sharpe 只有 0.8 。觉得一般,于是开始:
最后终于把 Sharpe 调到了 2.0 。当时觉得自己找到了一个非常优秀的因子。结果放到未来一年测试。Sharpe 又掉回了 0.5 。后来才明白,我只是在不断学习历史数据里的噪声。
加上实时验证
除了历史回测,把因子放到实时行情里观察也是个不错的选择。例如,一个动量因子昨天还能稳定给出信号,最近几周是否开始出现明显衰减?不同市场环境下排序能力有没有下降?
把实时价格流接入自己的因子计算程序,持续监控因子的表现。例如:
import websocket
import json
API_TOKEN = "YOUR_TOKEN"
def on_open(ws):
ws.send(json.dumps({
"cmd_id": 22002,
"seq_id": 1,
"trace": "factor-monitor",
"data": {
"symbol_list": [{
"code": "AAPL.US",
"depth": 1
}]
}
}))
def on_message(ws, message):
tick = json.loads(message)
print(tick)
ws = websocket.WebSocketApp(
f"wss://quote.alltick.io/quote-b-ws-api?token={API_TOKEN}",
on_open=on_open,
on_message=on_message
)
ws.run_forever()
实际开发中,我一般会把实时行情与已有的因子计算模块结合,一边生成交易信号,一边统计 IC 、Rank IC 、收益率等指标。如果这些指标连续一段时间明显下降,就意味着这个因子可能已经进入衰减阶段。
因子开始失效的几个信号
现在我不会等到收益归零才判断一个因子失效。通常出现下面几个现象,我就会重新评估。
1. IC 持续下降:短期波动很正常,但如果连续几个月都在下降,就要警惕。
2. 分组收益不再单调:以前最高分组收益明显最好。后来高低组开始混在一起,说明排序能力已经下降。
3. 换市场以后效果完全消失:现在我基本都会测试:
如果只能解释一小段历史,很可能只是过拟合。
4. 交易成本开始吞掉 Alpha:有些因子理论上仍然有效,但是换手越来越高、滑点越来越大、市场越来越拥挤,最终净收益越来越低。对于实盘来说,它已经失去了价值。
根本在于建立因子迭代机制
很难追求"找到一个永远有效的因子",因为这样的因子几乎不存在。换一种思路,考虑下:
- 因子还能维持多久?
- 是否已经进入衰减阶段?
- 有没有新的 Alpha 可以替代它?
真正稳定运行多年的策略,往往都不是依赖某一个神奇因子,而是不断淘汰旧因子、引入新因子,让整个因子库保持活力。
不停地找到新因子,这或许才是量化研究里最重要的一项能力。