RH链研究数据层诊断
地址标签 · token 标签 · 跟单回测 三类研究的耗时全貌与改造方向 · 审计日期 2026-09-04 · 覆盖 rh-fomo / rh-fomo-test / meme-smartmoney / rh-oldpump / robinhood-chain
结论:最薄弱的不是"拉 K 线"这一个动作,而是整套研究没有沉淀的数据层。每个想法一个脚本,每个脚本从远端 API 单线程重新拉一遍,各存各的库。真正算策略的 eval 阶段全是本地 sqlite、只要几秒;一次端到端回测 5 个多小时,99% 在等数据。
1. 现状:五个项目,五套数据层
2. 一次回测的时间去了哪里
rh-fomo 14 天回测(96 地址、1200 万区块,2026-09-01 实跑日志)。斜纹部分是代码里写死的 sleep,不是在等网络。
txs 阶段 103 分钟里 56 分钟是每 40 笔固定 sleep 4.5 秒;整个回测日志里 RPC 一次 429 都没出现过,这个 sleep 是猜的。prices 阶段(按买入循环的原版)估算 2.3 万次 GT 调用约 15 小时,当时直接放弃改跑 prices2。
3. K 线为什么慢:四个叠加原因
配额被后台监控占满
GT 匿名档按出口 IP 限 30 次/分,四个 launchd 监控常驻占用。研究脚本一开跑就撞 429,退避 35 到 80 秒一次,web.py 里还有 62 秒硬睡。
缓存key 里带了时间戳
fetched(pool, tf, before_timestamp):before 由每笔买入时间推出,同币两笔差 1 秒就是两次远端调用。cohort_bt 与 bt_eval_test 直接用 time.time() 当 key,命中率 0%,两次运行 53 + 178 分钟全是重复拉取。limit 不在 key 里,大 limit 请求会被小 limit 缓存静默截断(正确性 bug)。
循环按买入而不是按币
backtest.py prices 阶段对 7877 笔买入循环、每笔 3 次 GT 调用,而不是 801 个币。toks 已经算出来打印了,然后没用上。
孤岛五份 K 线缓存互不相通
bt.db 277 池 · bt7.db 115 · rh-fomo-test 301 · oldpump 2264 · meme json 300 币;413 个池在两个以上库里重复拉过。CoinGecko key 通道只有 rh-oldpump 接了,rh-fomo 全家仍走匿名 GT。
4. 其他耗时环节(按严重程度)
| 环节 | 实测 | 根因 | 重复存储 |
|---|---|---|---|
| 账本回放 全史 ERC20 Transfer getLogs | 130 到 730 行/秒。CASHCAT 一个币 7.5 小时;9 个应用币 3 分片 3.3 小时;oldpump 120 个事件每分片约 1 小时 | 单线程串行;密集区自适应窗口塌到几千块,round-trip 数爆炸;手动分片进程互相把 sqlite 锁死 | rh.db 1520万 · app_pnl.db 810万 · oldpump 647万 · bt.db raw · chain.db,各存一份 |
| tx_meta / 买入验真 eth_getTransactionByHash | 12 到 28 笔/秒;app_txmeta.log 97% 的行是 429;460 万笔只回填 99 万 | 批量 40 无 pacing 反而比批量 25 + 1.5 秒更慢;Blockscout 替代线 4 到 6 笔/秒且死于 database is locked;在线监控每轮 350 到 580 次验真不缓存 receipt | tx_meta(rh.db)· txinfo(bt.db ×3) |
| 地址标签 合约名 / is_contract / nonce / OKX 标签 | 逐地址查 Blockscout,无批量;nonce 50/批会 429 需降到 20 | Blockscout 封自定义 UA、百万级地址过滤接口稳定 500、几小时后限流 | addrinfo 五张表:304 / 961 / 1008 / 1016 / 3905 行 |
| 按币元数据 DexScreener 池 / 现价 / 建池时间 | forward.py 3113 个币,每币 2.4 秒固定间隔,纯睡眠 2 小时打底;prices2 现价 13.5 秒/币 | DS 批量端点截断 pairs 被迫逐币;报价侧池会拿错币价,须过滤 baseToken | tokmeta / tokfull / fwd_tok / token_cache / tokens |
| 工程层 | 全部项目零并发(无线程、无 async);每个请求新建 TLS 握手;限速全是固定 sleep(2.3 / 4.5 / 6 秒) | web.py 在两个项目各有一份相同拷贝;限速器是进程内变量,跨进程无协调 | — |
5. 目标架构:研究脚本只读本地
6. 改造清单
止血当天可做,回测从小时级压到分钟级
- K 线缓存 key 改成覆盖区间(按小时对齐或存 [from, to]),命中改用区间包含;limit 纳入 key。直接救回 cohort_bt 53 分钟、bt_eval_test 178 分钟。
- backtest.py prices 阶段改按币循环(801 而不是 7877)。
- 删掉 txs 的 4.5 秒硬睡,改成按 429 退避;同时把 txinfo 查表提到循环外(bt_txs3 那 17 分钟全是这个循环)。
- 所有 GT 调用统一切到 CoinGecko key(rh-oldpump 的
gt_get已是现成实现),加一个跨进程令牌桶(共享 sqlite 或锁文件)。Demo 档 1 万次/月,先估监控用量,不够上 Analyst(500 次/分、50 万/月)。 - 五份 candles 合并进一张共享表,先把 2414 个池的存量 K 线一次性并入。
结构几天工作量,服务于"快速测想法"
- 建共用数据仓,先合并已有存量:转账账本五份、addrinfo 五张、tx_meta / txinfo 四张。合并本身零网络。
- 填库任务独立成一个后台进程:并发 + 每源令牌桶 + 增量游标;研究脚本和监控不再自己抓。
- web.py 收敛成一个共享模块(连接复用、统一 UA、统一代理读取),去掉两份拷贝。
- 账本范围先做"关注钱包 ∪ 关注币"的并集而不是全链;全链 Transfer 索引对本机是否可行、有没有支持 RH 链的付费 RPC 或索引服务,需要另行实测再定。
- 把四个后台监控迁到共享限速器之后,研究时段与监控互不干扰。
附录:数据源实测(2026-09-04)
| 源 | 实测 | 限制 / 坑 |
|---|---|---|
| GeckoTerminal 匿名 | 第 1 次 0.11 秒 200,第 2 次立即 429 | 30 次/分按出口 IP,被后台监控占满;直连在 fake-ip DNS 下不可达 |
| CoinGecko onchain(Demo key) | 8 次 OHLCV 5.3 秒全 200,每次 1000 根,0.5 到 1.2 秒/次 | 按 key 计额度,约 30 次/分、1 万次/月;路径与 GT 同构 |
| DexScreener | pair 0.33 秒,search 0.05 秒 | 无 K 线;批量 tokens 端点截断 pairs;按 token 查会混入报价侧池 |
| RH 链 RPC | getLogs 100k 块窗口约 3.4 秒;tx 批量 40 在监控高峰会 429 | 单查询 1 万条日志上限;密集区窗口须允许缩到 50 块;urllib 经代理 CONNECT 会被断连 |
| Blockscout | 逐地址 0.3 到 1 秒 | 封自定义 UA;百万级地址过滤接口 500;几小时后限流自动解封 |
| OKX priapi | 每币 2 次调用,2.5 秒间隔 | 须带 Referer;V4 新币数据残缺;翻页只认 rankStart/rankEnd |
数据来源:各项目 scripts/ 静态审计 + logs/ 时间戳 + sqlite 行数统计 + 当日实测延迟。数字均为实跑记录,不是估算的部分已注明"估算"。