3. 状态空间设计:市场微观结构特征、技术指标工程、订单簿特征提取、多时间尺度特征融合
状态空间设计,说白了就是决定「强化学习智能体能看到什么」。
我见过太多人一上来就堆几百个特征,结果模型训出来跟抽风一样。其实,好的状态空间应该像围棋高手看棋盘——信息量不大,但每一条都致命。
这一章,我们聊聊怎么给交易智能体「配眼镜」。
3.1 市场微观结构特征:从Tick数据里挖金子
微观结构,就是市场最底层的「呼吸」和「心跳」。我个人习惯从三个维度下手:
- 买卖价差(Bid-Ask Spread):流动性最直接的体现。价差突然扩大,说明有人慌了,或者做市商在撤单。
- 交易强度(Trade Intensity):单位时间内的成交笔数。我在做股指期货时发现,交易强度陡增往往是大资金进场的信号。
- 订单流不平衡(Order Flow Imbalance):主动买 vs 主动卖的成交量差值。这个指标对短期价格方向预测能力很强。
核心公式(我常用的):
# 订单流不平衡
def order_flow_imbalance(buy_volume, sell_volume, window=10):
net_flow = buy_volume - sell_volume
imbalance = net_flow.rolling(window).sum()
return imbalance / (buy_volume + sell_volume + 1e-8)
避坑指南:我曾经在回测里用了全量Tick数据,结果实盘时发现交易所的Tick推送有延迟。后来我强制在特征里加入「数据时间戳延迟」这个维度,模型才稳定下来。
3.2 技术指标工程:别做「指标收集癖」
技术指标这东西,用好了是神器,用多了是噪音。我一般只保留三类:
- 趋势类:EMA、MACD。注意,我不用原始值,而是用「斜率」和「交叉信号」。
- 动量类:RSI、ROC。重点看「背离」——价格创新高但RSI没跟上,这就是个危险信号。
- 波动率类:ATR、布林带宽度。波动率是RL模型最好的「风险调节器」。
你想想看,如果把50个指标全塞进去,模型根本分不清哪个有用。我习惯的做法是:先跑一轮Lasso回归,把冗余特征干掉。
注意:技术指标一定要做「未来数据防护」。我见过有人用当天的收盘价计算当天的指标,然后拿去预测当天的收益——这等于作弊。正确的做法是:用t-1时刻的数据计算指标,预测t时刻的动作。
3.3 订单簿特征提取:Level 2数据的正确打开方式
订单簿(Order Book)是高频交易的「圣杯」。但原始数据太粗糙,需要加工。
我常用的特征提取方法:
| 特征名称 | 计算方法 | 物理意义 |
|---|---|---|
| 价格深度 | 前N档挂单量的加权价格 | 真实成交价可能在哪 |
| 斜率 | 挂单量随价格档位的变化率 | 支撑/阻力位的强度 |
| 订单簿不平衡 | (买1量 - 卖1量) / (买1量 + 卖1量) | 短期买卖压力 |
| 撤单率 | 单位时间内撤单数量 / 总挂单量 | 虚假挂单比例 |
代码示例:提取订单簿斜率
def orderbook_slope(bids, asks, levels=5):
# bids: [(price, volume), ...]
# asks: [(price, volume), ...]
bid_prices = [b[0] for b in bids[:levels]]
bid_volumes = [b[1] for b in bids[:levels]]
slope = np.polyfit(bid_prices, bid_volumes, 1)[0]
return slope
嗯,这里要注意:订单簿数据更新极快,每秒可能几百次。我建议在特征提取层做「事件驱动」处理,而不是定时采样。否则你会丢失很多关键信息。
3.4 多时间尺度特征融合:让模型既看树又看林
单时间尺度的特征有个致命问题:它看不到全局。比如1分钟K线图上是个小回调,但放在日线图上可能只是上升趋势中的一个小浪花。
我常用的融合策略:
- 金字塔采样:同时维护1分钟、5分钟、30分钟、日线四个时间尺度的特征。
- 特征对齐:所有尺度在同一个时间戳上对齐。比如在14:30:00,我同时拿到过去1分钟、5分钟、30分钟、1天的统计量。
- 权重自适应:让模型自己学哪个尺度更重要。波动率大的时候,短尺度权重高;趋势明显的时候,长尺度权重高。
我的经验:多尺度特征不要直接拼接。我试过把四个尺度的特征拼成一个大向量,结果模型过拟合严重。后来改成「分层输入」——先让每个尺度自己过一个小型MLP,再把隐层向量拼接。效果好了很多。
3.5 知识体系总览
下面这张图,是我做状态空间设计时的「作战地图」。每次设计新系统,我都会先对着这张图过一遍,看看哪个环节漏了。
状态空间设计没有银弹。不同的市场、不同的交易频率,需要的特征组合天差地别。我的建议是:从最简单的开始,比如只用价格和成交量,然后逐步加特征。每加一个特征,都要问自己一句:「这个特征真的能帮模型做更好的决策吗?」
如果答案不确定,那就先跑个A/B测试。我在实盘系统里一直保留着「特征开关」——随时可以打开或关闭某个特征组,看看对收益和风险的影响。这才是工程化的做法。