源文件:research/quant_digests/2026-04-14_2218_microprice-obi-spreadfade-shell.md
microprice log-spread 做均值回复;当 spread 的 z-score 走到极端时反向做配对,OBI(order-book imbalance)只负责开仓放行/否决,不是 alpha 本体。README.md + main.cpp + optimizer.py + analyzer.py + book_recorder.py + data_loader.py + fix_strategies.py)+ Binance USDⓈ-M 1h/1m/1s public-data portability probe这轮默认还是优先补 raw alpha 素材池,而不是再写一个纯 gate / overlay。
最近几篇 digest 已经写过不少 pairs / cointegration / spread fade,但还没单独把这条线拆清楚:
> 当 spread 本体还是老老实实的均值回复时,能不能把“更快的定价口径(microprice)+ 更近盘口的 admission(OBI veto)+ 更像生产壳的执行线程”拼成一条更短周期的 pairs shell?
这份 repo 值得看的地方,不是作者自称 ~42µs 逻辑延迟,也不是 AWS Tokyo 这些工程姿势;真正值得 desk 收进池子的,是它把下面三件事放在了一条链里:
microprice spread 做 z-score fade;OBI 决定是否允许开仓。一句话说,它不是“又一个普通 z-score pair notebook”,而是:
> 把 spread mean reversion 这条 raw alpha,往真正更短的微观结构执行层又推了一步。
2026-01-18,最后 push 于 2026-02-05)Crypto_Stat-Arb_HFT_ModelREADME.mdmain.cppoptimizer.pyanalyzer.pybook_recorder.pydata_loader.pyfix_strategies.py这些文件基本把作者想表达的结构都摆出来了:
!bookTicker、算 microprice、看 spread z-score、下单、风控;strategies.json 做 research-to-execution handoff。这篇东西的 base alpha 是什么?
> base alpha = 协整 pair 的 spread mean reversion。
更具体点:
log(p1) - hedge_ratio * log(p2);z > entry 时做 short spread(卖第一腿、买第二腿);z < -entry 时做 long spread(买第一腿、卖第二腿);z 回到中心附近就平仓。这里:
microprice 只是把价格口径从普通 mid/last 推到更接近盘口压力的位置;OBI 只是开仓 admission / veto;所以它不是:
它本质上还是一条很标准的:
> pairs / stat-arb / relative-value / mean-reversion raw alpha。
analyzer.py 的路线是:
MIN_CORRELATION = 0.85);cointegrated_pairs.csv。翻成人话就是:
> 不是拿任何两个相关币就直接上 z-score,而是先问“它到底像不像一条会回来的 spread”。
optimizer.py 用的是典型的 spread-fade 网格:
WINDOWS = [30, 60, 120, 240, 360]ENTRY_ZS = [1.5, 2.0, 2.5, 3.0]EXIT_ZS = [0.0, 0.25, 0.5]STOP_ZS = [4.0, 5.0, 8.0]FEE_PCT = 0.0012逻辑也很直白:
z > entry → short spreadz < -entry → long spreadexit 附近平仓stop_z 被打掉这部分没什么花活,但优点是:alpha 本体很干净,容易搬到我们自己的 1m / 3m / 5m 研究框架里。
microprice + OBI vetomain.cpp 里,作者没有直接用 last 或普通 mid,而是用:
> microprice = (best_bid * ask_vol + best_ask * bid_vol) / (bid_vol + ask_vol)
也就是:
然后在 pair 信号里再叠一层 OBI:
obi = (bid_vol - ask_vol) / (bid_vol + ask_vol)Z_ENTRY = 2.0Z_EXIT = 0.5OBI_LONG_THRESHOLD = -0.2OBI_SHORT_THRESHOLD = 0.2BET_SIZE = 1000开仓逻辑可以翻成人话:
这层东西最值得 desk 记住的,不是阈值本身,而是它背后的结构:
> spread alpha 负责告诉你“价差远了”;OBI 负责告诉你“现在追进去会不会刚好撞上盘口不利一侧”。
这是这轮最值得诚实写出来的部分。
optimizer.py 和 main.cpp 没真正接上optimizer.py 输出的是:
window_minutesentry_zexit_zstop_z但 main.cpp 真正读取并使用的却是:
leg1leg2hedge_ratiomeanstd_dev也就是说:
> 研究层找到的 entry/exit/stop 参数,live engine 根本没用上。
main.cpp 依赖 mean/std_dev,而 optimizer 并不输出它们这也是为什么 repo 里又多了一份 fix_strategies.py:
200 根 1m K 线,重新给 pair 补 mean 和 std_dev;main.cpp 直接拿 optimizer 产出的 strategies.json 是跑不起来的。换句话说:
> repo 现在不是“一键从 research 直通 live”,而是 research 产物还要再补一次参数,才能接进执行层。
analyzer.py 注释写的是:
MAX_HALF_LIFE = 240 # Max 4 hours to revert但它实际是在 1 小时重采样数据 上估 half-life,再直接拿 hl < 240 做筛选。
这意味着代码实际放行的更像是:
< 240 个 hourly bars,也就是远大于 4h;这会直接影响 pair universe:
为了不只停在源码阅读,我补了两层最小验证:
我用 Binance USDⓈ-M 当前 24h quote volume 前 15 个 USDT 对,抓最近 325 根 1h 收盘,按 repo 的大框架做了一个 quick pair scan。
其中比较干净的一对是:
DOGEUSDT / XRPUSDT0.916p-value:0.024611.6h0.0562为什么选这对?
SOL/XAG 这类混着商品代理的 pair 更像纯 crypto liquid pair;BTC-ETH 近邻路径。我按 repo 的思路,用 Binance depth?limit=5 连续抓了 180s 的 DOGE/XRP 五档盘口,计算:
OBImicroprice同时用最近 200 根 1m close(配合 hedge ratio)给 spread 做 mean/std 标准化。
产物保存到了:
reports/artifacts/quant_digests/doge_xrp_microprice_obi_liveprobe_2026-04-14.csv结果很直白:
180 个 1 秒样本里,|z| > 2 的次数是 0;short_signal = 0;long_signal = 0;0.36 ~ 0.68 之间。这说明什么?
> 在 liquid pair 上,这种 microprice spread + OBI veto 不是那种“每分钟乱响一堆信号”的玩具。它更像一个低频、挑时机、需要更长观察窗或更多 pair 并行的短周期壳。
1m portability backtest我继续对同一对 DOGE/XRP 抓了最近 7d 的 1m K 线(10080 bars),沿用 repo 的参数网格跑最小 spread 回测。
核心结果:
window=240, entry_z=2.5, exit_z=0.5, stop_z=8.041 笔交易+0.054212 bps round-trip 费用后,best 组合转负window=360, entry_z=3.0, exit_z=0.25, stop_z=8.022 笔交易-0.0108559.1%155.8 分钟6 bps round-trip,best 组合又回到正值+0.02075|z| > 1.5:2674 次|z| > 2.0:1492 次|z| > 2.5:769 次这组数字最重要的解读不是“它能直接上”,而是:
> spread MR 本体存在,但它对 friction 非常敏感;repo 里那种 HFT/microstructure 包装,不是锦上添花,而是它能否活下来的核心。
把这轮结论压缩成四句话:
pair spread mean reversion。所以这轮 4 字段应该老实写成:
raw alphamicroprice spread mean reversion是否pairs × microstructure admission最近 pairs digest 已经不少,但多数还停在:
这份 repo 额外给出的,是:
> 把 spread 的观察口径往盘口推进一层,把 admission 也往盘口推进一层。
这对 short-cycle desk 是有增量的。
这点很重要。源码虽然有断点,但结构上没有混淆:
这种拆法对我们自己重写最有帮助。
这类 alpha 在 1m 甚至更快层面,常见误判就是:
这轮 quick probe 恰好反过来提醒:
> 如果 friction 压不下去,那你看到的可能只是“有方向感的统计现象”,不一定是“可交易的 PnL”。
我不建议下一步继续在同一套粗糙 taker 框架里磨参数;更值钱的是下面 4 件事:
必须先改掉两处硬伤:
optimizer.py 直接输出 mean/std_dev;main.cpp 真正读取并使用 window/entry/exit/stop,不要继续硬编码 Z_ENTRY/Z_EXIT。不修这个,后面所有 live probe 都会混着配置漂移。
建议:
7d/14d 的 1h 协整 / ADF / half-life 重估;<= 12h 或 <= 24h,不要再放一个注释和代码不一致的 240;最小实验可以这样分层:
1m 决定 state 和方向;5s/1s 决定是否放行;<= 6 bps 再看这条线是否还能活。±0.2 这种裸阈值太依赖单币微观结构。
下一轮更值得测的是:
N 秒 / N 分钟的 OBI percentile;这样更容易扩到不同 liquidity bucket。
reports/artifacts/quant_digests/doge_xrp_microprice_obi_liveprobe_2026-04-14.csvreports/artifacts/quant_digests/crypto_statarb_hft_probe_summary_2026-04-14.jsonREADME.mdmain.cppoptimizer.pyanalyzer.pybook_recorder.pydata_loader.pyfix_strategies.py