源文件:research/quant_digests/2026-04-06_0718_coint-shell-signbug-costcliff.md
README.md + qstrat/constants.py + qstrat/libs/stats.py + qstrat/libs/strategy.py + qstrat/backtesting.py + backtest_log.txt)+ Binance Futures testnet 公共 5m/15m portability probeETHUSDT vs LINKUSDT 价差偏离后的回归)> 先回答一句:这篇东西的 base alpha 是什么? > > base alpha = cointegration spread mean reversion。 > 但这轮真正值得 intake 的,不是把它当“又一条 pairs z-score”,而是把它看成一个开源、最近、带 execution / verification / drawdown shell 的 raw-alpha 工程底座。只是源码当前至少有 3 处硬伤:entry threshold 配置不一致、z-score 方向疑似写反、cointegration admission 过松,所以它现在更像“值得修的策略壳”,还不是能直接抄上线的成品。
这轮主看:
https://github.com/ssanin82/strat-test-cointegrationhttps://github.com/ssanin82/strat-test-cointegration10.2307/1913236https://doi.org/10.2307/191323610.1093/rfs/hhj020https://doi.org/10.1093/rfs/hhj020这轮值得写它,不是因为我们缺第 N 条 pairs 论文,而是因为它补的是一个当前很缺的东西:
repo headline alpha != 可上线 alpha。源码看完以后,你会发现它最值钱的不是“ETH/LINK 有 edge”,而是“哪些工程层能留,哪些实现必须先修”。这份 2026 repo 真正值得 desk intake 的,是「cointegration spread raw alpha + execution / verification / drawdown shell」这套完整骨架;但就当前源码状态看,直接照抄会把本该做 mean reversion 的东西,写成方向可疑、阈值混乱、成本后明显失血的半成品。
我这轮不是只看 README,而是直接交叉了:
README.md:写的是 1h 级 ETH/LINK cointegration + z-score spread trading;qstrat/constants.py:发现默认 SIGNAL_TRIGGER_THRESHOLD = 0.02,和 README 口径明显不一致;qstrat/libs/stats.py + qstrat/libs/strategy.py:发现 spread 定义是 series1 - hedge_ratio * series2,但当 z-score > 0 时,策略却下 long symbol1 / short symbol2,这和经典 spread-fade 的方向相反;backtest_log.txt:repo 自带样本里只完成了 1 笔完整交易,总 PnL +236.83 USDT、最大回撤 3.53%,但日志里同时出现 order verification incomplete;markPriceKlines 的 5m/15m portability probe:5m 上,|z|>=2 事件 87 次,中位数 6.5 bars 回到 |z|<0.5;15m 上,|z|>=2 事件 93 次,中位数 6.0 bars 回到 |z|<0.5;2σ -> 0.5σ / max 12 bars / 4 bps per leg 非重叠事件策略,10k 名义资金下依然是 5m: -917.5 USDT、15m: -795.6 USDT。翻成人话就是:
> repo 展示了“spread 会回”的影子,但当前开源实现还没把这点 edge 变成成本后能活下来的策略。
这点先说死:
stats.py 里用 statsmodels.tsa.stattools.coint 做 cointegration 检验;spread = series1 - hedge_ratio * series2;21 bar rolling z-score 做偏离度;README 和 backtest_log 也都在讲“spread 偏离后等待回归”。所以它不是 regime、不是 overlay,它本体就是 raw alpha。
它开源给出的可复用部分,反而比信号本身更值钱:
DRAWDOWN_LIMIT_PCT = 90;main.py / backtesting.py 都把 kill-switch 接进去了。也就是说,它最适合服务的是: > 把我们已经积累的一堆 pairs / stat-arb raw alpha,先包进一套最小可执行壳。
#### 硬伤 1:threshold 口径不一致
README 口径是:z-score > 2 才触发;constants.py 当前实际写的是:SIGNAL_TRIGGER_THRESHOLD = 0.02。这不是小数点误差,这是交易频率和噪声暴露会差一个数量级的问题。
#### 硬伤 2:z-score 方向疑似写反
stats.py 先算:spread = symbol1 - hedge_ratio * symbol2;z-score > 0,说明 spread 偏高,经典 pairs 写法应是:short symbol1 / long symbol2;strategy.py 当前写的是:signal_side == positive -> BUY symbol1, SELL symbol2。也就是: > 当前 repo 对正 z-score 的处理,更像“追 spread 扩张”,不是“赌 spread 回归”。
除非作者后面对 spread 定义另有反向语义,否则这就是一个必须先修的 sign 问题。
#### 硬伤 3:cointegration admission 太松 stats.py 里 admission 条件写的是:
p_value < 0.5coint_t < critical_valuep < 0.5 这种门槛,基本不够当 admission gate。对 short-cycle desk,更现实的做法至少应该是:
p < 0.05 或更严格;half-life / zero-cross / spread vol / turnover budget 这些二级 admission。我补了一轮最小 transfer check,用的是:
markPriceKlines(无需授权)ETHUSDT / LINKUSDT5m、15m1500 根 bar21 bar z-score先看事件层:
5m:87 次 |z|>=2 事件,事件后中位 6.5 bars 回到 |z|<0.5;15m:93 次事件,中位 6.0 bars 回到 |z|<0.5。这说明 spread 回归 pocket 是有的。
但一上最朴素的可交易骨架:
|z| >= 2|z| < 0.5 或 12 bars time-stop10k 名义资金,双腿各 50%4 bps / leg结果就很直接:
5m:62 笔,gross +74.49 USDT,net -917.51 USDT;15m:64 笔,gross +228.43 USDT,net -795.57 USDT。如果把 entry 拉到更保守的 3σ:
5m:gross +34.94,net -125.06;15m:gross +65.82,net -94.18。这组数的含义非常清楚:
> 15m 明显比 5m 更接近“能活”的方向,但 naked z-score 本身还不够,必须靠更严 entry / 更强 admission / 更低成本 / 更少重试 才有机会。
它和当前项目的关系,不在于“我们还缺一篇 pairs digest”,而在于:
这正好适合当前 desk 的阶段:
|z| 回到较低阈值,或 time-stop 触发50%,beta-hedged;当前 repo 默认 10x leverage如果只想把这份 repo 变成 desk 可用的第一版,不要直接照抄,先做这 6 个修正:
z > +entry:先按经典 spread-fade 写成 short symbol1 / long beta*symbol2z < -entry:long symbol1 / short beta*symbol2entry ∈ {2.0, 2.5, 3.0}exit ∈ {0.5, 1.0}p < 0.0515m 开始,不先上 5m15m 更接近 gross 可用;5m 更像成本压力测试桶。做一个最小 A/B/C:
15m2.0 / 2.5 / 3.0σ entry0.5 / 1.0σ exit8 / 12 / 16 bars time-stopp < 0.05markPriceKlines15m,再 5m 当 stress testBTC/ETH/SOL/LINK/BNB 里滚动选 pair,不要只绑死 ETH/LINKtrain 30d / test 7d4 / 8 / 12 bps round-trip 等价三档这轮别问“最终收益最大化”,先回答 4 个问题:
15m 3σ 能不能在合理 fee 下接近 break-even / 小幅转正?backtest_log.txt 里只完成了 1 笔完整交易,不能把 +236.83 USDT 当成有效验证。如果只记一句:
> 这份 2026 新 repo 值得 intake 的不是“ETH/LINK 圣杯”,而是 cointegration raw alpha + execution shell 这套可修底座;但就当前源码和 portability probe 看,先修 sign / threshold / admission,再谈上线。
再补一句更贴当前短周期:
> 第一轮别上 5m,先拿 15m 做 corrected-sign + stricter-admission 的最小实验;5m 目前更像成本压力测试,不像主战场。
https://github.com/ssanin82/strat-test-cointegrationhttps://github.com/ssanin82/strat-test-cointegrationREADME.md、qstrat/constants.py、qstrat/libs/stats.py、qstrat/libs/strategy.py、qstrat/backtesting.py、backtest_log.txt10.2307/1913236https://doi.org/10.2307/191323610.1093/rfs/hhj020https://doi.org/10.1093/rfs/hhj020markPriceKlines(本轮 portability probe)ETHUSDT/LINKUSDT,各 1500 根 5m/15m mark-price bars,rolling 21 bar z-score,2σ/2.5σ/3σ entry,0.5σ/1.0σ exit,12 bar time-stop,双腿各 50% 名义资金,显式计入每 leg 手续费