记录一次新数据源的接入(2026-06-12)
记录一次新数据源的接入(2026-06-12)
两个数据源如果答案一样,那第二个就没有存在意义
GMGN 用了一整周,能挖的字段基本都挖过了。但有一类信息它天然给不了:市场热度、社媒包装、广告投放、多池流动性快照。
这天做的事,是把 DexScreener 接成第二个数据源——不是替换 GMGN,而是补它的盲区。
先想清楚:为什么要第二个源
结论很早就定了,而且这次是先想清楚分工再动手:
DexScreener = 市场热度 / 社媒包装 / 广告投放 / 多池流动性快照
GMGN = 链上聪明钱 / KOL 成交流 / 安全字段 / dev 信誉 / trenches 新币热榜
这两份能力清单几乎没有交集。GMGN 擅长看链上的人在干什么,DexScreener 擅长看市场在关注什么、项目方在花钱做什么。互补,不重复——这是接入的前提。如果第二个源只是把第一个源的数据再抄一遍,那接它纯粹是浪费。
8 个端点,全部不要 key
DexScreener 的公开接口实测下来很友好:全部返回 200,无需 API Key。
| 接口 | 用途 | 限速 |
|---|---|---|
/token-profiles/latest/v1 |
最新更新 token profile,含图标、简介、官网、twitter、telegram | 60/min |
/token-profiles/recent-updates/v1 |
最近更新 profile | 60/min |
/token-boosts/latest/v1 |
最新买 boost 的 token | 60/min |
/token-boosts/top/v1 |
当前 boost 最强 token | 60/min |
/orders/v1/{chainId}/{tokenAddress} |
查 token 是否买过 tokenProfile / CTO / tokenAd / trendingBarAd | 60/min |
/tokens/v1/{chainId}/{tokenAddresses} |
按 address 批量查 pair / 价格 / 成交 / 流动性,最多 30 个地址 | 300/min |
/token-pairs/v1/{chainId}/{tokenAddress} |
查一个 token 的全部池子 | 300/min |
/metas/trending/v1 |
查当前叙事趋势 | 60/min |
/tokens/v1 的 300/min 最有用——它很适合批量 enrich GMGN 候选币,正好补上 GMGN 有时新币 kline 历史不完整的问题。
四类信号,以及一条红线
第一类是 boost / ads,外部营销投入信号。 看到项目方或社区在花钱推,比如 {"amount": 100, "totalAmount": 500}。但这条信号有一条红线:
Dex boost 只是"注意力放大器",不能单独作为买入信号。
真项目会 boost,骗子盘也会 boost,庄家出货前更会 boost。所以它必须叠加 GMGN 的聪明钱、非蜜罐、非刷量、流动性确认,才有意义。
第二类是 token profile 的社媒信息。 icon、description、twitter、telegram、website——可以做社交完整度评分,用来过滤"裸奔币"。但同样不能太信,因为骗子也会包装。
第三类是 dex pair 的市场快照。 价格、成交量、交易笔数、价格变动、流动性、FDV,一份很密的数据。
第四类是 trending metas,叙事轮动信号。 看到当前热门叙事,比如 Chinese、World Cup。这条给了一个全新的视角:**以前只看单币信号,现在可以看"板块叙事正在热"**。
从调研到拆任务
调研完,"要不要做"就没悬念了,卡点在"怎么做才不半途而废"。
我先把骨架搭了一半:dexscreener_client.py 新增了,db.py 加了 sim_dexscreener_signals 表和读写 helper,9_sim_trading.py 也开始在候选评分前做 Dex enrich 和写库。
但对着清单一看,剩下的四项都还挂着:v1.23 没补齐、strategy_combo / score_combo 没确认消费 Dex 子评分、UI 没做、完整验证和重启(8501 / sim_loop)都没跑。
一个人的串行开发到这里就该停了。 于是把它拆成 4 个 Kanban 子任务:
t_3363ee1a→strategy:v1.23 Dex+GMGN 联合评分接线与版本落地t_84a7e5e4→dashboard-dev:9 号页 DexScreener UI 展示t_92244c3b→data-researcher:DexScreener API/DB 小样本验证t_fd5d50af→strategy:最终集成验收,依赖上面 3 个
dispatch 输出:
1 | Spawned: 3 |
3 个无依赖的并行开工,验收任务等依赖。这里有一条自己定的规矩:不会只信子智能体的"完成"报告,最终我自己核验。
接线:同一个逻辑,要改两处
t_3363ee1a 带回一个关键发现:**9 号页的 strategy_combo 是一个完全独立的本地函数,根本不调用 engine.score_combo**。
这意味着 Dex 逻辑不能只加一处——实盘和回测两处都要各加一份,才能保证共用同一套评分规则。改动落在三个文件:
strategy_engine/engine.py:score_combo新增 +22 行 Dex 块(Dex+ 有 GMGN 确认才进 combo,Dex- 直接扣,cap 在[-2,+2])pages/9_sim_trading.py:strategy_combo同样 +22 行,并删掉旧的 Dex BUY 触发块(避免重复计数)strategy_engine/version_risk_history.py:新增 v1.23 配置,在 v1.22 基础上加三个参数:
1 | DEX_SCORE_MAX_BONUS = 2.0 |
第三个参数是这次接入的核心约束:Dex 分可以为负、可以扣分,但正分必须要有 GMGN 信号确认。这正好对应上面那条红线——boost 不能单独把币买进来。
验证结果是 5 个相关文件全部 py_compile 通过。
建表,和一次"表不存在"
t_92244c3b 做小样本验证,先撞上一个基础问题:**sim_dexscreener_signals 表在实际的历史库里根本不存在**。
CREATE TABLE IF NOT EXISTS 的定义明明写在 db.py 里,但 init_db() 从来没有在当前这台机器上跑过——所以定义在那儿,表却没建。这和前几天 v1.16 那个 "ALTER 必须手动跑" 是同一类问题:代码里写了,不代表环境里有了。
验证链路是这么走通的:
- HTTP
/tokens/v1:6 个真实地址全部返回 ≥1 个 pair ✅ enrich_tokens:返回 3 条,dex_score/reason/liquidity/volume字段齐全 ✅- 手动
CREATE TABLE:43 列,与代码定义一致 ✅ upsert_dexscreener_signals:写入 3 条(base / sol / bsc 各 1)✅list_dexscreener_signals:读回 3 条,内容正确 ✅
顺带交付了两个可复用脚本:create_dexscreener_table.py(一次性建表)和 verify_dexscreener.py(可重复跑完整链路验证)。核心策略代码没动。
UI:4 个指标 + 1 张表
t_84a7e5e4 负责让数据看得见。改动在 pages/9_sim_trading.py 的 render() 里,约 1975 行处(交易记录和风险规则之间)插入约 50 行。
上半部分是 4 个 st.metric:扫描 Token 数 / 平均 DexScore / 平均流动性 / 平均 24h 成交。
下半部分是 1 张 st.dataframe 明细表:Score / 流动性 / 24h成交 / 24h买 / 24h卖 / 24h涨跌 / Boosts / 有Profile / 有Twitter / 原因。展示规则是按 Score 降序、同一 (chain, address) 取最新一条、0 行时显示 st.info("暂无 DexScreener 数据,后台循环正在采集…")。
DB helper list_dexscreener_signals 在 v1.23 里已经存在,无需新增。验证走了语法、数据、渲染三重:py_compile 通过、DB 3 行真实数据、DataFrame 构建无错。
样例是 base 链的 SINGIT:+0.3 = 流动性 $72k ✅ + Twitter ✅ + Website ✅ − 卖压 ❌,reason 字段完整显示。
验收
t_fd5d50af 是最终集成验收,依赖前三个任务。结果是全部 7 步验收通过。
到这里,第二个数据源算是真正接进来了:能采(dexscreener_client.py)、能存(43 列表)、能算(v1.23 的 Dex 子评分)、能看(9 号页 UI)、能被别的任务验证(verify_dexscreener.py)。
隔天整理出的模块清单
6 月 13 日回头看,把这次接入整理成了一份 dexscreener_integration 模块清单,正好给这次接入做个收尾。
已完成部分:
- 新增
dexscreener_client.py客户端文件 db.py已添加sim_dexscreener_signals表定义及读写 helper 函数9_sim_trading.py已实现候选评分前的 Dex 数据 enrich 及写库逻辑
待完成部分:
- 确认并补齐 v1.23 版本相关配置
- 确认
strategy_combo / score_combo正确消费 Dex 子评分 - 完成 9 号页 DexScreener 数据 UI 展示
- 跑完整链路验证、重启
8501端口服务及sim_loop循环
留意这份清单的时间戳:它记录的是骨架刚搭完那一刻的状态。而同一个 12 号,并行推进的四个子任务已经把后面的每一项都推下去了。
最后
这一天的三层。
最表面的一层,是 DexScreener 的 8 个端点、四类信号,和一个能看的 UI。数据源接进来了,看得见、存得下、算得动。
中间一层,是那两条必须分开写死的约束:
- 同一个评分逻辑出现在两处(实盘 + 回测),必须两处同改——
9_sim_trading.py那个独立函数是最容易漏的地方。 - Dex 正向分必须要有 GMGN 确认——
DEX_REQUIRE_GMGN_SIGNAL_FOR_POSITIVE = True。新数据源一进来就带加分,是最容易把策略带偏的做法,所以这条从第一天就写死。
最里面一层,是那个拆任务的决定。 骨架做了一半就看清"剩下的活不是一个人串行能干净做完的",于是拆成 4 个子任务、3 个并行、1 个验收——并且明确说了自己会核验,不只看"完成"这两个字。
回头看,sim_dexscreener_signals 那张表"定义在代码里却在库里不存在",和这一天的所有事是同一个道理:你以为已经有的东西,不核实一遍,就不算真有。 第二个数据源是这样,那张表也是这样。