源文件:research/quant_digests/2026-04-01_2140_microprice-obi-veto-pairs-hft-alpha.md
README.md + analyzer.py + optimizer.py + book_recorder.py + main.cpp + strategies.json)1h 协整筛 pair,再在更快执行层对 log(microprice_1) - beta * log(microprice_2) 的 z-score 偏离做均值回复这次看的是 Samarth Chaudhary (GitHub, 2026) 的仓库 Crypto_Stat-Arb_HFT_Model。表面看,它像一份“研究层 Python + 执行层 C++”的 HFT 项目;但对我们 desk 真正有价值的,不是 4-7ms RTT 这种工程秀肌肉,而是它把一条 可以独立落地的 pairs raw alpha 壳 写得比较完整:
data_loader.py 先抓 Binance Futures top 50 quote-volume USDT perp 的 1m 数据、回看 365 天;analyzer.py 把 1m 数据 resample 成 1h,先过 相关性 > 0.85,再做 Engle-Granger OLS + ADF,并给出 hedge_ratio / p-value / half-life;optimizer.py 再对 spread 做 rolling z-score 参数扫描:window = 30/60/120/240/360,entry = 1.5~3.0,exit = 0~0.5,stop = 4~8;book_recorder.py / main.cpp 在执行层引入 microprice + OBI:不再只看 mid,而是用盘口量加权价与一档不平衡去决定是否放行入场;main.cpp 里写死了 Z_ENTRY = 2.0、Z_EXIT = 0.5、单 pair notional = 1000 美元、单仓亏损止损 = -20 美元、全局 kill = -100 美元。一句话:base alpha 不是 OBI,也不是低延迟;base alpha 仍然是 pair spread mean reversion。真正值得 intake 的,是它把 “慢频选 pair + 快频执行 veto” 接成了一条完整策略链。
main.cpp 里执行价不是普通 mid,而是 microprice:(bid * askVol + ask * bidVol) / (bidVol + askVol);同时再加 OBI veto:z > 2 只在 obi1 < 0.2 && obi2 > -0.2 时做 short leg1 / long leg2z < -2 只在 obi1 > -0.2 && obi2 < 0.2 时做 long leg1 / short leg2这相当于要求盘口短时压力不要和 spread fade 完全打架。
optimizer.py 说明 repo 想给一条完整策略壳:entry / exit / stop / sizing / cost 都有定义,而不是只给“这个 pair 看起来会回归”一句空话。analyzer.py 在 1h resample 后仍把 MAX_HALF_LIFE = 240 注释成“最多 4 小时回归”,单位明显错位;按代码实际口径更像 240 小时。optimizer.py 的成本近似是 abs(spread) * fee_pct,不是双腿名义金额成本,会低估真实 friction。strategies.json 里一开始缺 mean/std_dev,后来又靠 fix_strategies.py 现场补,这说明 repo 的研究层和执行层 口径并没完全锁死。一句话核心结论:真正该复现的不是“低延迟 C++”,而是“慢频筛出可交易 pair,再让 microprice+OBI 只负责决定这次 spread 偏离要不要做”这条 pairs raw alpha。
一句话说它怎么证明:证据主要来自 repo 源码本身——数据下载、pair discovery、参数扫描、盘口记录、执行与风控模块是同一条链,说明作者不是只写了概念,而是把完整策略壳真的连起来了。
最近两天 intake 里,pairs / relative-value 家族已经补了不少:
这轮补的不是“再来一个 pairs headline”,而是一个当前素材池里更缺的组件:spread alpha 怎么和盘口执行层接上。
这和当前学习进展的关系也很直接:
momentum 原主线还是趋势 / breakout / ATR / volume;1m/3m/5m/15m 上该怎么进场,才不会被盘口噪声直接吃掉。翻成人话:pair spread 会不会回归,是第一层;这次偏离值不值得立刻出手,是第二层。repo 的价值就在把第二层写成了可执行规则。
log(p1) - beta * log(p2) 的 spread,而不是单腿方向判断|z| > 2 触发、OBI veto、MAX_SAFE_Z = 25 异常极值跳过|z| <= 0.5 止盈、单仓美元亏损止损、全局 kill-switch、microprice 作为更细盘口执行价代理1m klines 做 pair discovery 输入;bookTicker 或 top-of-book 快照做 best bid / best ask / bid size / ask size;1s~5s 盘口 proxy。15~30 个最液态 USDT perp;先分 bucket(majors / L1 / meme),不要第一刀全市场乱配。30~60 天 1h 数据重算 pair;> 0.8;p < 0.05;15m 先做 baseline:spread rolling z 的 entry 2.0/2.5、exit 0.5、stop 3.5/4.0;1m 或盘口流:8/16/24 根 15m;把 funding 加回 pair PnL。1~3 根 adverse excursion 是否下降;15m signal + 1m veto 是否优于纯 1m signal 直接交易。先测 “microprice / OBI 是否能当 execution veto,而不是 alpha 本体”。
别一上来就测:
第一刀更合理的是:保留一个最朴素的 spread z-score baseline,再只替换入场口那一层的执行判定。
如果这一刀都不能改善 post-entry path,就没必要急着把它升级成“高频系统”。
abs(spread) 近似,必须回到双腿名义、手续费、滑点、funding 与 legging risk。1h 上协整成立,不代表 1m 上一定值得做;中间必须经过 15m/5m 的桥接测试。如果把这份材料变成 desk 可测策略,我会把它定义成:“1h 慢频筛 pair,15m 做 spread 触发,1m / bookTicker 用 microprice + OBI 决定这笔 fade 要不要放行”的完整 pairs raw alpha 壳,而不是一份单纯炫低延迟的 C++ 项目。