DEX 代币日度价格数据集(dex_price_daily / v_dex_price_daily)
对应 SQL:schema/clickhouse/derived/031_dex_prices.sql。
对应 SQL:schema/clickhouse/derived/031_dex_prices.sql。
从合并后的 DEX 交易与池子数据(008_dex.sql,包含 Uniswap V3 与 V4)派生每日、每资产对的交易量、交易笔数、精确有理数 OHLC 价格(开盘/收盘/最高/最低),并通过视图提供经代币精度换算后的成交量加权平均价(VWAP)展示。
1. 安装与补算
1.1 安装方式
与衍生数据集一致,替换库名占位符 {db} 后执行:
sed 's/{db}/robinhood/g' schema/clickhouse/derived/031_dex_prices.sql | clickhouse-client --multiquery如果使用 HTTP 接口(不支持多语句批处理),请按 ; 拆分逐条发送。
1.2 调度与幂等刷新机制
- 每日定时刷新(物化视图):
mv_dex_price_daily是定时刷新物化视图(REFRESH EVERY 1 DAY OFFSET 1 HOUR RANDOMIZE FOR 30 MINUTE APPEND),每天 UTC 01:00 对过去 3 天的已关闭日期([today() - 3, today()))基于底层FINAL表重新从头聚合。 - 历史回填(Backfill):
建表后可执行文件中附带的
INSERT INTO {db}.dex_price_daily ... WHERE toDate(s.block_timestamp) < today()对历史上所有已结算日期进行一次性补算。 - 幂等性与重组修复:
目标表采用
ENGINE = ReplacingMergeTree(refreshed_at),主键为(day, token, quote_token)。无论物化视图周期刷新还是多次手动回填,同一天同一交易对的新计算行都会以最新的refreshed_at覆盖旧行,在FINAL读取和后台合并时完全消除重复,天然吸收区块链重组和补算重叠。
2. 链上计价代币(Quote Tokens)研究与选型
通过在生产 ClickHouse(只读、max_threads=2)和 RPC 节点对 Robinhood Chain(Chain ID 4663,高度 ~72M)的数千万笔交易日志和池子进行统计,确认本链没有以太坊主网常见的原生 USDC / USDT 跨链流通,而是以以下三种代币构成核心流动性结算体系:
- USDG(
0x5fc5360d0400a0fd4f2af552add042d716f1d168):- 官方与 Paxos / Global Dollar Network 合作发行的原生合规美元稳定币,
decimals = 6。 - 所有股票代币(TSLA、AAPL、NVDA 等)和主要法币交易对均以 USDG 为基准计价代币。
- 官方与 Paxos / Global Dollar Network 合作发行的原生合规美元稳定币,
- WETH(
0x0bd7d308f8e1639fab988df18a8011f41eacad73):- 标准 ERC-20 封装以太坊代币,
decimals = 18。Uniswap V3 池子绝大多数以此作为报价币。
- 标准 ERC-20 封装以太坊代币,
- 原生 ETH(
0x0000000000000000000000000000000000000000):- Uniswap V4 单例(
PoolManager)中原生货币直接作为Currency使用全零地址,无需经过 WETH 封装,decimals = 18。在 V4 中有大量山寨币/社区代币直接与原生 ETH 配对。
- Uniswap V4 单例(
报价优先级规则
为了确保交易对报价方向符合金融直觉(例如 WETH/USDG 输出以 USDG 计价的 WETH 价格,而非以 WETH 计价的 USDG 价格):
- 优先级 2:
USDG(法币稳定币,最高优先级报价币) - 优先级 1:
WETH与原生 ETH(加密基准资产) - 优先级 0:其他代币(作为 Base Token)
当池中包含两个代币时:
- 若仅有一个为计价币,计价币自动作为
quote_token,另一代币作为token。 - 若两者均为计价币(如 WETH 与 USDG 配对),优先级更高的 USDG 作为
quote_token,WETH 作为token。 - 若两者优先级相同(如原生 ETH 与 WETH 配对),按地址排序区分,保证确定性。
- 若两者均非计价币,不作为标准基准报价对入库。
3. 设计与正确性保证(严格金钱安全)
3.1 为什么必须对 CLOSED 周期基于 FINAL 聚合
dex_swaps 属于 ReplacingMergeTree(version, is_deleted)。在回填中断重试、分段并发写入或链重组时,底层日志会包含同一事件的多版本插入或带更高 version 的 is_deleted = 1 墓碑行。
若使用针对每笔写入即时触发的累加物化视图(SUM/COUNT),会对未去重的物理行重复累加,造成金额和笔数虚高。
因此必须采用方案 (b):仅针对已完结的 UTC 自然日(toDate(block_timestamp) < today()),在 FINAL 且 is_deleted = 0 的权威快照上计算每日指标,实现完全幂等与自愈。
3.2 绝对零浮点:精确有理数与整数算术
- 底层表
dex_price_daily全程使用整数: 成交量为绝对值总和UInt256。所有价格点(开盘first_price、收盘last_price、最低min_price、最高max_price)均直接保留单笔 Swap 发生时的原始成交金额分子与分母: $$\text{Price} = \frac{\text{quote_amount_raw}}{\text{base_amount_raw}}$$ 分子quote_amount_raw(UInt256)与分母base_amount_raw(UInt256)原样落盘,杜绝任何有损精度舍入。 - 最低/最高价确定性极值排序:
ClickHouse 内置极值比较时使用纯整数商及高精度余数商元组:
tuple(intDiv(quote_raw, base_raw), intDiv((quote_raw % base_raw) * 10^25, base_raw), block_number, log_index),既防止了 UInt256 乘法溢出,又能在 25 位小数精度下准确确定单笔成交极值,且无任何浮点数介入。
3.3 视图 VWAP 的 Decimal 展示换算
v_dex_price_daily 视图从 {db}.tokens 读取代币精度 $d_{\text{base}}$ 与 $d_{\text{quote}}$。
真实成交量加权平均价公式为:
$$\text{VWAP}{\text{human}} = \frac{\sum Q{\text{raw}}}{\sum B_{\text{raw}}} \times \frac{10^{d_{\text{base}}}}{10^{d_{\text{quote}}}}$$
- 10 的次幂全部通过字符串构造:
toUInt256(concat('1', repeat('0', ...))),严禁使用会转化为 Float64 的pow(10, n)。 - 通过整数商与余数构造字符串后,再通过
toDecimal256(..., 18)输出为精确的 18 位定点小数,满足展示需求。
4. 表结构与视图定义
4.1 表 dex_price_daily
| 字段 | 类型 | 说明 |
|---|---|---|
day | Date | UTC 结算日期 |
token | FixedString(20) | 标的资产代币地址(Base Token) |
quote_token | FixedString(20) | 计价货币代币地址(Quote Token) |
swap_count | UInt64 | 当日有效成交笔数 |
base_volume_raw | UInt256 | 标的代币原始成交总量(绝对值之和) |
quote_volume_raw | UInt256 | 计价代币原始成交总量(绝对值之和) |
first_price_numerator | UInt256 | 当日第一笔交易计价代币原始金额(开盘价分子) |
first_price_denominator | UInt256 | 当日第一笔交易标的代币原始金额(开盘价分母) |
last_price_numerator | UInt256 | 当日最后一笔交易计价代币原始金额(收盘价分子) |
last_price_denominator | UInt256 | 当日最后一笔交易标的代币原始金额(收盘价分母) |
min_price_numerator | UInt256 | 当日最低成交价对应交易的计价代币金额(最低价分子) |
min_price_denominator | UInt256 | 当日最低成交价对应交易的标的代币金额(最低价分母) |
max_price_numerator | UInt256 | 当日最高成交价对应交易的计价代币金额(最高价分子) |
max_price_denominator | UInt256 | 当日最高成交价对应交易的标的代币金额(最高价分母) |
refreshed_at | DateTime('UTC') | 聚合计算刷新时间戳(兼作 ReplacingMergeTree 版本列) |
4.2 视图 v_dex_price_daily
在基础表之上关联 {db}.tokens,补充可读符号并在展示层格式化:
token_symbol/token_name: 标的代币名称与符号quote_symbol/quote_name: 计价币名称与符号(USDG / WETH / ETH)base_volume: 标的代币人类可读交易量(Decimal(76, 18))quote_volume: 计价代币人类可读交易量(Decimal(76, 18))vwap: 成交量加权平均价(Decimal(76, 18))first_price/last_price/min_price/max_price: 经精度调整的人类可读 OHLC 价格(Decimal(76, 18))- 以及对应的原始有理数分子/分母字段
5. 本地全链路独立验证(精确对账证据)
5.1 验证方法
在本地 ClickHouse 独立 Scratch 数据库中,加载 Robinhood Chain 真实区块历史交易与池子(包含 Uniswap V3 与 V4 真实交易):
- 应用
sql/tokens.sql,并从 RPC 链上节点查询各代币真实name、symbol、decimals写入tokens表。 - 运行
031_dex_prices.sql生成dex_price_daily与视图v_dex_price_daily。 - 编写独立的 Python 验证程序(采用 Python
decimal.Decimal,精度设为 100 位,不依赖 ClickHouse 计算逻辑),直接从最底层单笔dex_swaps原始行逐笔模拟累加和价格比较,核对 3 个典型池子及全部交易对。
5.2 对账结果(3 个池子 2026-09-25 真实数据,100% 精确匹配)
池子 1:Agrippa / ETH(Uniswap V4 原生代币池)
- 标的代币:
0x1785EC2BD68C72042711A9EF36AF93C9AECB5BA3(18 decimals) - 计价代币:
0x0000000000000000000000000000000000000000(原生 ETH,18 decimals)
| 指标 | ClickHouse 结果 | 独立 Python Decimal 计算 | 对账状态 |
|---|---|---|---|
swap_count | 70 | 70 | EXACT MATCH |
base_volume_raw | 205795031621476504045885807 | 205795031621476504045885807 | EXACT MATCH |
quote_volume_raw | 7241132137372618697 | 7241132137372618697 | EXACT MATCH |
first_price (分子/分母) | 1998242000000 / 87316552968883239345 | 1998242000000 / 87316552968883239345 | EXACT MATCH |
last_price (分子/分母) | 16721066000870489 / 364288917231736933027056 | 16721066000870489 / 364288917231736933027056 | EXACT MATCH |
min_price (分子/分母) | 1998242000000 / 87316552968883239345 | 1998242000000 / 87316552968883239345 | EXACT MATCH |
max_price (分子/分母) | 99000000000000000 / 2108495979854737386241980 | 99000000000000000 / 2108495979854737386241980 | EXACT MATCH |
vwap (Decimal18) | 0.000000035186136809 | 0.000000035186136809 | EXACT MATCH |
池子 2:GRAILS / WETH(Uniswap V3 池)
- 标的代币:
0xC410396E1087E75B3FC1CEFE7A48BCF6E88A878C(18 decimals) - 计价代币:
0x0BD7D308F8E1639FAB988DF18A8011F41EACAD73(WETH,18 decimals)
| 指标 | ClickHouse 结果 | 独立 Python Decimal 计算 | 对账状态 |
|---|---|---|---|
swap_count | 47 | 47 | EXACT MATCH |
base_volume_raw | 199322493804688194436351258 | 199322493804688194436351258 | EXACT MATCH |
quote_volume_raw | 1161977531546934234 | 1161977531546934234 | EXACT MATCH |
first_price (分子/分母) | 500000000000000 / 99971646275875362838747 | 500000000000000 / 99971646275875362838747 | EXACT MATCH |
last_price (分子/分母) | 199000000000000 / 31214184411439729473297 | 199000000000000 / 31214184411439729473297 | EXACT MATCH |
min_price (分子/分母) | 500000000000000 / 99971646275875362838747 | 500000000000000 / 99971646275875362838747 | EXACT MATCH |
max_price (分子/分母) | 25831314425596850 / 4034271134904952420000000 | 25831314425596850 / 4034271134904952420000000 | EXACT MATCH |
vwap (Decimal18) | 0.000000005829635729 | 0.000000005829635729 | EXACT MATCH |
池子 3:PEAR / USDG(Uniswap V4 跨精度稳定币计价池)
- 标的代币:
0x383562778894760D53A247C97686284931BB28CC(18 decimals) - 计价代币:
0x5FC5360D0400A0FD4F2AF552ADD042D716F1D168(USDG,6 decimals)
| 指标 | ClickHouse 结果 | 独立 Python Decimal 计算 | 对账状态 |
|---|---|---|---|
swap_count | 3 | 3 | EXACT MATCH |
base_volume_raw | 45172606851309327552121 | 45172606851309327552121 | EXACT MATCH |
quote_volume_raw | 28323979 | 28323979 | EXACT MATCH |
first_price (分子/分母) | 982036 / 1526082920877114310237 | 982036 / 1526082920877114310237 | EXACT MATCH |
last_price (分子/分母) | 1070867 / 1752586326330000000000 | 1070867 / 1752586326330000000000 | EXACT MATCH |
min_price (分子/分母) | 1070867 / 1752586326330000000000 | 1070867 / 1752586326330000000000 | EXACT MATCH |
max_price (分子/分母) | 982036 / 1526082920877114310237 | 982036 / 1526082920877114310237 | EXACT MATCH |
vwap (Decimal18) | 0.000627016702693991 | 0.000627016702693991 | EXACT MATCH |
此外,本地测试集中的全部 9/9 个交易对在上述核对中均达到了 100% 精确匹配。
6. 常用示例查询
6.1 查询指定代币的历史每日 VWAP 与交易量
SELECT
day,
token_symbol,
quote_symbol,
swap_count,
base_volume,
quote_volume,
vwap,
min_price,
max_price
FROM robinhood.v_dex_price_daily
WHERE token_symbol = 'TSLA'
AND quote_symbol = 'USDG'
ORDER BY day DESC
LIMIT 30;6.2 查询某日全链交易量最大的代币价格看板
SELECT
token_symbol,
quote_symbol,
swap_count,
quote_volume,
vwap,
first_price AS open_price,
last_price AS close_price,
min_price AS low_price,
max_price AS high_price
FROM robinhood.v_dex_price_daily
WHERE day = '2026-09-24'
ORDER BY quote_volume_raw DESC
LIMIT 20;6.3 使用原始有理数分子分母进行自定义超高精度算术
SELECT
day,
hex(token) AS token_hex,
hex(quote_token) AS quote_token_hex,
toString(first_price_numerator) AS first_num,
toString(first_price_denominator) AS first_den,
toString(last_price_numerator) AS last_num,
toString(last_price_denominator) AS last_den
FROM robinhood.dex_price_daily FINAL
WHERE day = '2026-09-24'
ORDER BY swap_count DESC
LIMIT 10;DEX 交易数据集(dex_pools / dex_swaps)
对应 SQL:schema/clickhouse/derived/008_dex.sql。 安装方式与 001_erc20_transfers.sql 等一致:sed 's/{db}/robinhood/g' 008_dex.sql | clickhouse-client --multiquery(HTTP…
价格预言机数据集(oracle_feeds / oracle_prices)
Robinhood Chain(chain id 4663)上确实存在链上价格预言机,用于给约 60 多个代币化股票 / 加密资产 / 稳定币提供参考价。经独立验证,其形态是经典 Chainlink FluxAggregator (AggregatorV3Interface + AnswerUpdated/…