RH链研究数据层诊断

地址标签 · token 标签 · 跟单回测 三类研究的耗时全貌与改造方向 · 审计日期 2026-09-04 · 覆盖 rh-fomo / rh-fomo-test / meme-smartmoney / rh-oldpump / robinhood-chain

结论:最薄弱的不是"拉 K 线"这一个动作,而是整套研究没有沉淀的数据层。每个想法一个脚本,每个脚本从远端 API 单线程重新拉一遍,各存各的库。真正算策略的 eval 阶段全是本地 sqlite、只要几秒;一次端到端回测 5 个多小时,99% 在等数据。

5h 20m
一次 14 天回测端到端(rh-fomo,9/1 实跑)
秒级
其中策略评估 eval / evalhold 的耗时
0%
cohort_bt / bt_eval_test 的 K 线缓存命中率(key 用了 time.time())
642
近两天三个监控日志里的 HTTP 429 次数(159 + 161 + 322)

1. 现状:五个项目,五套数据层

外部数据源(每个项目各自直连) RH 链 RPCgetLogs / tx / eth_call GeckoTerminal 匿名OHLCV · 30次/分/IP CoinGecko key同构 OHLCV · 按 key 计额 DexScreener池/现价 · 批量会截断 Blockscout合约名 / txlist · 封UA OKX priapi盈利榜 / 标签 同一个代理出口 IP(Clash 7897)→ GT 匿名配额被所有进程共享,谁都不知道别人用了多少 rh-fomo rh-fomo-test meme-smartmoney rh-oldpump robinhood-chain bt.db · bt7.db · fomo.db candles 277+115 池 addrinfo 961 · txinfo 3.3万 raw 8万 · web.py 拷贝 bt.db · fomo.db(克隆) candles 301 池 addrinfo 1016 · txinfo 5.2万 raw 10.5万 rh.db 8.8G · app_pnl.db 3.4G transfers 1520万+810万 tx_meta 99万 / 需 460万 K线 json 300 币 · 无 sanity oldpump.db 2.4G candles 2264 池(唯一走 CG key) xfers 647万 · addrinfo 3905 web.py 拷贝 chain.db 1.6G(已停用) pools / snapshots · 无 OHLCV web.py 原件(被 3 项目 import) 项目之间没有任何数据共享:同一个池的 K 线、同一个地址的标签、同一笔 tx 的 sender 各拉各的(413 个池在 ≥2 个库里重复) 还在跑的后台监控(与研究脚本抢同一份配额) rh-fomo · 每 1 分钟getLogs + GT pricectx + DS rh-fomo-test · 每 5 分钟同上(克隆) meme rhmon · 每 5 分钟getLogs + 350-580 tx 验真/轮 rwa-arb · 每 10 分钟eth_call quoter + DS 实测(2026-09-04 14:30):研究脚本第 2 次 GT 匿名调用即 429;同一时刻 CoinGecko key 通道 8 次 OHLCV 调用 5.3 秒全部 200 近两天 429 计数:rh-fomo 159 · rh-fomo-test 161 · meme rhmon 322(其中 RPC eth_call 与 GT pricectx 各占一半)
现状数据流:六个外部源、五个项目、五套互不相通的缓存,全部经同一个出口 IP;四个后台监控与任何一次研究回测抢同一份 GeckoTerminal 匿名配额。

2. 一次回测的时间去了哪里

rh-fomo 14 天回测(96 地址、1200 万区块,2026-09-01 实跑日志)。斜纹部分是代码里写死的 sleep,不是在等网络。

scan 扫转账日志
13.6 分钟
txs 买入判定
103 分钟
prices2 K线(GT)
80 分钟
prices2 现价(DS)
51 分钟
其余 scan/txs 重跑
~64 分钟
eval / evalhold
秒级

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 次验真不缓存 receipttx_meta(rh.db)· txinfo(bt.db ×3)
地址标签
合约名 / is_contract / nonce / OKX 标签
逐地址查 Blockscout,无批量;nonce 50/批会 429 需降到 20Blockscout 封自定义 UA、百万级地址过滤接口稳定 500、几小时后限流addrinfo 五张表:304 / 961 / 1008 / 1016 / 3905 行
按币元数据
DexScreener 池 / 现价 / 建池时间
forward.py 3113 个币,每币 2.4 秒固定间隔,纯睡眠 2 小时打底;prices2 现价 13.5 秒/币DS 批量端点截断 pairs 被迫逐币;报价侧池会拿错币价,须过滤 baseTokentokmeta / tokfull / fwd_tok / token_cache / tokens
工程层全部项目零并发(无线程、无 async);每个请求新建 TLS 握手;限速全是固定 sleep(2.3 / 4.5 / 6 秒)web.py 在两个项目各有一份相同拷贝;限速器是进程内变量,跨进程无协调

5. 目标架构:研究脚本只读本地

外部数据源(只有填库任务能碰) RH 链 RPCCoinGecko keyDexScreenerBlockscoutOKX priapi 填库任务(唯一的抓取者) 按源各一个令牌桶 · 跨进程共享 · 按 429 自适应 · 并发拉取 · 增量续扫 · 失败只推进到已成功位置 统一本地数据仓(一个 sqlite 或 duckdb,所有项目共用) candles(pool, tf, ts) + 覆盖区间表 transfers 账本关注钱包 ∪ 关注币,增量续扫 tx_metasender / value / 路由来源,终身复用 addr_labels合约名·路由·nonce·OKX·蜜罐 写入 回测 / 想法验证(秒级) 地址画像 / 队列构建 后台监控(只补最新块) 看板 / 报告渲染 只读本地
目标:外部源只被一个带共享限速器的填库任务访问,写进一个共用数据仓;回测、画像、监控、看板全部只读本地。新想法的成本就只剩现在那个秒级的 eval。

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 次立即 42930 次/分按出口 IP,被后台监控占满;直连在 fake-ip DNS 下不可达
CoinGecko onchain(Demo key)8 次 OHLCV 5.3 秒全 200,每次 1000 根,0.5 到 1.2 秒/次按 key 计额度,约 30 次/分、1 万次/月;路径与 GT 同构
DexScreenerpair 0.33 秒,search 0.05 秒无 K 线;批量 tokens 端点截断 pairs;按 token 查会混入报价侧池
RH 链 RPCgetLogs 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 行数统计 + 当日实测延迟。数字均为实跑记录,不是估算的部分已注明"估算"。