ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Qlib 订单簿实战:把 Level2 盘口数据变成可查询的分钟级特征

Qlib 订单簿实战:把 Level2 盘口数据变成可查询的分钟级特征 Qlib 订单簿实战把 Level2 盘口数据变成可查询的分钟级特征【免费下载链接】qlibQlib is an AI-oriented Quant investment platform that aims to use AI tech to empower Quant Research, from exploring ideas to implementing productions. Qlib supports diverse ML modeling paradigms, including supervised learning, market dynamics modeling, and RL, and is now equipped with https://github.com/microsoft/RD-Agent to automate RD process.项目地址: https://gitcode.com/GitHub_Trending/qli/qlib你手里有一批 Level2 订单簿数据盘口快照、逐笔委托、逐笔成交到达时间完全随机。想拿它们做因子第一步就卡住了——按天、按分钟组织的特征框架装不下这种数据。Qlib 对此有一条现成路径原始 tick 交给 Arctic MongoDB 存查询时用表达式引擎在线聚合成分钟级特征。跟着做一遍你本地就能查出带分钟级聚合的盘口因子。先说结论分钟级查询秒级信号怎么实现我们直接给结论在 Qlib 里订单簿不需要预先算好特征再入库。原始数据按「股票 × 日期」切片存进 MongoDB通过 Arctic 的 chunk storeD.features查询时表达式里的TResample负责把秒级、毫秒级数据聚合到分钟Rolling负责秒级滑动窗口。整条链路是这样的三个要点先记住存储粒度是「一只股票一个 symbol」ticks库里一只股票对应一个时间序列查询用freq区分数据层ticks盘口快照、order逐笔委托、transaction逐笔成交所有聚合都发生在查询时的表达式求值阶段库里始终只有原始数据。盘口数据和日线数据差在哪差异决定了整个设计先看对比维度日线 / 分钟线订单簿 tick 数据时间到达规整时间戳可枚举任意时刻到达间隔不规则单日体量KB 级MB 到 GB 级记录形态每期一行 OHLCV快照、委托、成交多种记录混存时间索引可对齐统一交易日历无法对齐日历对齐必须关闭常用算子Ref、Mean按 bar 操作需要TResample、Rolling处理秒级窗口最后一行是关键日线世界里「上一期」永远存在盘口世界里同一分钟内可能有 20 条快照也可能一条都没有。所以 Qlib 给这类数据配了独立的存储后端而默认的数据后端bin 文件 固定日历直接不可用。存储与初始化MongoDB、Arctic 和 qlib.init装完 MongoDB下一步做什么把原始数据灌进去再配置 Qlib 指向它。# 启动 MongoDBArctic 的底层存储 sudo systemctl start mongod # 安装 Arctic注意它的 pip 依赖解析经常翻车见后文避坑 pip install arctic # 进入订单簿示例目录 cd examples/orderbook_data # 创建 ticks / orders / transactions 等 Arctic 库 python create_dataset.py initialize_library # 把原始数据按股票写入 MongoDB python create_dataset.py import_datacreate_dataset.py内部做的事其实很直白把每只股票的 CSV 清洗成以时间戳为索引的 DataFrame然后lib.write(symbol, df)写入对应库。它默认对ticks、order、transaction三类库设了约 3TB 的配额全市场多日数据够用。数据入库后用qlib.init把 Qlib 切换到这套后端。只保留关键参数逐行解释import qlib qlib.init( provider_uri~/.qlib/qlib_data/yahoo_cn_1min, # 基础 1min 数据提供日历与标的信息 mem_cache_size_limit1024**3 * 2, # 2GB 内存缓存 expression_provider{class: LocalExpressionProvider, kwargs: {time2idx: False}}, # 不把时间映射为索引 feature_provider{ class: ArcticFeatureProvider, # tick 级数据改从 MongoDB 读 module_path: qlib.contrib.data.data, kwargs: {uri: 127.0.0.1}, }, dataset_provider{class: LocalDatasetProvider, kwargs: {align_time: False}}, # 非固定频率不能对齐日历 )其中两个参数最容易踩坑单独说明time2idxFalse固定频率数据用「时间 → 数组下标」加速订单簿没有规整下标必须关掉align_timeFalse同理盘口数据无法对齐到共享日历。⚠️ArcticFeatureProvider默认带一个交易时段配置market_transaction_time_list[(09:15,11:30),(13:00,15:00)]TResample依赖它处理 A 股午休。研究其他市场时记得改成对应的开闭市时段。配置好后一次最小查询长这样from qlib.data import D df D.features( [SZ000725], # 示例标的 [$ask1, $bid1, $asize1, $bsize1], freqticks, # tick 级 start_time20201230, # 限制时间窗口 end_time20210101, ) print(df.head())返回的 DataFrame 索引就是每个快照的真实到达时间不规整但真实。四个代表性因子直觉、表达式、输出表达式是这套玩法的核心。挑四个有代表性的每个按「直觉 → 表达式 → 输出示意」展开。1档位深度占比。直觉某档挂单量占整本订单簿的比例衡量该档的「话语权」。total TResample( .join(f${n}{i} for i in range(1, 11) for n in [asize, bsize]) , 1min, sum) expr fTResample($asize1, 1min, mean) / ({total}) # 买一均价挂单量 / 十档总量2相对价差。直觉买一卖一口径价差除以中间价衡量即期交易成本。expr (2 * TResample($ask1 - $bid1, 1min, last) / (TResample($ask1, 1min, last) TResample($bid1, 1min, last)))3订单流强度。直觉3 秒窗口内新委托里限价买单的占比刻画短线买压。注意它要在freqorder的委托层上算expr (Rolling(Eq($function_code, 66) Eq($order_kind, 48), 3s, sum) / Rolling($function_code, 3s, count))⚠️66和48是字符B买和0限价的 ASCII 码Eq做的是逐笔字段比较不是数值比较。4中价变动率。直觉中间价买一卖一均值相对 5 秒前移动了多少捕捉秒级方向。expr (TResample(Ref(TResample($ask1 $bid1, 1s, ffill), -5) / TResample($ask1 $bid1, 1s, ffill) - 1, 1min, mean))四个因子放在一起看因子表达式骨架查询 freq直觉深度占比TResample($asize1,1min,mean)/总量ticks该档挂单话语权相对价差2*(ask1-bid1)/(ask1bid1)ticks即期交易成本订单流强度Rolling(Eq(...) Eq(...),3s,sum)/Rolling(...,3s,count)order短线买压中价变动率Ref(中价,-5s)/中价 - 1ticks秒级方向输出示意以深度占比为例D.features返回后重命名列datetimedep_asize_1dep_asize_22020-12-30 09:31:000.1830.1412020-12-30 09:32:000.2050.138注意TResample聚合后的时间戳落在窗口起点如 09:31:00这是它在qlib/data/ops.py里的明确约定画图或对齐标签时按这个理解。提速与避坑缓存、窗口和版本冲突数据能查了怎么让它快且不翻车缓存层面。mem_cache_size_limit配足示例用 2GB大股票池可放大并用mem_cache_typesizeof让缓存按真实数据量计账。表达式求值中间结果会走内存缓存同一个窗口里多查几个因子第二个开始会明显变快。查询层面。三条规则按收益排序手段做法收益来源限定时间窗口start_time/end_time必填少扫大量 chunk只取需要的档位表达式里只写$asize1~$asize5少读一半字段服务端预聚合用TResample直接出分钟值传输量从 tick 级降到分钟级版本与已知限制实测高频坑⚠️pip install arctic的依赖解析经常失败示例 README 里明确提醒过。失败时手动装它依赖的pymongo、pandas等再装 arctic装完跑一次import arctic验证。⚠️ 官方明确的已知限制不同频率之间的表达式计算暂不支持。也就是说不要在同一个表达式里混合ticks层和transaction层的字段做跨层运算先各查各的、在 DataFrame 层面再合并。⚠️ 示例数据里$askX、$bidX含大量 0远端档位为空。做除法类因子深度占比、相对价差时先确认分母非零否则 NaN 会污染下游。下一步把特征接进你的研究流程清单给你按顺序做换数据源保持ticks/order/transaction三类库结构照create_dataset.py的流程把你自己采集的 Level2 数据写进 Arctic查询侧零改动。扩因子库把深度占比、价差、变动率按 1~10 档循环展开示例里的total_func写法就是干这个的一次拿到 60 个因子。接入模型用TResample聚合出的分钟级特征替代手工对齐直接喂给 LightGBM 或 LSTM 类 benchmark 跑通训练。做因子验证对生成的特征算 IC、画累计收益曲线用 Qlib 的报告工具确认哪些档位、哪个窗口真正有区分度。滚动复验按周滚动重训确认因子不是某天的偶然现象。最后留一张速查表写表达式时对照着查算子 / 用法作用示例D.features(..., freqticks)查询 tick 级字段D.features([SZ000725], [$ask1], freqticks)TResample(x, 1min, last)分钟级重采样时间戳落在窗口起点TResample($bid1, 1min, sum)Rolling(x, 3s, sum)秒级滑动窗口Rolling($function_code, 3s, count)Eq($function_code, 66)逐笔条件判断判断是否为买单Ref(x, n)回看 n 个窗口Ref(TResample($ask1$bid1,1s,ffill), -5)盘口数据的门槛从来不在存储而在「原始频率」和「特征频率」之间的那层转换。把TResample用熟之后你会发现自己其实已经具备了把任意秒级事件流变成可训练特征的能力。【免费下载链接】qlibQlib is an AI-oriented Quant investment platform that aims to use AI tech to empower Quant Research, from exploring ideas to implementing productions. Qlib supports diverse ML modeling paradigms, including supervised learning, market dynamics modeling, and RL, and is now equipped with https://github.com/microsoft/RD-Agent to automate RD process.项目地址: https://gitcode.com/GitHub_Trending/qli/qlib创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表