Uniswap API中Tick实体的价格与流动性数据格式/单位问询
Uniswap V3 流动性池价格数值解析与转换
核心原因
你看到的price0确实是Q64.96定点数格式,但原始值必须经过转换才能得到实际价格。另外,Uniswap V3的tick是离散的价格档位,你拉取的1000个tick里大多是远离当前活跃交易区间的极端档位,所以数值会显得极小或极大。
两种转换方法
1. Q64.96格式直接转换
Q64.96的规则是用64位存整数部分、96位存小数部分,转换为实际价格的公式很简单:实际价格 = price0原始值 / 2^96
2. 通过tickIdx计算精准价格
Uniswap V3的每个tickIdx对应一个固定价格,计算公式是:价格 = 1.0001^tickIdx
注意:对于ETH/USDT池(token0为USDT,token1为ETH),这个价格就是1 ETH能兑换的USDT数量,和price0的含义一致。
比如当前ETH价格约3850 USDT,对应的tickIdx大概是log(3850)/log(1.0001) ≈ 85180,你可以找这个区间的tick来验证转换结果。
代码示例(含转换逻辑)
修改你的代码,加入转换步骤:
import requests import math query = """ { pool(id: "0x11b815efb8f581194ae79006d24e0d814b7697f6") { ticks(first: 1000) { tickIdx price0 } } } """ url = "https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3" response = requests.post(url, json={'query': query}) data = response.json() # 遍历tick并转换价格 for tick in data['data']['pool']['ticks']: # Q64.96转换 price0_raw = int(tick['price0']) q64_converted = price0_raw / (2 ** 96) # tickIdx计算价格 tick_calculated = math.pow(1.0001, int(tick['tickIdx'])) print(f"tickIdx: {tick['tickIdx']}, Q64转换后: {q64_converted:.4f}, tick计算价: {tick_calculated:.4f}")
获取当前活跃价格的更优方式
如果只需要当前市场的ETH/USDT价格,没必要拉取大量tick,直接请求池的slot0数据即可,里面包含当前活跃的tick和sqrtPriceX96:
query = """ { pool(id: "0x11b815efb8f581194ae79006d24e0d814b7697f6") { slot0 { tick sqrtPriceX96 } } } """
转换sqrtPriceX96为实际价格的公式:实际价格 = (sqrtPriceX96数值 / 2^96) ** 2
这个结果就是当前1 ETH能兑换的USDT数量,和市场价格一致。
内容的提问来源于stack exchange,提问作者helloimgeorgia
相关产品推荐
相关产品推荐

